OSDN Git Service

PR target/32280
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63
64 ;; UNSPEC usage:
65
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
79
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
89
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
95
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
106
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
126
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
131
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
143
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
151
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
163
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
166
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
172
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
177
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
183
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
193
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
198
199    ; For FMA4 support
200    (UNSPEC_FMA4_INTRINSIC       150)
201    (UNSPEC_FMA4_FMADDSUB        151)
202    (UNSPEC_FMA4_FMSUBADD        152)
203    (UNSPEC_XOP_UNSIGNED_CMP     151)
204    (UNSPEC_XOP_TRUEFALSE        152)
205    (UNSPEC_XOP_PERMUTE          153)
206    (UNSPEC_FRCZ                 154)
207
208    ; For AES support
209    (UNSPEC_AESENC               159)
210    (UNSPEC_AESENCLAST           160)
211    (UNSPEC_AESDEC               161)
212    (UNSPEC_AESDECLAST           162)
213    (UNSPEC_AESIMC               163)
214    (UNSPEC_AESKEYGENASSIST      164)
215
216    ; For PCLMUL support
217    (UNSPEC_PCLMUL               165)
218
219    ; For AVX support
220    (UNSPEC_PCMP                 166)
221    (UNSPEC_VPERMIL              167)
222    (UNSPEC_VPERMIL2F128         168)
223    (UNSPEC_MASKLOAD             169)
224    (UNSPEC_MASKSTORE            170)
225    (UNSPEC_CAST                 171)
226    (UNSPEC_VTESTP               172)
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
6014       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6015          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6016       if (CONST_INT_P (operands[2])
6017           /* Avoid overflows.  */
6018           && (<MODE>mode != DImode
6019               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6020           && (INTVAL (operands[2]) == 128
6021               || (INTVAL (operands[2]) < 0
6022                   && INTVAL (operands[2]) != -128)))
6023         {
6024           operands[2] = GEN_INT (-INTVAL (operands[2]));
6025           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6026         }
6027       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6028     }
6029 }
6030   [(set (attr "type")
6031      (cond [(and (eq_attr "alternative" "2") 
6032                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6033               (const_string "lea")
6034             (eq_attr "alternative" "3")
6035               (const_string "lea")
6036             ; Current assemblers are broken and do not allow @GOTOFF in
6037             ; ought but a memory context.
6038             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6039               (const_string "lea")
6040             (match_operand:SWI48 2 "incdec_operand" "")
6041               (const_string "incdec")
6042            ]
6043            (const_string "alu")))
6044    (set (attr "length_immediate")
6045       (if_then_else
6046         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6047         (const_string "1")
6048         (const_string "*")))
6049    (set_attr "mode" "<MODE>")])
6050
6051 ;; It may seem that nonimmediate operand is proper one for operand 1.
6052 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6053 ;; we take care in ix86_binary_operator_ok to not allow two memory
6054 ;; operands so proper swapping will be done in reload.  This allow
6055 ;; patterns constructed from addsi_1 to match.
6056
6057 (define_insn "*addsi_1_zext"
6058   [(set (match_operand:DI 0 "register_operand" "=r,r")
6059         (zero_extend:DI
6060           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6061                    (match_operand:SI 2 "general_operand" "g,li"))))
6062    (clobber (reg:CC FLAGS_REG))]
6063   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6064 {
6065   switch (get_attr_type (insn))
6066     {
6067     case TYPE_LEA:
6068       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6069       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6070
6071     case TYPE_INCDEC:
6072       if (operands[2] == const1_rtx)
6073         return "inc{l}\t%k0";
6074       else
6075         {
6076           gcc_assert (operands[2] == constm1_rtx);
6077           return "dec{l}\t%k0";
6078         }
6079
6080     default:
6081       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6082          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6083       if (CONST_INT_P (operands[2])
6084           && (INTVAL (operands[2]) == 128
6085               || (INTVAL (operands[2]) < 0
6086                   && INTVAL (operands[2]) != -128)))
6087         {
6088           operands[2] = GEN_INT (-INTVAL (operands[2]));
6089           return "sub{l}\t{%2, %k0|%k0, %2}";
6090         }
6091       return "add{l}\t{%2, %k0|%k0, %2}";
6092     }
6093 }
6094   [(set (attr "type")
6095      (cond [(eq_attr "alternative" "1")
6096               (const_string "lea")
6097             ; Current assemblers are broken and do not allow @GOTOFF in
6098             ; ought but a memory context.
6099             (match_operand:SI 2 "pic_symbolic_operand" "")
6100               (const_string "lea")
6101             (match_operand:SI 2 "incdec_operand" "")
6102               (const_string "incdec")
6103            ]
6104            (const_string "alu")))
6105    (set (attr "length_immediate")
6106       (if_then_else
6107         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6108         (const_string "1")
6109         (const_string "*")))
6110    (set_attr "mode" "SI")])
6111
6112 (define_insn "*addhi_1"
6113   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6114         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6115                  (match_operand:HI 2 "general_operand" "rn,rm")))
6116    (clobber (reg:CC FLAGS_REG))]
6117   "TARGET_PARTIAL_REG_STALL
6118    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6119 {
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == const1_rtx)
6124         return "inc{w}\t%0";
6125       else
6126         {
6127           gcc_assert (operands[2] == constm1_rtx);
6128           return "dec{w}\t%0";
6129         }
6130
6131     default:
6132       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6133          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6134       if (CONST_INT_P (operands[2])
6135           && (INTVAL (operands[2]) == 128
6136               || (INTVAL (operands[2]) < 0
6137                   && INTVAL (operands[2]) != -128)))
6138         {
6139           operands[2] = GEN_INT (-INTVAL (operands[2]));
6140           return "sub{w}\t{%2, %0|%0, %2}";
6141         }
6142       return "add{w}\t{%2, %0|%0, %2}";
6143     }
6144 }
6145   [(set (attr "type")
6146      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6147         (const_string "incdec")
6148         (const_string "alu")))
6149    (set (attr "length_immediate")
6150       (if_then_else
6151         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6152         (const_string "1")
6153         (const_string "*")))
6154    (set_attr "mode" "HI")])
6155
6156 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6157 ;; type optimizations enabled by define-splits.  This is not important
6158 ;; for PII, and in fact harmful because of partial register stalls.
6159
6160 (define_insn "*addhi_1_lea"
6161   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6162         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6163                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6164    (clobber (reg:CC FLAGS_REG))]
6165   "!TARGET_PARTIAL_REG_STALL
6166    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6167 {
6168   switch (get_attr_type (insn))
6169     {
6170     case TYPE_LEA:
6171       return "#";
6172     case TYPE_INCDEC:
6173       if (operands[2] == const1_rtx)
6174         return "inc{w}\t%0";
6175       else
6176         {
6177           gcc_assert (operands[2] == constm1_rtx);
6178           return "dec{w}\t%0";
6179         }
6180
6181     default:
6182       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6183          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6184       if (CONST_INT_P (operands[2])
6185           && (INTVAL (operands[2]) == 128
6186               || (INTVAL (operands[2]) < 0
6187                   && INTVAL (operands[2]) != -128)))
6188         {
6189           operands[2] = GEN_INT (-INTVAL (operands[2]));
6190           return "sub{w}\t{%2, %0|%0, %2}";
6191         }
6192       return "add{w}\t{%2, %0|%0, %2}";
6193     }
6194 }
6195   [(set (attr "type")
6196      (if_then_else (eq_attr "alternative" "2")
6197         (const_string "lea")
6198         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6199            (const_string "incdec")
6200            (const_string "alu"))))
6201    (set (attr "length_immediate")
6202       (if_then_else
6203         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6204         (const_string "1")
6205         (const_string "*")))
6206    (set_attr "mode" "HI,HI,SI")])
6207
6208 (define_insn "*addqi_1"
6209   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6210         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6211                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6212    (clobber (reg:CC FLAGS_REG))]
6213   "TARGET_PARTIAL_REG_STALL
6214    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6215 {
6216   int widen = (which_alternative == 2);
6217   switch (get_attr_type (insn))
6218     {
6219     case TYPE_INCDEC:
6220       if (operands[2] == const1_rtx)
6221         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222       else
6223         {
6224           gcc_assert (operands[2] == constm1_rtx);
6225           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6226         }
6227
6228     default:
6229       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6231       if (CONST_INT_P (operands[2])
6232           && (INTVAL (operands[2]) == 128
6233               || (INTVAL (operands[2]) < 0
6234                   && INTVAL (operands[2]) != -128)))
6235         {
6236           operands[2] = GEN_INT (-INTVAL (operands[2]));
6237           if (widen)
6238             return "sub{l}\t{%2, %k0|%k0, %2}";
6239           else
6240             return "sub{b}\t{%2, %0|%0, %2}";
6241         }
6242       if (widen)
6243         return "add{l}\t{%k2, %k0|%k0, %k2}";
6244       else
6245         return "add{b}\t{%2, %0|%0, %2}";
6246     }
6247 }
6248   [(set (attr "type")
6249      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250         (const_string "incdec")
6251         (const_string "alu")))
6252    (set (attr "length_immediate")
6253       (if_then_else
6254         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6255         (const_string "1")
6256         (const_string "*")))
6257    (set_attr "mode" "QI,QI,SI")])
6258
6259 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6260 (define_insn "*addqi_1_lea"
6261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6262         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6263                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6264    (clobber (reg:CC FLAGS_REG))]
6265   "!TARGET_PARTIAL_REG_STALL
6266    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6267 {
6268   int widen = (which_alternative == 2);
6269   switch (get_attr_type (insn))
6270     {
6271     case TYPE_LEA:
6272       return "#";
6273     case TYPE_INCDEC:
6274       if (operands[2] == const1_rtx)
6275         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6276       else
6277         {
6278           gcc_assert (operands[2] == constm1_rtx);
6279           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6280         }
6281
6282     default:
6283       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6284          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6285       if (CONST_INT_P (operands[2])
6286           && (INTVAL (operands[2]) == 128
6287               || (INTVAL (operands[2]) < 0
6288                   && INTVAL (operands[2]) != -128)))
6289         {
6290           operands[2] = GEN_INT (-INTVAL (operands[2]));
6291           if (widen)
6292             return "sub{l}\t{%2, %k0|%k0, %2}";
6293           else
6294             return "sub{b}\t{%2, %0|%0, %2}";
6295         }
6296       if (widen)
6297         return "add{l}\t{%k2, %k0|%k0, %k2}";
6298       else
6299         return "add{b}\t{%2, %0|%0, %2}";
6300     }
6301 }
6302   [(set (attr "type")
6303      (if_then_else (eq_attr "alternative" "3")
6304         (const_string "lea")
6305         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6306            (const_string "incdec")
6307            (const_string "alu"))))
6308    (set (attr "length_immediate")
6309       (if_then_else
6310         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6311         (const_string "1")
6312         (const_string "*")))
6313    (set_attr "mode" "QI,QI,SI,SI")])
6314
6315 (define_insn "*addqi_1_slp"
6316   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6317         (plus:QI (match_dup 0)
6318                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6319    (clobber (reg:CC FLAGS_REG))]
6320   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6321    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6322 {
6323   switch (get_attr_type (insn))
6324     {
6325     case TYPE_INCDEC:
6326       if (operands[1] == const1_rtx)
6327         return "inc{b}\t%0";
6328       else
6329         {
6330           gcc_assert (operands[1] == constm1_rtx);
6331           return "dec{b}\t%0";
6332         }
6333
6334     default:
6335       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6336       if (CONST_INT_P (operands[1])
6337           && INTVAL (operands[1]) < 0)
6338         {
6339           operands[1] = GEN_INT (-INTVAL (operands[1]));
6340           return "sub{b}\t{%1, %0|%0, %1}";
6341         }
6342       return "add{b}\t{%1, %0|%0, %1}";
6343     }
6344 }
6345   [(set (attr "type")
6346      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6347         (const_string "incdec")
6348         (const_string "alu1")))
6349    (set (attr "memory")
6350      (if_then_else (match_operand 1 "memory_operand" "")
6351         (const_string "load")
6352         (const_string "none")))
6353    (set_attr "mode" "QI")])
6354
6355 (define_insn "*add<mode>_2"
6356   [(set (reg FLAGS_REG)
6357         (compare
6358           (plus:SWI48
6359             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6360             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6361           (const_int 0)))
6362    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6363         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6364   "ix86_match_ccmode (insn, CCGOCmode)
6365    && ix86_binary_operator_ok (PLUS, <MODE>mode, 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       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6374       if (operands[2] == const1_rtx)
6375         return "inc{<imodesuffix>}\t%0";
6376       else
6377         {
6378           gcc_assert (operands[2] == constm1_rtx);
6379           return "dec{<imodesuffix>}\t%0";
6380         }
6381
6382     default:
6383       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6384       /* ???? In DImode, we ought to handle there the 32bit case too
6385          - do we need new constraint?  */
6386       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6387          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6388       if (CONST_INT_P (operands[2])
6389           /* Avoid overflows.  */
6390           && (<MODE>mode != DImode
6391               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6392           && (INTVAL (operands[2]) == 128
6393               || (INTVAL (operands[2]) < 0
6394                   && INTVAL (operands[2]) != -128)))
6395         {
6396           operands[2] = GEN_INT (-INTVAL (operands[2]));
6397           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6398         }
6399       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6400     }
6401 }
6402   [(set (attr "type")
6403      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6404         (const_string "incdec")
6405         (const_string "alu")))
6406    (set (attr "length_immediate")
6407       (if_then_else
6408         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6409         (const_string "1")
6410         (const_string "*")))
6411    (set_attr "mode" "<MODE>")])
6412
6413 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6414 (define_insn "*addsi_2_zext"
6415   [(set (reg FLAGS_REG)
6416         (compare
6417           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6418                    (match_operand:SI 2 "general_operand" "g"))
6419           (const_int 0)))
6420    (set (match_operand:DI 0 "register_operand" "=r")
6421         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6422   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6423    && ix86_binary_operator_ok (PLUS, SImode, operands)
6424    /* Current assemblers are broken and do not allow @GOTOFF in
6425       ought but a memory context.  */
6426    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6427 {
6428   switch (get_attr_type (insn))
6429     {
6430     case TYPE_INCDEC:
6431       if (operands[2] == const1_rtx)
6432         return "inc{l}\t%k0";
6433       else
6434         {
6435           gcc_assert (operands[2] == constm1_rtx);
6436           return "dec{l}\t%k0";
6437         }
6438
6439     default:
6440       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6441          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6442       if (CONST_INT_P (operands[2])
6443           && (INTVAL (operands[2]) == 128
6444               || (INTVAL (operands[2]) < 0
6445                   && INTVAL (operands[2]) != -128)))
6446         {
6447           operands[2] = GEN_INT (-INTVAL (operands[2]));
6448           return "sub{l}\t{%2, %k0|%k0, %2}";
6449         }
6450       return "add{l}\t{%2, %k0|%k0, %2}";
6451     }
6452 }
6453   [(set (attr "type")
6454      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6455         (const_string "incdec")
6456         (const_string "alu")))
6457    (set (attr "length_immediate")
6458       (if_then_else
6459         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6460         (const_string "1")
6461         (const_string "*")))
6462    (set_attr "mode" "SI")])
6463
6464 (define_insn "*addhi_2"
6465   [(set (reg FLAGS_REG)
6466         (compare
6467           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6468                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6469           (const_int 0)))
6470    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6471         (plus:HI (match_dup 1) (match_dup 2)))]
6472   "ix86_match_ccmode (insn, CCGOCmode)
6473    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6474 {
6475   switch (get_attr_type (insn))
6476     {
6477     case TYPE_INCDEC:
6478       if (operands[2] == const1_rtx)
6479         return "inc{w}\t%0";
6480       else
6481         {
6482           gcc_assert (operands[2] == constm1_rtx);
6483           return "dec{w}\t%0";
6484         }
6485
6486     default:
6487       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6488          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6489       if (CONST_INT_P (operands[2])
6490           && (INTVAL (operands[2]) == 128
6491               || (INTVAL (operands[2]) < 0
6492                   && INTVAL (operands[2]) != -128)))
6493         {
6494           operands[2] = GEN_INT (-INTVAL (operands[2]));
6495           return "sub{w}\t{%2, %0|%0, %2}";
6496         }
6497       return "add{w}\t{%2, %0|%0, %2}";
6498     }
6499 }
6500   [(set (attr "type")
6501      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6502         (const_string "incdec")
6503         (const_string "alu")))
6504    (set (attr "length_immediate")
6505       (if_then_else
6506         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6507         (const_string "1")
6508         (const_string "*")))
6509    (set_attr "mode" "HI")])
6510
6511 (define_insn "*addqi_2"
6512   [(set (reg FLAGS_REG)
6513         (compare
6514           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6515                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6516           (const_int 0)))
6517    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6518         (plus:QI (match_dup 1) (match_dup 2)))]
6519   "ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == const1_rtx)
6526         return "inc{b}\t%0";
6527       else
6528         {
6529           gcc_assert (operands[2] == constm1_rtx
6530                       || (CONST_INT_P (operands[2])
6531                           && INTVAL (operands[2]) == 255));
6532           return "dec{b}\t%0";
6533         }
6534
6535     default:
6536       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6537       if (CONST_INT_P (operands[2])
6538           && INTVAL (operands[2]) < 0)
6539         {
6540           operands[2] = GEN_INT (-INTVAL (operands[2]));
6541           return "sub{b}\t{%2, %0|%0, %2}";
6542         }
6543       return "add{b}\t{%2, %0|%0, %2}";
6544     }
6545 }
6546   [(set (attr "type")
6547      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6548         (const_string "incdec")
6549         (const_string "alu")))
6550    (set_attr "mode" "QI")])
6551
6552 (define_insn "*add<mode>_3"
6553   [(set (reg FLAGS_REG)
6554         (compare
6555           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6556           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6557    (clobber (match_scratch:SWI48 0 "=r"))]
6558   "ix86_match_ccmode (insn, CCZmode)
6559    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6560    /* Current assemblers are broken and do not allow @GOTOFF in
6561       ought but a memory context.  */
6562    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6563 {
6564   switch (get_attr_type (insn))
6565     {
6566     case TYPE_INCDEC:
6567       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6568       if (operands[2] == const1_rtx)
6569         return "inc{<imodesuffix>}\t%0";
6570       else
6571         {
6572           gcc_assert (operands[2] == constm1_rtx);
6573           return "dec{<imodesuffix>}\t%0";
6574         }
6575
6576     default:
6577       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6578       /* ???? In DImode, we ought to handle there the 32bit case too
6579          - do we need new constraint?  */
6580       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6581          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6582       if (CONST_INT_P (operands[2])
6583           /* Avoid overflows.  */
6584           && (<MODE>mode != DImode
6585               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6586           && (INTVAL (operands[2]) == 128
6587               || (INTVAL (operands[2]) < 0
6588                   && INTVAL (operands[2]) != -128)))
6589         {
6590           operands[2] = GEN_INT (-INTVAL (operands[2]));
6591           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6592         }
6593       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6594     }
6595 }
6596   [(set (attr "type")
6597      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6598         (const_string "incdec")
6599         (const_string "alu")))
6600    (set (attr "length_immediate")
6601       (if_then_else
6602         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6603         (const_string "1")
6604         (const_string "*")))
6605    (set_attr "mode" "<MODE>")])
6606
6607 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6608 (define_insn "*addsi_3_zext"
6609   [(set (reg FLAGS_REG)
6610         (compare
6611           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6612           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6613    (set (match_operand:DI 0 "register_operand" "=r")
6614         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6615   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6616    && ix86_binary_operator_ok (PLUS, SImode, operands)
6617    /* Current assemblers are broken and do not allow @GOTOFF in
6618       ought but a memory context.  */
6619    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6620 {
6621   switch (get_attr_type (insn))
6622     {
6623     case TYPE_INCDEC:
6624       if (operands[2] == const1_rtx)
6625         return "inc{l}\t%k0";
6626       else
6627         {
6628           gcc_assert (operands[2] == constm1_rtx);
6629           return "dec{l}\t%k0";
6630         }
6631
6632     default:
6633       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6634          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6635       if (CONST_INT_P (operands[2])
6636           && (INTVAL (operands[2]) == 128
6637               || (INTVAL (operands[2]) < 0
6638                   && INTVAL (operands[2]) != -128)))
6639         {
6640           operands[2] = GEN_INT (-INTVAL (operands[2]));
6641           return "sub{l}\t{%2, %k0|%k0, %2}";
6642         }
6643       return "add{l}\t{%2, %k0|%k0, %2}";
6644     }
6645 }
6646   [(set (attr "type")
6647      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6648         (const_string "incdec")
6649         (const_string "alu")))
6650    (set (attr "length_immediate")
6651       (if_then_else
6652         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6653         (const_string "1")
6654         (const_string "*")))
6655    (set_attr "mode" "SI")])
6656
6657 (define_insn "*addhi_3"
6658   [(set (reg FLAGS_REG)
6659         (compare
6660           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6661           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6662    (clobber (match_scratch:HI 0 "=r"))]
6663   "ix86_match_ccmode (insn, CCZmode)
6664    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6665 {
6666   switch (get_attr_type (insn))
6667     {
6668     case TYPE_INCDEC:
6669       if (operands[2] == const1_rtx)
6670         return "inc{w}\t%0";
6671       else
6672         {
6673           gcc_assert (operands[2] == constm1_rtx);
6674           return "dec{w}\t%0";
6675         }
6676
6677     default:
6678       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6679          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6680       if (CONST_INT_P (operands[2])
6681           && (INTVAL (operands[2]) == 128
6682               || (INTVAL (operands[2]) < 0
6683                   && INTVAL (operands[2]) != -128)))
6684         {
6685           operands[2] = GEN_INT (-INTVAL (operands[2]));
6686           return "sub{w}\t{%2, %0|%0, %2}";
6687         }
6688       return "add{w}\t{%2, %0|%0, %2}";
6689     }
6690 }
6691   [(set (attr "type")
6692      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6693         (const_string "incdec")
6694         (const_string "alu")))
6695    (set (attr "length_immediate")
6696       (if_then_else
6697         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6698         (const_string "1")
6699         (const_string "*")))
6700    (set_attr "mode" "HI")])
6701
6702 (define_insn "*addqi_3"
6703   [(set (reg FLAGS_REG)
6704         (compare
6705           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6706           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6707    (clobber (match_scratch:QI 0 "=q"))]
6708   "ix86_match_ccmode (insn, CCZmode)
6709    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710 {
6711   switch (get_attr_type (insn))
6712     {
6713     case TYPE_INCDEC:
6714       if (operands[2] == const1_rtx)
6715         return "inc{b}\t%0";
6716       else
6717         {
6718           gcc_assert (operands[2] == constm1_rtx
6719                       || (CONST_INT_P (operands[2])
6720                           && INTVAL (operands[2]) == 255));
6721           return "dec{b}\t%0";
6722         }
6723
6724     default:
6725       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6726       if (CONST_INT_P (operands[2])
6727           && INTVAL (operands[2]) < 0)
6728         {
6729           operands[2] = GEN_INT (-INTVAL (operands[2]));
6730           return "sub{b}\t{%2, %0|%0, %2}";
6731         }
6732       return "add{b}\t{%2, %0|%0, %2}";
6733     }
6734 }
6735   [(set (attr "type")
6736      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6737         (const_string "incdec")
6738         (const_string "alu")))
6739    (set_attr "mode" "QI")])
6740
6741 ; For comparisons against 1, -1 and 128, we may generate better code
6742 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6743 ; is matched then.  We can't accept general immediate, because for
6744 ; case of overflows,  the result is messed up.
6745 ; This pattern also don't hold of 0x8000000000000000, since the value
6746 ; overflows when negated.
6747 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6748 ; only for comparisons not depending on it.
6749
6750 (define_insn "*adddi_4"
6751   [(set (reg FLAGS_REG)
6752         (compare
6753           (match_operand:DI 1 "nonimmediate_operand" "0")
6754           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6755    (clobber (match_scratch:DI 0 "=rm"))]
6756   "TARGET_64BIT
6757    && ix86_match_ccmode (insn, CCGCmode)"
6758 {
6759   switch (get_attr_type (insn))
6760     {
6761     case TYPE_INCDEC:
6762       if (operands[2] == constm1_rtx)
6763         return "inc{q}\t%0";
6764       else
6765         {
6766           gcc_assert (operands[2] == const1_rtx);
6767           return "dec{q}\t%0";
6768         }
6769
6770     default:
6771       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6773          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6774       if ((INTVAL (operands[2]) == -128
6775            || (INTVAL (operands[2]) > 0
6776                && INTVAL (operands[2]) != 128))
6777           /* Avoid overflows.  */
6778           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6779         return "sub{q}\t{%2, %0|%0, %2}";
6780       operands[2] = GEN_INT (-INTVAL (operands[2]));
6781       return "add{q}\t{%2, %0|%0, %2}";
6782     }
6783 }
6784   [(set (attr "type")
6785      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6786         (const_string "incdec")
6787         (const_string "alu")))
6788    (set (attr "length_immediate")
6789       (if_then_else
6790         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6791         (const_string "1")
6792         (const_string "*")))
6793    (set_attr "mode" "DI")])
6794
6795 ; For comparisons against 1, -1 and 128, we may generate better code
6796 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6797 ; is matched then.  We can't accept general immediate, because for
6798 ; case of overflows,  the result is messed up.
6799 ; This pattern also don't hold of 0x80000000, since the value overflows
6800 ; when negated.
6801 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6802 ; only for comparisons not depending on it.
6803
6804 (define_insn "*addsi_4"
6805   [(set (reg FLAGS_REG)
6806         (compare
6807           (match_operand:SI 1 "nonimmediate_operand" "0")
6808           (match_operand:SI 2 "const_int_operand" "n")))
6809    (clobber (match_scratch:SI 0 "=rm"))]
6810   "ix86_match_ccmode (insn, CCGCmode)
6811    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6812 {
6813   switch (get_attr_type (insn))
6814     {
6815     case TYPE_INCDEC:
6816       if (operands[2] == constm1_rtx)
6817         return "inc{l}\t%0";
6818       else
6819         {
6820           gcc_assert (operands[2] == const1_rtx);
6821           return "dec{l}\t%0";
6822         }
6823
6824     default:
6825       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6826       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6827          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6828       if ((INTVAL (operands[2]) == -128
6829            || (INTVAL (operands[2]) > 0
6830                && INTVAL (operands[2]) != 128)))
6831         return "sub{l}\t{%2, %0|%0, %2}";
6832       operands[2] = GEN_INT (-INTVAL (operands[2]));
6833       return "add{l}\t{%2, %0|%0, %2}";
6834     }
6835 }
6836   [(set (attr "type")
6837      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6838         (const_string "incdec")
6839         (const_string "alu")))
6840    (set (attr "length_immediate")
6841       (if_then_else
6842         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6843         (const_string "1")
6844         (const_string "*")))
6845    (set_attr "mode" "SI")])
6846
6847 ; See comments above addsi_4 for details.
6848
6849 (define_insn "*addhi_4"
6850   [(set (reg FLAGS_REG)
6851         (compare
6852           (match_operand:HI 1 "nonimmediate_operand" "0")
6853           (match_operand:HI 2 "const_int_operand" "n")))
6854    (clobber (match_scratch:HI 0 "=rm"))]
6855   "ix86_match_ccmode (insn, CCGCmode)
6856    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6857 {
6858   switch (get_attr_type (insn))
6859     {
6860     case TYPE_INCDEC:
6861       if (operands[2] == constm1_rtx)
6862         return "inc{w}\t%0";
6863       else
6864         {
6865           gcc_assert (operands[2] == const1_rtx);
6866           return "dec{w}\t%0";
6867         }
6868
6869     default:
6870       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6871       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6872          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6873       if ((INTVAL (operands[2]) == -128
6874            || (INTVAL (operands[2]) > 0
6875                && INTVAL (operands[2]) != 128)))
6876         return "sub{w}\t{%2, %0|%0, %2}";
6877       operands[2] = GEN_INT (-INTVAL (operands[2]));
6878       return "add{w}\t{%2, %0|%0, %2}";
6879     }
6880 }
6881   [(set (attr "type")
6882      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6883         (const_string "incdec")
6884         (const_string "alu")))
6885    (set (attr "length_immediate")
6886       (if_then_else
6887         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6888         (const_string "1")
6889         (const_string "*")))
6890    (set_attr "mode" "HI")])
6891
6892 ; See comments above addsi_4 for details.
6893
6894 (define_insn "*addqi_4"
6895   [(set (reg FLAGS_REG)
6896         (compare
6897           (match_operand:QI 1 "nonimmediate_operand" "0")
6898           (match_operand:QI 2 "const_int_operand" "n")))
6899    (clobber (match_scratch:QI 0 "=qm"))]
6900   "ix86_match_ccmode (insn, CCGCmode)
6901    && (INTVAL (operands[2]) & 0xff) != 0x80"
6902 {
6903   switch (get_attr_type (insn))
6904     {
6905     case TYPE_INCDEC:
6906       if (operands[2] == constm1_rtx
6907           || (CONST_INT_P (operands[2])
6908               && INTVAL (operands[2]) == 255))
6909         return "inc{b}\t%0";
6910       else
6911         {
6912           gcc_assert (operands[2] == const1_rtx);
6913           return "dec{b}\t%0";
6914         }
6915
6916     default:
6917       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6918       if (INTVAL (operands[2]) < 0)
6919         {
6920           operands[2] = GEN_INT (-INTVAL (operands[2]));
6921           return "add{b}\t{%2, %0|%0, %2}";
6922         }
6923       return "sub{b}\t{%2, %0|%0, %2}";
6924     }
6925 }
6926   [(set (attr "type")
6927      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6928         (const_string "incdec")
6929         (const_string "alu")))
6930    (set_attr "mode" "QI")])
6931
6932 (define_insn "*add<mode>_5"
6933   [(set (reg FLAGS_REG)
6934         (compare
6935           (plus:SWI48
6936             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6937             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6938           (const_int 0)))
6939    (clobber (match_scratch:SWI48 0 "=r"))]
6940   "ix86_match_ccmode (insn, CCGOCmode)
6941    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6942    /* Current assemblers are broken and do not allow @GOTOFF in
6943       ought but a memory context.  */
6944    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6945 {
6946   switch (get_attr_type (insn))
6947     {
6948     case TYPE_INCDEC:
6949       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6950       if (operands[2] == const1_rtx)
6951         return "inc{<imodesuffix>}\t%0";
6952       else
6953         {
6954           gcc_assert (operands[2] == constm1_rtx);
6955           return "dec{<imodesuffix>}\t%0";
6956         }
6957
6958     default:
6959       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6960       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6961          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6962       if (CONST_INT_P (operands[2])
6963           /* Avoid overflows.  */
6964           && (<MODE>mode != DImode
6965               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6966           && (INTVAL (operands[2]) == 128
6967               || (INTVAL (operands[2]) < 0
6968                   && INTVAL (operands[2]) != -128)))
6969         {
6970           operands[2] = GEN_INT (-INTVAL (operands[2]));
6971           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6972         }
6973       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6974     }
6975 }
6976   [(set (attr "type")
6977      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6978         (const_string "incdec")
6979         (const_string "alu")))
6980    (set (attr "length_immediate")
6981       (if_then_else
6982         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6983         (const_string "1")
6984         (const_string "*")))
6985    (set_attr "mode" "<MODE>")])
6986
6987 (define_insn "*addhi_5"
6988   [(set (reg FLAGS_REG)
6989         (compare
6990           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6991                    (match_operand:HI 2 "general_operand" "rmn"))
6992           (const_int 0)))
6993    (clobber (match_scratch:HI 0 "=r"))]
6994   "ix86_match_ccmode (insn, CCGOCmode)
6995    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6996 {
6997   switch (get_attr_type (insn))
6998     {
6999     case TYPE_INCDEC:
7000       if (operands[2] == const1_rtx)
7001         return "inc{w}\t%0";
7002       else
7003         {
7004           gcc_assert (operands[2] == constm1_rtx);
7005           return "dec{w}\t%0";
7006         }
7007
7008     default:
7009       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7010          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7011       if (CONST_INT_P (operands[2])
7012           && (INTVAL (operands[2]) == 128
7013               || (INTVAL (operands[2]) < 0
7014                   && INTVAL (operands[2]) != -128)))
7015         {
7016           operands[2] = GEN_INT (-INTVAL (operands[2]));
7017           return "sub{w}\t{%2, %0|%0, %2}";
7018         }
7019       return "add{w}\t{%2, %0|%0, %2}";
7020     }
7021 }
7022   [(set (attr "type")
7023      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7024         (const_string "incdec")
7025         (const_string "alu")))
7026    (set (attr "length_immediate")
7027       (if_then_else
7028         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7029         (const_string "1")
7030         (const_string "*")))
7031    (set_attr "mode" "HI")])
7032
7033 (define_insn "*addqi_5"
7034   [(set (reg FLAGS_REG)
7035         (compare
7036           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7037                    (match_operand:QI 2 "general_operand" "qmn"))
7038           (const_int 0)))
7039    (clobber (match_scratch:QI 0 "=q"))]
7040   "ix86_match_ccmode (insn, CCGOCmode)
7041    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7042 {
7043   switch (get_attr_type (insn))
7044     {
7045     case TYPE_INCDEC:
7046       if (operands[2] == const1_rtx)
7047         return "inc{b}\t%0";
7048       else
7049         {
7050           gcc_assert (operands[2] == constm1_rtx
7051                       || (CONST_INT_P (operands[2])
7052                           && INTVAL (operands[2]) == 255));
7053           return "dec{b}\t%0";
7054         }
7055
7056     default:
7057       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7058       if (CONST_INT_P (operands[2])
7059           && INTVAL (operands[2]) < 0)
7060         {
7061           operands[2] = GEN_INT (-INTVAL (operands[2]));
7062           return "sub{b}\t{%2, %0|%0, %2}";
7063         }
7064       return "add{b}\t{%2, %0|%0, %2}";
7065     }
7066 }
7067   [(set (attr "type")
7068      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7069         (const_string "incdec")
7070         (const_string "alu")))
7071    (set_attr "mode" "QI")])
7072
7073 (define_insn "*addqi_ext_1_rex64"
7074   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7075                          (const_int 8)
7076                          (const_int 8))
7077         (plus:SI
7078           (zero_extract:SI
7079             (match_operand 1 "ext_register_operand" "0")
7080             (const_int 8)
7081             (const_int 8))
7082           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7083    (clobber (reg:CC FLAGS_REG))]
7084   "TARGET_64BIT"
7085 {
7086   switch (get_attr_type (insn))
7087     {
7088     case TYPE_INCDEC:
7089       if (operands[2] == const1_rtx)
7090         return "inc{b}\t%h0";
7091       else
7092         {
7093           gcc_assert (operands[2] == constm1_rtx
7094                       || (CONST_INT_P (operands[2])
7095                           && INTVAL (operands[2]) == 255));
7096           return "dec{b}\t%h0";
7097         }
7098
7099     default:
7100       return "add{b}\t{%2, %h0|%h0, %2}";
7101     }
7102 }
7103   [(set (attr "type")
7104      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7105         (const_string "incdec")
7106         (const_string "alu")))
7107    (set_attr "modrm" "1")
7108    (set_attr "mode" "QI")])
7109
7110 (define_insn "addqi_ext_1"
7111   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7112                          (const_int 8)
7113                          (const_int 8))
7114         (plus:SI
7115           (zero_extract:SI
7116             (match_operand 1 "ext_register_operand" "0")
7117             (const_int 8)
7118             (const_int 8))
7119           (match_operand:QI 2 "general_operand" "Qmn")))
7120    (clobber (reg:CC FLAGS_REG))]
7121   "!TARGET_64BIT"
7122 {
7123   switch (get_attr_type (insn))
7124     {
7125     case TYPE_INCDEC:
7126       if (operands[2] == const1_rtx)
7127         return "inc{b}\t%h0";
7128       else
7129         {
7130           gcc_assert (operands[2] == constm1_rtx
7131                       || (CONST_INT_P (operands[2])
7132                           && INTVAL (operands[2]) == 255));
7133           return "dec{b}\t%h0";
7134         }
7135
7136     default:
7137       return "add{b}\t{%2, %h0|%h0, %2}";
7138     }
7139 }
7140   [(set (attr "type")
7141      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7142         (const_string "incdec")
7143         (const_string "alu")))
7144    (set_attr "modrm" "1")
7145    (set_attr "mode" "QI")])
7146
7147 (define_insn "*addqi_ext_2"
7148   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7149                          (const_int 8)
7150                          (const_int 8))
7151         (plus:SI
7152           (zero_extract:SI
7153             (match_operand 1 "ext_register_operand" "%0")
7154             (const_int 8)
7155             (const_int 8))
7156           (zero_extract:SI
7157             (match_operand 2 "ext_register_operand" "Q")
7158             (const_int 8)
7159             (const_int 8))))
7160    (clobber (reg:CC FLAGS_REG))]
7161   ""
7162   "add{b}\t{%h2, %h0|%h0, %h2}"
7163   [(set_attr "type" "alu")
7164    (set_attr "mode" "QI")])
7165
7166 ;; The lea patterns for non-Pmodes needs to be matched by
7167 ;; several insns converted to real lea by splitters.
7168
7169 (define_insn_and_split "*lea_general_1"
7170   [(set (match_operand 0 "register_operand" "=r")
7171         (plus (plus (match_operand 1 "index_register_operand" "l")
7172                     (match_operand 2 "register_operand" "r"))
7173               (match_operand 3 "immediate_operand" "i")))]
7174   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7175     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7176    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7177    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7178    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7179    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7180        || GET_MODE (operands[3]) == VOIDmode)"
7181   "#"
7182   "&& reload_completed"
7183   [(const_int 0)]
7184 {
7185   rtx pat;
7186   operands[0] = gen_lowpart (SImode, operands[0]);
7187   operands[1] = gen_lowpart (Pmode, operands[1]);
7188   operands[2] = gen_lowpart (Pmode, operands[2]);
7189   operands[3] = gen_lowpart (Pmode, operands[3]);
7190   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7191                       operands[3]);
7192   if (Pmode != SImode)
7193     pat = gen_rtx_SUBREG (SImode, pat, 0);
7194   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7195   DONE;
7196 }
7197   [(set_attr "type" "lea")
7198    (set_attr "mode" "SI")])
7199
7200 (define_insn_and_split "*lea_general_1_zext"
7201   [(set (match_operand:DI 0 "register_operand" "=r")
7202         (zero_extend:DI
7203           (plus:SI (plus:SI
7204                      (match_operand:SI 1 "index_register_operand" "l")
7205                      (match_operand:SI 2 "register_operand" "r"))
7206                    (match_operand:SI 3 "immediate_operand" "i"))))]
7207   "TARGET_64BIT"
7208   "#"
7209   "&& reload_completed"
7210   [(set (match_dup 0)
7211         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7212                                                      (match_dup 2))
7213                                             (match_dup 3)) 0)))]
7214 {
7215   operands[1] = gen_lowpart (Pmode, operands[1]);
7216   operands[2] = gen_lowpart (Pmode, operands[2]);
7217   operands[3] = gen_lowpart (Pmode, operands[3]);
7218 }
7219   [(set_attr "type" "lea")
7220    (set_attr "mode" "SI")])
7221
7222 (define_insn_and_split "*lea_general_2"
7223   [(set (match_operand 0 "register_operand" "=r")
7224         (plus (mult (match_operand 1 "index_register_operand" "l")
7225                     (match_operand 2 "const248_operand" "i"))
7226               (match_operand 3 "nonmemory_operand" "ri")))]
7227   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7228     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7229    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7230    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7231    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7232        || GET_MODE (operands[3]) == VOIDmode)"
7233   "#"
7234   "&& reload_completed"
7235   [(const_int 0)]
7236 {
7237   rtx pat;
7238   operands[0] = gen_lowpart (SImode, operands[0]);
7239   operands[1] = gen_lowpart (Pmode, operands[1]);
7240   operands[3] = gen_lowpart (Pmode, operands[3]);
7241   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7242                       operands[3]);
7243   if (Pmode != SImode)
7244     pat = gen_rtx_SUBREG (SImode, pat, 0);
7245   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7246   DONE;
7247 }
7248   [(set_attr "type" "lea")
7249    (set_attr "mode" "SI")])
7250
7251 (define_insn_and_split "*lea_general_2_zext"
7252   [(set (match_operand:DI 0 "register_operand" "=r")
7253         (zero_extend:DI
7254           (plus:SI (mult:SI
7255                      (match_operand:SI 1 "index_register_operand" "l")
7256                      (match_operand:SI 2 "const248_operand" "n"))
7257                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7258   "TARGET_64BIT"
7259   "#"
7260   "&& reload_completed"
7261   [(set (match_dup 0)
7262         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7263                                                      (match_dup 2))
7264                                             (match_dup 3)) 0)))]
7265 {
7266   operands[1] = gen_lowpart (Pmode, operands[1]);
7267   operands[3] = gen_lowpart (Pmode, operands[3]);
7268 }
7269   [(set_attr "type" "lea")
7270    (set_attr "mode" "SI")])
7271
7272 (define_insn_and_split "*lea_general_3"
7273   [(set (match_operand 0 "register_operand" "=r")
7274         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7275                           (match_operand 2 "const248_operand" "i"))
7276                     (match_operand 3 "register_operand" "r"))
7277               (match_operand 4 "immediate_operand" "i")))]
7278   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7279     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7280    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7281    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7282    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7283   "#"
7284   "&& reload_completed"
7285   [(const_int 0)]
7286 {
7287   rtx pat;
7288   operands[0] = gen_lowpart (SImode, operands[0]);
7289   operands[1] = gen_lowpart (Pmode, operands[1]);
7290   operands[3] = gen_lowpart (Pmode, operands[3]);
7291   operands[4] = gen_lowpart (Pmode, operands[4]);
7292   pat = gen_rtx_PLUS (Pmode,
7293                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7294                                                          operands[2]),
7295                                     operands[3]),
7296                       operands[4]);
7297   if (Pmode != SImode)
7298     pat = gen_rtx_SUBREG (SImode, pat, 0);
7299   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7300   DONE;
7301 }
7302   [(set_attr "type" "lea")
7303    (set_attr "mode" "SI")])
7304
7305 (define_insn_and_split "*lea_general_3_zext"
7306   [(set (match_operand:DI 0 "register_operand" "=r")
7307         (zero_extend:DI
7308           (plus:SI (plus:SI
7309                      (mult:SI
7310                        (match_operand:SI 1 "index_register_operand" "l")
7311                        (match_operand:SI 2 "const248_operand" "n"))
7312                      (match_operand:SI 3 "register_operand" "r"))
7313                    (match_operand:SI 4 "immediate_operand" "i"))))]
7314   "TARGET_64BIT"
7315   "#"
7316   "&& reload_completed"
7317   [(set (match_dup 0)
7318         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7319                                                               (match_dup 2))
7320                                                      (match_dup 3))
7321                                             (match_dup 4)) 0)))]
7322 {
7323   operands[1] = gen_lowpart (Pmode, operands[1]);
7324   operands[3] = gen_lowpart (Pmode, operands[3]);
7325   operands[4] = gen_lowpart (Pmode, operands[4]);
7326 }
7327   [(set_attr "type" "lea")
7328    (set_attr "mode" "SI")])
7329
7330 ;; Convert lea to the lea pattern to avoid flags dependency.
7331 (define_split
7332   [(set (match_operand:DI 0 "register_operand" "")
7333         (plus:DI (match_operand:DI 1 "register_operand" "")
7334                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7335    (clobber (reg:CC FLAGS_REG))]
7336   "TARGET_64BIT && reload_completed 
7337    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7338   [(set (match_dup 0)
7339         (plus:DI (match_dup 1)
7340                  (match_dup 2)))]
7341   "")
7342
7343 ;; Convert lea to the lea pattern to avoid flags dependency.
7344 (define_split
7345   [(set (match_operand 0 "register_operand" "")
7346         (plus (match_operand 1 "register_operand" "")
7347               (match_operand 2 "nonmemory_operand" "")))
7348    (clobber (reg:CC FLAGS_REG))]
7349   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7350   [(const_int 0)]
7351 {
7352   rtx pat;
7353   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7354      may confuse gen_lowpart.  */
7355   if (GET_MODE (operands[0]) != Pmode)
7356     {
7357       operands[1] = gen_lowpart (Pmode, operands[1]);
7358       operands[2] = gen_lowpart (Pmode, operands[2]);
7359     }
7360   operands[0] = gen_lowpart (SImode, operands[0]);
7361   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7362   if (Pmode != SImode)
7363     pat = gen_rtx_SUBREG (SImode, pat, 0);
7364   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7365   DONE;
7366 })
7367
7368 ;; Convert lea to the lea pattern to avoid flags dependency.
7369 (define_split
7370   [(set (match_operand:DI 0 "register_operand" "")
7371         (zero_extend:DI
7372           (plus:SI (match_operand:SI 1 "register_operand" "")
7373                    (match_operand:SI 2 "nonmemory_operand" ""))))
7374    (clobber (reg:CC FLAGS_REG))]
7375   "TARGET_64BIT && reload_completed
7376    && true_regnum (operands[0]) != true_regnum (operands[1])"
7377   [(set (match_dup 0)
7378         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7379 {
7380   operands[1] = gen_lowpart (Pmode, operands[1]);
7381   operands[2] = gen_lowpart (Pmode, operands[2]);
7382 })
7383 \f
7384 ;; Subtract instructions
7385
7386 (define_expand "sub<mode>3"
7387   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7388         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7389                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7390   ""
7391   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7392
7393 (define_insn_and_split "*sub<dwi>3_doubleword"
7394   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7395         (minus:<DWI>
7396           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7397           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7398    (clobber (reg:CC FLAGS_REG))]
7399   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7400   "#"
7401   "reload_completed"
7402   [(parallel [(set (reg:CC FLAGS_REG)
7403                    (compare:CC (match_dup 1) (match_dup 2)))
7404               (set (match_dup 0)
7405                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7406    (parallel [(set (match_dup 3)
7407                    (minus:DWIH
7408                      (match_dup 4)
7409                      (plus:DWIH
7410                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7411                        (match_dup 5))))
7412               (clobber (reg:CC FLAGS_REG))])]
7413   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7414
7415 (define_insn "*sub<mode>_1"
7416   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7417         (minus:SWI
7418           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7419           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7420    (clobber (reg:CC FLAGS_REG))]
7421   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7422   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7423   [(set_attr "type" "alu")
7424    (set_attr "mode" "<MODE>")])
7425
7426 (define_insn "*subsi_1_zext"
7427   [(set (match_operand:DI 0 "register_operand" "=r")
7428         (zero_extend:DI
7429           (minus:SI (match_operand:SI 1 "register_operand" "0")
7430                     (match_operand:SI 2 "general_operand" "g"))))
7431    (clobber (reg:CC FLAGS_REG))]
7432   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7433   "sub{l}\t{%2, %k0|%k0, %2}"
7434   [(set_attr "type" "alu")
7435    (set_attr "mode" "SI")])
7436
7437 (define_insn "*subqi_1_slp"
7438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7439         (minus:QI (match_dup 0)
7440                   (match_operand:QI 1 "general_operand" "qn,qm")))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7443    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7444   "sub{b}\t{%1, %0|%0, %1}"
7445   [(set_attr "type" "alu1")
7446    (set_attr "mode" "QI")])
7447
7448 (define_insn "*sub<mode>_2"
7449   [(set (reg FLAGS_REG)
7450         (compare
7451           (minus:SWI
7452             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7453             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7454           (const_int 0)))
7455    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7456         (minus:SWI (match_dup 1) (match_dup 2)))]
7457   "ix86_match_ccmode (insn, CCGOCmode)
7458    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7459   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7460   [(set_attr "type" "alu")
7461    (set_attr "mode" "<MODE>")])
7462
7463 (define_insn "*subsi_2_zext"
7464   [(set (reg FLAGS_REG)
7465         (compare
7466           (minus:SI (match_operand:SI 1 "register_operand" "0")
7467                     (match_operand:SI 2 "general_operand" "g"))
7468           (const_int 0)))
7469    (set (match_operand:DI 0 "register_operand" "=r")
7470         (zero_extend:DI
7471           (minus:SI (match_dup 1)
7472                     (match_dup 2))))]
7473   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7474    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7475   "sub{l}\t{%2, %k0|%k0, %2}"
7476   [(set_attr "type" "alu")
7477    (set_attr "mode" "SI")])
7478
7479 (define_insn "*sub<mode>_3"
7480   [(set (reg FLAGS_REG)
7481         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7482                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7483    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7484         (minus:SWI (match_dup 1) (match_dup 2)))]
7485   "ix86_match_ccmode (insn, CCmode)
7486    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7487   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7488   [(set_attr "type" "alu")
7489    (set_attr "mode" "<MODE>")])
7490
7491 (define_insn "*subsi_3_zext"
7492   [(set (reg FLAGS_REG)
7493         (compare (match_operand:SI 1 "register_operand" "0")
7494                  (match_operand:SI 2 "general_operand" "g")))
7495    (set (match_operand:DI 0 "register_operand" "=r")
7496         (zero_extend:DI
7497           (minus:SI (match_dup 1)
7498                     (match_dup 2))))]
7499   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7500    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7501   "sub{l}\t{%2, %1|%1, %2}"
7502   [(set_attr "type" "alu")
7503    (set_attr "mode" "SI")])
7504 \f
7505 ;; Add with carry and subtract with borrow
7506
7507 (define_expand "<plusminus_insn><mode>3_carry"
7508   [(parallel
7509     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7510           (plusminus:SWI
7511             (match_operand:SWI 1 "nonimmediate_operand" "")
7512             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7513                        [(match_operand 3 "flags_reg_operand" "")
7514                         (const_int 0)])
7515                       (match_operand:SWI 2 "<general_operand>" ""))))
7516      (clobber (reg:CC FLAGS_REG))])]
7517   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7518   "")
7519
7520 (define_insn "*<plusminus_insn><mode>3_carry"
7521   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7522         (plusminus:SWI
7523           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7524           (plus:SWI
7525             (match_operator 3 "ix86_carry_flag_operator"
7526              [(reg FLAGS_REG) (const_int 0)])
7527             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7528    (clobber (reg:CC FLAGS_REG))]
7529   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7530   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7531   [(set_attr "type" "alu")
7532    (set_attr "use_carry" "1")
7533    (set_attr "pent_pair" "pu")
7534    (set_attr "mode" "<MODE>")])
7535
7536 (define_insn "*addsi3_carry_zext"
7537   [(set (match_operand:DI 0 "register_operand" "=r")
7538         (zero_extend:DI
7539           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7540                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7541                              [(reg FLAGS_REG) (const_int 0)])
7542                             (match_operand:SI 2 "general_operand" "g")))))
7543    (clobber (reg:CC FLAGS_REG))]
7544   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7545   "adc{l}\t{%2, %k0|%k0, %2}"
7546   [(set_attr "type" "alu")
7547    (set_attr "use_carry" "1")
7548    (set_attr "pent_pair" "pu")
7549    (set_attr "mode" "SI")])
7550
7551 (define_insn "*subsi3_carry_zext"
7552   [(set (match_operand:DI 0 "register_operand" "=r")
7553         (zero_extend:DI
7554           (minus:SI (match_operand:SI 1 "register_operand" "0")
7555                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7556                               [(reg FLAGS_REG) (const_int 0)])
7557                              (match_operand:SI 2 "general_operand" "g")))))
7558    (clobber (reg:CC FLAGS_REG))]
7559   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7560   "sbb{l}\t{%2, %k0|%k0, %2}"
7561   [(set_attr "type" "alu")
7562    (set_attr "pent_pair" "pu")
7563    (set_attr "mode" "SI")])
7564 \f
7565 ;; Overflow setting add and subtract instructions
7566
7567 (define_insn "*add<mode>3_cconly_overflow"
7568   [(set (reg:CCC FLAGS_REG)
7569         (compare:CCC
7570           (plus:SWI
7571             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7572             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7573           (match_dup 1)))
7574    (clobber (match_scratch:SWI 0 "=<r>"))]
7575   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7576   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7577   [(set_attr "type" "alu")
7578    (set_attr "mode" "<MODE>")])
7579
7580 (define_insn "*sub<mode>3_cconly_overflow"
7581   [(set (reg:CCC FLAGS_REG)
7582         (compare:CCC
7583           (minus:SWI
7584             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7585             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7586           (match_dup 0)))]
7587   ""
7588   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7589   [(set_attr "type" "icmp")
7590    (set_attr "mode" "<MODE>")])
7591
7592 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7593   [(set (reg:CCC FLAGS_REG)
7594         (compare:CCC
7595             (plusminus:SWI
7596                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7597                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7598             (match_dup 1)))
7599    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7600         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7601   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7602   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7603   [(set_attr "type" "alu")
7604    (set_attr "mode" "<MODE>")])
7605
7606 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7607   [(set (reg:CCC FLAGS_REG)
7608         (compare:CCC
7609           (plusminus:SI
7610             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7611             (match_operand:SI 2 "general_operand" "g"))
7612           (match_dup 1)))
7613    (set (match_operand:DI 0 "register_operand" "=r")
7614         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7615   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7616   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7617   [(set_attr "type" "alu")
7618    (set_attr "mode" "SI")])
7619
7620 ;; The patterns that match these are at the end of this file.
7621
7622 (define_expand "<plusminus_insn>xf3"
7623   [(set (match_operand:XF 0 "register_operand" "")
7624         (plusminus:XF
7625           (match_operand:XF 1 "register_operand" "")
7626           (match_operand:XF 2 "register_operand" "")))]
7627   "TARGET_80387"
7628   "")
7629
7630 (define_expand "<plusminus_insn><mode>3"
7631   [(set (match_operand:MODEF 0 "register_operand" "")
7632         (plusminus:MODEF
7633           (match_operand:MODEF 1 "register_operand" "")
7634           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7635   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7636     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7637   "")
7638 \f
7639 ;; Multiply instructions
7640
7641 (define_expand "mul<mode>3"
7642   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7643                    (mult:SWIM248
7644                      (match_operand:SWIM248 1 "register_operand" "")
7645                      (match_operand:SWIM248 2 "<general_operand>" "")))
7646               (clobber (reg:CC FLAGS_REG))])]
7647   ""
7648   "")
7649
7650 (define_expand "mulqi3"
7651   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7652                    (mult:QI
7653                      (match_operand:QI 1 "register_operand" "")
7654                      (match_operand:QI 2 "nonimmediate_operand" "")))
7655               (clobber (reg:CC FLAGS_REG))])]
7656   "TARGET_QIMODE_MATH"
7657   "")
7658
7659 ;; On AMDFAM10
7660 ;; IMUL reg32/64, reg32/64, imm8        Direct
7661 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7662 ;; IMUL reg32/64, reg32/64, imm32       Direct
7663 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7664 ;; IMUL reg32/64, reg32/64              Direct
7665 ;; IMUL reg32/64, mem32/64              Direct
7666
7667 (define_insn "*mul<mode>3_1"
7668   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7669         (mult:SWI48
7670           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7671           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7672    (clobber (reg:CC FLAGS_REG))]
7673   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7674   "@
7675    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7676    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7677    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7678   [(set_attr "type" "imul")
7679    (set_attr "prefix_0f" "0,0,1")
7680    (set (attr "athlon_decode")
7681         (cond [(eq_attr "cpu" "athlon")
7682                   (const_string "vector")
7683                (eq_attr "alternative" "1")
7684                   (const_string "vector")
7685                (and (eq_attr "alternative" "2")
7686                     (match_operand 1 "memory_operand" ""))
7687                   (const_string "vector")]
7688               (const_string "direct")))
7689    (set (attr "amdfam10_decode")
7690         (cond [(and (eq_attr "alternative" "0,1")
7691                     (match_operand 1 "memory_operand" ""))
7692                   (const_string "vector")]
7693               (const_string "direct")))
7694    (set_attr "mode" "<MODE>")])
7695
7696 (define_insn "*mulsi3_1_zext"
7697   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7698         (zero_extend:DI
7699           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7700                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7701    (clobber (reg:CC FLAGS_REG))]
7702   "TARGET_64BIT
7703    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7704   "@
7705    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7706    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7707    imul{l}\t{%2, %k0|%k0, %2}"
7708   [(set_attr "type" "imul")
7709    (set_attr "prefix_0f" "0,0,1")
7710    (set (attr "athlon_decode")
7711         (cond [(eq_attr "cpu" "athlon")
7712                   (const_string "vector")
7713                (eq_attr "alternative" "1")
7714                   (const_string "vector")
7715                (and (eq_attr "alternative" "2")
7716                     (match_operand 1 "memory_operand" ""))
7717                   (const_string "vector")]
7718               (const_string "direct")))
7719    (set (attr "amdfam10_decode")
7720         (cond [(and (eq_attr "alternative" "0,1")
7721                     (match_operand 1 "memory_operand" ""))
7722                   (const_string "vector")]
7723               (const_string "direct")))
7724    (set_attr "mode" "SI")])
7725
7726 ;; On AMDFAM10
7727 ;; IMUL reg16, reg16, imm8      VectorPath
7728 ;; IMUL reg16, mem16, imm8      VectorPath
7729 ;; IMUL reg16, reg16, imm16     VectorPath
7730 ;; IMUL reg16, mem16, imm16     VectorPath
7731 ;; IMUL reg16, reg16            Direct
7732 ;; IMUL reg16, mem16            Direct
7733
7734 (define_insn "*mulhi3_1"
7735   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7736         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7737                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7738    (clobber (reg:CC FLAGS_REG))]
7739   "TARGET_HIMODE_MATH
7740    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7741   "@
7742    imul{w}\t{%2, %1, %0|%0, %1, %2}
7743    imul{w}\t{%2, %1, %0|%0, %1, %2}
7744    imul{w}\t{%2, %0|%0, %2}"
7745   [(set_attr "type" "imul")
7746    (set_attr "prefix_0f" "0,0,1")
7747    (set (attr "athlon_decode")
7748         (cond [(eq_attr "cpu" "athlon")
7749                   (const_string "vector")
7750                (eq_attr "alternative" "1,2")
7751                   (const_string "vector")]
7752               (const_string "direct")))
7753    (set (attr "amdfam10_decode")
7754         (cond [(eq_attr "alternative" "0,1")
7755                   (const_string "vector")]
7756               (const_string "direct")))
7757    (set_attr "mode" "HI")])
7758
7759 ;;On AMDFAM10
7760 ;; MUL reg8     Direct
7761 ;; MUL mem8     Direct
7762
7763 (define_insn "*mulqi3_1"
7764   [(set (match_operand:QI 0 "register_operand" "=a")
7765         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7766                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7767    (clobber (reg:CC FLAGS_REG))]
7768   "TARGET_QIMODE_MATH
7769    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7770   "mul{b}\t%2"
7771   [(set_attr "type" "imul")
7772    (set_attr "length_immediate" "0")
7773    (set (attr "athlon_decode")
7774      (if_then_else (eq_attr "cpu" "athlon")
7775         (const_string "vector")
7776         (const_string "direct")))
7777    (set_attr "amdfam10_decode" "direct")
7778    (set_attr "mode" "QI")])
7779
7780 (define_expand "<u>mul<mode><dwi>3"
7781   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7782                    (mult:<DWI>
7783                      (any_extend:<DWI>
7784                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7785                      (any_extend:<DWI>
7786                        (match_operand:DWIH 2 "register_operand" ""))))
7787               (clobber (reg:CC FLAGS_REG))])]
7788   ""
7789   "")
7790
7791 (define_expand "<u>mulqihi3"
7792   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7793                    (mult:HI
7794                      (any_extend:HI
7795                        (match_operand:QI 1 "nonimmediate_operand" ""))
7796                      (any_extend:HI
7797                        (match_operand:QI 2 "register_operand" ""))))
7798               (clobber (reg:CC FLAGS_REG))])]
7799   "TARGET_QIMODE_MATH"
7800   "")
7801
7802 (define_insn "*<u>mul<mode><dwi>3_1"
7803   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7804         (mult:<DWI>
7805           (any_extend:<DWI>
7806             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7807           (any_extend:<DWI>
7808             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7809    (clobber (reg:CC FLAGS_REG))]
7810   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7811   "<sgnprefix>mul{<imodesuffix>}\t%2"
7812   [(set_attr "type" "imul")
7813    (set_attr "length_immediate" "0")
7814    (set (attr "athlon_decode")
7815      (if_then_else (eq_attr "cpu" "athlon")
7816         (const_string "vector")
7817         (const_string "double")))
7818    (set_attr "amdfam10_decode" "double")
7819    (set_attr "mode" "<MODE>")])
7820
7821 (define_insn "*<u>mulqihi3_1"
7822   [(set (match_operand:HI 0 "register_operand" "=a")
7823         (mult:HI
7824           (any_extend:HI
7825             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7826           (any_extend:HI
7827             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7828    (clobber (reg:CC FLAGS_REG))]
7829   "TARGET_QIMODE_MATH
7830    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7831   "<sgnprefix>mul{b}\t%2"
7832   [(set_attr "type" "imul")
7833    (set_attr "length_immediate" "0")
7834    (set (attr "athlon_decode")
7835      (if_then_else (eq_attr "cpu" "athlon")
7836         (const_string "vector")
7837         (const_string "direct")))
7838    (set_attr "amdfam10_decode" "direct")
7839    (set_attr "mode" "QI")])
7840
7841 (define_expand "<s>mul<mode>3_highpart"
7842   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7843                    (truncate:SWI48
7844                      (lshiftrt:<DWI>
7845                        (mult:<DWI>
7846                          (any_extend:<DWI>
7847                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7848                          (any_extend:<DWI>
7849                            (match_operand:SWI48 2 "register_operand" "")))
7850                        (match_dup 4))))
7851               (clobber (match_scratch:SWI48 3 ""))
7852               (clobber (reg:CC FLAGS_REG))])]
7853   ""
7854   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7855
7856 (define_insn "*<s>muldi3_highpart_1"
7857   [(set (match_operand:DI 0 "register_operand" "=d")
7858         (truncate:DI
7859           (lshiftrt:TI
7860             (mult:TI
7861               (any_extend:TI
7862                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7863               (any_extend:TI
7864                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7865             (const_int 64))))
7866    (clobber (match_scratch:DI 3 "=1"))
7867    (clobber (reg:CC FLAGS_REG))]
7868   "TARGET_64BIT
7869    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7870   "<sgnprefix>mul{q}\t%2"
7871   [(set_attr "type" "imul")
7872    (set_attr "length_immediate" "0")
7873    (set (attr "athlon_decode")
7874      (if_then_else (eq_attr "cpu" "athlon")
7875         (const_string "vector")
7876         (const_string "double")))
7877    (set_attr "amdfam10_decode" "double")
7878    (set_attr "mode" "DI")])
7879
7880 (define_insn "*<s>mulsi3_highpart_1"
7881   [(set (match_operand:SI 0 "register_operand" "=d")
7882         (truncate:SI
7883           (lshiftrt:DI
7884             (mult:DI
7885               (any_extend:DI
7886                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7887               (any_extend:DI
7888                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7889             (const_int 32))))
7890    (clobber (match_scratch:SI 3 "=1"))
7891    (clobber (reg:CC FLAGS_REG))]
7892   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7893   "<sgnprefix>mul{l}\t%2"
7894   [(set_attr "type" "imul")
7895    (set_attr "length_immediate" "0")
7896    (set (attr "athlon_decode")
7897      (if_then_else (eq_attr "cpu" "athlon")
7898         (const_string "vector")
7899         (const_string "double")))
7900    (set_attr "amdfam10_decode" "double")
7901    (set_attr "mode" "SI")])
7902
7903 (define_insn "*<s>mulsi3_highpart_zext"
7904   [(set (match_operand:DI 0 "register_operand" "=d")
7905         (zero_extend:DI (truncate:SI
7906           (lshiftrt:DI
7907             (mult:DI (any_extend:DI
7908                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7909                      (any_extend:DI
7910                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7911             (const_int 32)))))
7912    (clobber (match_scratch:SI 3 "=1"))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "TARGET_64BIT
7915    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7916   "<sgnprefix>mul{l}\t%2"
7917   [(set_attr "type" "imul")
7918    (set_attr "length_immediate" "0")
7919    (set (attr "athlon_decode")
7920      (if_then_else (eq_attr "cpu" "athlon")
7921         (const_string "vector")
7922         (const_string "double")))
7923    (set_attr "amdfam10_decode" "double")
7924    (set_attr "mode" "SI")])
7925
7926 ;; The patterns that match these are at the end of this file.
7927
7928 (define_expand "mulxf3"
7929   [(set (match_operand:XF 0 "register_operand" "")
7930         (mult:XF (match_operand:XF 1 "register_operand" "")
7931                  (match_operand:XF 2 "register_operand" "")))]
7932   "TARGET_80387"
7933   "")
7934
7935 (define_expand "mul<mode>3"
7936   [(set (match_operand:MODEF 0 "register_operand" "")
7937         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7938                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7939   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7940     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7941   "")
7942 \f
7943 ;; Divide instructions
7944
7945 (define_insn "<u>divqi3"
7946   [(set (match_operand:QI 0 "register_operand" "=a")
7947         (any_div:QI
7948           (match_operand:HI 1 "register_operand" "0")
7949           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7950    (clobber (reg:CC FLAGS_REG))]
7951   "TARGET_QIMODE_MATH"
7952   "<sgnprefix>div{b}\t%2"
7953   [(set_attr "type" "idiv")
7954    (set_attr "mode" "QI")])
7955
7956 ;; The patterns that match these are at the end of this file.
7957
7958 (define_expand "divxf3"
7959   [(set (match_operand:XF 0 "register_operand" "")
7960         (div:XF (match_operand:XF 1 "register_operand" "")
7961                 (match_operand:XF 2 "register_operand" "")))]
7962   "TARGET_80387"
7963   "")
7964
7965 (define_expand "divdf3"
7966   [(set (match_operand:DF 0 "register_operand" "")
7967         (div:DF (match_operand:DF 1 "register_operand" "")
7968                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7969    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7970     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7971    "")
7972
7973 (define_expand "divsf3"
7974   [(set (match_operand:SF 0 "register_operand" "")
7975         (div:SF (match_operand:SF 1 "register_operand" "")
7976                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7977   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7978     || TARGET_SSE_MATH"
7979 {
7980   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7981       && flag_finite_math_only && !flag_trapping_math
7982       && flag_unsafe_math_optimizations)
7983     {
7984       ix86_emit_swdivsf (operands[0], operands[1],
7985                          operands[2], SFmode);
7986       DONE;
7987     }
7988 })
7989 \f
7990 ;; Divmod instructions.
7991
7992 (define_expand "divmod<mode>4"
7993   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7994                    (div:SWIM248
7995                      (match_operand:SWIM248 1 "register_operand" "")
7996                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7997               (set (match_operand:SWIM248 3 "register_operand" "")
7998                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7999               (clobber (reg:CC FLAGS_REG))])]
8000   ""
8001   "")
8002
8003 (define_insn_and_split "*divmod<mode>4"
8004   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8005         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8006                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8007    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8008         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8009    (clobber (reg:CC FLAGS_REG))]
8010   ""
8011   "#"
8012   "&& reload_completed"
8013   [(parallel [(set (match_dup 1)
8014                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8015               (clobber (reg:CC FLAGS_REG))])
8016    (parallel [(set (match_dup 0)
8017                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8018               (set (match_dup 1)
8019                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8020               (use (match_dup 1))
8021               (clobber (reg:CC FLAGS_REG))])]
8022 {
8023   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8024
8025   if (<MODE>mode != HImode
8026       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8027     operands[4] = operands[2];
8028   else
8029     {
8030       /* Avoid use of cltd in favor of a mov+shift.  */
8031       emit_move_insn (operands[1], operands[2]);
8032       operands[4] = operands[1];
8033     }
8034 }
8035   [(set_attr "type" "multi")
8036    (set_attr "mode" "<MODE>")])
8037
8038 (define_insn "*divmod<mode>4_noext"
8039   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8040         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8041                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8042    (set (match_operand:SWIM248 1 "register_operand" "=d")
8043         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8044    (use (match_operand:SWIM248 4 "register_operand" "1"))
8045    (clobber (reg:CC FLAGS_REG))]
8046   ""
8047   "idiv{<imodesuffix>}\t%3"
8048   [(set_attr "type" "idiv")
8049    (set_attr "mode" "<MODE>")])
8050
8051 (define_expand "udivmod<mode>4"
8052   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8053                    (udiv:SWIM248
8054                      (match_operand:SWIM248 1 "register_operand" "")
8055                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8056               (set (match_operand:SWIM248 3 "register_operand" "")
8057                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8058               (clobber (reg:CC FLAGS_REG))])]
8059   ""
8060   "")
8061
8062 (define_insn_and_split "*udivmod<mode>4"
8063   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8064         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8065                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8066    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8067         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8068    (clobber (reg:CC FLAGS_REG))]
8069   ""
8070   "#"
8071   "&& reload_completed"
8072   [(set (match_dup 1) (const_int 0))
8073    (parallel [(set (match_dup 0)
8074                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8075               (set (match_dup 1)
8076                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8077               (use (match_dup 1))
8078               (clobber (reg:CC FLAGS_REG))])]
8079   ""
8080   [(set_attr "type" "multi")
8081    (set_attr "mode" "<MODE>")])
8082
8083 (define_insn "*udivmod<mode>4_noext"
8084   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8085         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8086                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8087    (set (match_operand:SWIM248 1 "register_operand" "=d")
8088         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8089    (use (match_operand:SWIM248 4 "register_operand" "1"))
8090    (clobber (reg:CC FLAGS_REG))]
8091   ""
8092   "div{<imodesuffix>}\t%3"
8093   [(set_attr "type" "idiv")
8094    (set_attr "mode" "<MODE>")])
8095
8096 ;; We cannot use div/idiv for double division, because it causes
8097 ;; "division by zero" on the overflow and that's not what we expect
8098 ;; from truncate.  Because true (non truncating) double division is
8099 ;; never generated, we can't create this insn anyway.
8100 ;
8101 ;(define_insn ""
8102 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8103 ;       (truncate:SI
8104 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8105 ;                  (zero_extend:DI
8106 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8107 ;   (set (match_operand:SI 3 "register_operand" "=d")
8108 ;       (truncate:SI
8109 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8110 ;   (clobber (reg:CC FLAGS_REG))]
8111 ;  ""
8112 ;  "div{l}\t{%2, %0|%0, %2}"
8113 ;  [(set_attr "type" "idiv")])
8114 \f
8115 ;;- Logical AND instructions
8116
8117 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8118 ;; Note that this excludes ah.
8119
8120 (define_expand "testsi_ccno_1"
8121   [(set (reg:CCNO FLAGS_REG)
8122         (compare:CCNO
8123           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8124                   (match_operand:SI 1 "nonmemory_operand" ""))
8125           (const_int 0)))]
8126   ""
8127   "")
8128
8129 (define_expand "testqi_ccz_1"
8130   [(set (reg:CCZ FLAGS_REG)
8131         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8132                              (match_operand:QI 1 "nonmemory_operand" ""))
8133                  (const_int 0)))]
8134   ""
8135   "")
8136
8137 (define_insn "*testdi_1"
8138   [(set (reg FLAGS_REG)
8139         (compare
8140          (and:DI
8141           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8142           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8143          (const_int 0)))]
8144   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8145    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8146   "@
8147    test{l}\t{%k1, %k0|%k0, %k1}
8148    test{l}\t{%k1, %k0|%k0, %k1}
8149    test{q}\t{%1, %0|%0, %1}
8150    test{q}\t{%1, %0|%0, %1}
8151    test{q}\t{%1, %0|%0, %1}"
8152   [(set_attr "type" "test")
8153    (set_attr "modrm" "0,1,0,1,1")
8154    (set_attr "mode" "SI,SI,DI,DI,DI")])
8155
8156 (define_insn "*testqi_1_maybe_si"
8157   [(set (reg FLAGS_REG)
8158         (compare
8159           (and:QI
8160             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8161             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8162           (const_int 0)))]
8163    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8164     && ix86_match_ccmode (insn,
8165                          CONST_INT_P (operands[1])
8166                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8167 {
8168   if (which_alternative == 3)
8169     {
8170       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8171         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8172       return "test{l}\t{%1, %k0|%k0, %1}";
8173     }
8174   return "test{b}\t{%1, %0|%0, %1}";
8175 }
8176   [(set_attr "type" "test")
8177    (set_attr "modrm" "0,1,1,1")
8178    (set_attr "mode" "QI,QI,QI,SI")
8179    (set_attr "pent_pair" "uv,np,uv,np")])
8180
8181 (define_insn "*test<mode>_1"
8182   [(set (reg FLAGS_REG)
8183         (compare
8184          (and:SWI124
8185           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8186           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8187          (const_int 0)))]
8188   "ix86_match_ccmode (insn, CCNOmode)
8189    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8190   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8191   [(set_attr "type" "test")
8192    (set_attr "modrm" "0,1,1")
8193    (set_attr "mode" "<MODE>")
8194    (set_attr "pent_pair" "uv,np,uv")])
8195
8196 (define_expand "testqi_ext_ccno_0"
8197   [(set (reg:CCNO FLAGS_REG)
8198         (compare:CCNO
8199           (and:SI
8200             (zero_extract:SI
8201               (match_operand 0 "ext_register_operand" "")
8202               (const_int 8)
8203               (const_int 8))
8204             (match_operand 1 "const_int_operand" ""))
8205           (const_int 0)))]
8206   ""
8207   "")
8208
8209 (define_insn "*testqi_ext_0"
8210   [(set (reg FLAGS_REG)
8211         (compare
8212           (and:SI
8213             (zero_extract:SI
8214               (match_operand 0 "ext_register_operand" "Q")
8215               (const_int 8)
8216               (const_int 8))
8217             (match_operand 1 "const_int_operand" "n"))
8218           (const_int 0)))]
8219   "ix86_match_ccmode (insn, CCNOmode)"
8220   "test{b}\t{%1, %h0|%h0, %1}"
8221   [(set_attr "type" "test")
8222    (set_attr "mode" "QI")
8223    (set_attr "length_immediate" "1")
8224    (set_attr "modrm" "1")
8225    (set_attr "pent_pair" "np")])
8226
8227 (define_insn "*testqi_ext_1_rex64"
8228   [(set (reg FLAGS_REG)
8229         (compare
8230           (and:SI
8231             (zero_extract:SI
8232               (match_operand 0 "ext_register_operand" "Q")
8233               (const_int 8)
8234               (const_int 8))
8235             (zero_extend:SI
8236               (match_operand:QI 1 "register_operand" "Q")))
8237           (const_int 0)))]
8238   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8239   "test{b}\t{%1, %h0|%h0, %1}"
8240   [(set_attr "type" "test")
8241    (set_attr "mode" "QI")])
8242
8243 (define_insn "*testqi_ext_1"
8244   [(set (reg FLAGS_REG)
8245         (compare
8246           (and:SI
8247             (zero_extract:SI
8248               (match_operand 0 "ext_register_operand" "Q")
8249               (const_int 8)
8250               (const_int 8))
8251             (zero_extend:SI
8252               (match_operand:QI 1 "general_operand" "Qm")))
8253           (const_int 0)))]
8254   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8255   "test{b}\t{%1, %h0|%h0, %1}"
8256   [(set_attr "type" "test")
8257    (set_attr "mode" "QI")])
8258
8259 (define_insn "*testqi_ext_2"
8260   [(set (reg FLAGS_REG)
8261         (compare
8262           (and:SI
8263             (zero_extract:SI
8264               (match_operand 0 "ext_register_operand" "Q")
8265               (const_int 8)
8266               (const_int 8))
8267             (zero_extract:SI
8268               (match_operand 1 "ext_register_operand" "Q")
8269               (const_int 8)
8270               (const_int 8)))
8271           (const_int 0)))]
8272   "ix86_match_ccmode (insn, CCNOmode)"
8273   "test{b}\t{%h1, %h0|%h0, %h1}"
8274   [(set_attr "type" "test")
8275    (set_attr "mode" "QI")])
8276
8277 (define_insn "*testqi_ext_3_rex64"
8278   [(set (reg FLAGS_REG)
8279         (compare (zero_extract:DI
8280                    (match_operand 0 "nonimmediate_operand" "rm")
8281                    (match_operand:DI 1 "const_int_operand" "")
8282                    (match_operand:DI 2 "const_int_operand" ""))
8283                  (const_int 0)))]
8284   "TARGET_64BIT
8285    && ix86_match_ccmode (insn, CCNOmode)
8286    && INTVAL (operands[1]) > 0
8287    && INTVAL (operands[2]) >= 0
8288    /* Ensure that resulting mask is zero or sign extended operand.  */
8289    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8290        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8291            && INTVAL (operands[1]) > 32))
8292    && (GET_MODE (operands[0]) == SImode
8293        || GET_MODE (operands[0]) == DImode
8294        || GET_MODE (operands[0]) == HImode
8295        || GET_MODE (operands[0]) == QImode)"
8296   "#")
8297
8298 ;; Combine likes to form bit extractions for some tests.  Humor it.
8299 (define_insn "*testqi_ext_3"
8300   [(set (reg FLAGS_REG)
8301         (compare (zero_extract:SI
8302                    (match_operand 0 "nonimmediate_operand" "rm")
8303                    (match_operand:SI 1 "const_int_operand" "")
8304                    (match_operand:SI 2 "const_int_operand" ""))
8305                  (const_int 0)))]
8306   "ix86_match_ccmode (insn, CCNOmode)
8307    && INTVAL (operands[1]) > 0
8308    && INTVAL (operands[2]) >= 0
8309    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8310    && (GET_MODE (operands[0]) == SImode
8311        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8312        || GET_MODE (operands[0]) == HImode
8313        || GET_MODE (operands[0]) == QImode)"
8314   "#")
8315
8316 (define_split
8317   [(set (match_operand 0 "flags_reg_operand" "")
8318         (match_operator 1 "compare_operator"
8319           [(zero_extract
8320              (match_operand 2 "nonimmediate_operand" "")
8321              (match_operand 3 "const_int_operand" "")
8322              (match_operand 4 "const_int_operand" ""))
8323            (const_int 0)]))]
8324   "ix86_match_ccmode (insn, CCNOmode)"
8325   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8326 {
8327   rtx val = operands[2];
8328   HOST_WIDE_INT len = INTVAL (operands[3]);
8329   HOST_WIDE_INT pos = INTVAL (operands[4]);
8330   HOST_WIDE_INT mask;
8331   enum machine_mode mode, submode;
8332
8333   mode = GET_MODE (val);
8334   if (MEM_P (val))
8335     {
8336       /* ??? Combine likes to put non-volatile mem extractions in QImode
8337          no matter the size of the test.  So find a mode that works.  */
8338       if (! MEM_VOLATILE_P (val))
8339         {
8340           mode = smallest_mode_for_size (pos + len, MODE_INT);
8341           val = adjust_address (val, mode, 0);
8342         }
8343     }
8344   else if (GET_CODE (val) == SUBREG
8345            && (submode = GET_MODE (SUBREG_REG (val)),
8346                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8347            && pos + len <= GET_MODE_BITSIZE (submode)
8348            && GET_MODE_CLASS (submode) == MODE_INT)
8349     {
8350       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8351       mode = submode;
8352       val = SUBREG_REG (val);
8353     }
8354   else if (mode == HImode && pos + len <= 8)
8355     {
8356       /* Small HImode tests can be converted to QImode.  */
8357       mode = QImode;
8358       val = gen_lowpart (QImode, val);
8359     }
8360
8361   if (len == HOST_BITS_PER_WIDE_INT)
8362     mask = -1;
8363   else
8364     mask = ((HOST_WIDE_INT)1 << len) - 1;
8365   mask <<= pos;
8366
8367   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8368 })
8369
8370 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8371 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8372 ;; this is relatively important trick.
8373 ;; Do the conversion only post-reload to avoid limiting of the register class
8374 ;; to QI regs.
8375 (define_split
8376   [(set (match_operand 0 "flags_reg_operand" "")
8377         (match_operator 1 "compare_operator"
8378           [(and (match_operand 2 "register_operand" "")
8379                 (match_operand 3 "const_int_operand" ""))
8380            (const_int 0)]))]
8381    "reload_completed
8382     && QI_REG_P (operands[2])
8383     && GET_MODE (operands[2]) != QImode
8384     && ((ix86_match_ccmode (insn, CCZmode)
8385          && !(INTVAL (operands[3]) & ~(255 << 8)))
8386         || (ix86_match_ccmode (insn, CCNOmode)
8387             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8388   [(set (match_dup 0)
8389         (match_op_dup 1
8390           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8391                    (match_dup 3))
8392            (const_int 0)]))]
8393   "operands[2] = gen_lowpart (SImode, operands[2]);
8394    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8395
8396 (define_split
8397   [(set (match_operand 0 "flags_reg_operand" "")
8398         (match_operator 1 "compare_operator"
8399           [(and (match_operand 2 "nonimmediate_operand" "")
8400                 (match_operand 3 "const_int_operand" ""))
8401            (const_int 0)]))]
8402    "reload_completed
8403     && GET_MODE (operands[2]) != QImode
8404     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8405     && ((ix86_match_ccmode (insn, CCZmode)
8406          && !(INTVAL (operands[3]) & ~255))
8407         || (ix86_match_ccmode (insn, CCNOmode)
8408             && !(INTVAL (operands[3]) & ~127)))"
8409   [(set (match_dup 0)
8410         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8411                          (const_int 0)]))]
8412   "operands[2] = gen_lowpart (QImode, operands[2]);
8413    operands[3] = gen_lowpart (QImode, operands[3]);")
8414
8415 ;; %%% This used to optimize known byte-wide and operations to memory,
8416 ;; and sometimes to QImode registers.  If this is considered useful,
8417 ;; it should be done with splitters.
8418
8419 (define_expand "and<mode>3"
8420   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8421         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8422                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8423   ""
8424   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8425
8426 (define_insn "*anddi_1"
8427   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8428         (and:DI
8429          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8430          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8433 {
8434   switch (get_attr_type (insn))
8435     {
8436     case TYPE_IMOVX:
8437       {
8438         enum machine_mode mode;
8439
8440         gcc_assert (CONST_INT_P (operands[2]));
8441         if (INTVAL (operands[2]) == 0xff)
8442           mode = QImode;
8443         else
8444           {
8445             gcc_assert (INTVAL (operands[2]) == 0xffff);
8446             mode = HImode;
8447           }
8448
8449         operands[1] = gen_lowpart (mode, operands[1]);
8450         if (mode == QImode)
8451           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8452         else
8453           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8454       }
8455
8456     default:
8457       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8458       if (get_attr_mode (insn) == MODE_SI)
8459         return "and{l}\t{%k2, %k0|%k0, %k2}";
8460       else
8461         return "and{q}\t{%2, %0|%0, %2}";
8462     }
8463 }
8464   [(set_attr "type" "alu,alu,alu,imovx")
8465    (set_attr "length_immediate" "*,*,*,0")
8466    (set (attr "prefix_rex")
8467      (if_then_else
8468        (and (eq_attr "type" "imovx")
8469             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8470                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8471        (const_string "1")
8472        (const_string "*")))
8473    (set_attr "mode" "SI,DI,DI,SI")])
8474
8475 (define_insn "*andsi_1"
8476   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8477         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8478                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8479    (clobber (reg:CC FLAGS_REG))]
8480   "ix86_binary_operator_ok (AND, SImode, operands)"
8481 {
8482   switch (get_attr_type (insn))
8483     {
8484     case TYPE_IMOVX:
8485       {
8486         enum machine_mode mode;
8487
8488         gcc_assert (CONST_INT_P (operands[2]));
8489         if (INTVAL (operands[2]) == 0xff)
8490           mode = QImode;
8491         else
8492           {
8493             gcc_assert (INTVAL (operands[2]) == 0xffff);
8494             mode = HImode;
8495           }
8496
8497         operands[1] = gen_lowpart (mode, operands[1]);
8498         if (mode == QImode)
8499           return "movz{bl|x}\t{%1, %0|%0, %1}";
8500         else
8501           return "movz{wl|x}\t{%1, %0|%0, %1}";
8502       }
8503
8504     default:
8505       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8506       return "and{l}\t{%2, %0|%0, %2}";
8507     }
8508 }
8509   [(set_attr "type" "alu,alu,imovx")
8510    (set (attr "prefix_rex")
8511      (if_then_else
8512        (and (eq_attr "type" "imovx")
8513             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8514                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8515        (const_string "1")
8516        (const_string "*")))
8517    (set_attr "length_immediate" "*,*,0")
8518    (set_attr "mode" "SI")])
8519
8520 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8521 (define_insn "*andsi_1_zext"
8522   [(set (match_operand:DI 0 "register_operand" "=r")
8523         (zero_extend:DI
8524           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8525                   (match_operand:SI 2 "general_operand" "g"))))
8526    (clobber (reg:CC FLAGS_REG))]
8527   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8528   "and{l}\t{%2, %k0|%k0, %2}"
8529   [(set_attr "type" "alu")
8530    (set_attr "mode" "SI")])
8531
8532 (define_insn "*andhi_1"
8533   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8534         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8535                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "ix86_binary_operator_ok (AND, HImode, operands)"
8538 {
8539   switch (get_attr_type (insn))
8540     {
8541     case TYPE_IMOVX:
8542       gcc_assert (CONST_INT_P (operands[2]));
8543       gcc_assert (INTVAL (operands[2]) == 0xff);
8544       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8545
8546     default:
8547       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8548
8549       return "and{w}\t{%2, %0|%0, %2}";
8550     }
8551 }
8552   [(set_attr "type" "alu,alu,imovx")
8553    (set_attr "length_immediate" "*,*,0")
8554    (set (attr "prefix_rex")
8555      (if_then_else
8556        (and (eq_attr "type" "imovx")
8557             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8558        (const_string "1")
8559        (const_string "*")))
8560    (set_attr "mode" "HI,HI,SI")])
8561
8562 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8563 (define_insn "*andqi_1"
8564   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8565         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8566                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   "ix86_binary_operator_ok (AND, QImode, operands)"
8569   "@
8570    and{b}\t{%2, %0|%0, %2}
8571    and{b}\t{%2, %0|%0, %2}
8572    and{l}\t{%k2, %k0|%k0, %k2}"
8573   [(set_attr "type" "alu")
8574    (set_attr "mode" "QI,QI,SI")])
8575
8576 (define_insn "*andqi_1_slp"
8577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8578         (and:QI (match_dup 0)
8579                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8582    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8583   "and{b}\t{%1, %0|%0, %1}"
8584   [(set_attr "type" "alu1")
8585    (set_attr "mode" "QI")])
8586
8587 (define_split
8588   [(set (match_operand 0 "register_operand" "")
8589         (and (match_dup 0)
8590              (const_int -65536)))
8591    (clobber (reg:CC FLAGS_REG))]
8592   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8593     || optimize_function_for_size_p (cfun)"
8594   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8595   "operands[1] = gen_lowpart (HImode, operands[0]);")
8596
8597 (define_split
8598   [(set (match_operand 0 "ext_register_operand" "")
8599         (and (match_dup 0)
8600              (const_int -256)))
8601    (clobber (reg:CC FLAGS_REG))]
8602   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8603    && reload_completed"
8604   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8605   "operands[1] = gen_lowpart (QImode, operands[0]);")
8606
8607 (define_split
8608   [(set (match_operand 0 "ext_register_operand" "")
8609         (and (match_dup 0)
8610              (const_int -65281)))
8611    (clobber (reg:CC FLAGS_REG))]
8612   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8613    && reload_completed"
8614   [(parallel [(set (zero_extract:SI (match_dup 0)
8615                                     (const_int 8)
8616                                     (const_int 8))
8617                    (xor:SI
8618                      (zero_extract:SI (match_dup 0)
8619                                       (const_int 8)
8620                                       (const_int 8))
8621                      (zero_extract:SI (match_dup 0)
8622                                       (const_int 8)
8623                                       (const_int 8))))
8624               (clobber (reg:CC FLAGS_REG))])]
8625   "operands[0] = gen_lowpart (SImode, operands[0]);")
8626
8627 (define_insn "*anddi_2"
8628   [(set (reg FLAGS_REG)
8629         (compare
8630          (and:DI
8631           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8632           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8633          (const_int 0)))
8634    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8635         (and:DI (match_dup 1) (match_dup 2)))]
8636   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8637    && ix86_binary_operator_ok (AND, DImode, operands)"
8638   "@
8639    and{l}\t{%k2, %k0|%k0, %k2}
8640    and{q}\t{%2, %0|%0, %2}
8641    and{q}\t{%2, %0|%0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "SI,DI,DI")])
8644
8645 (define_insn "*andqi_2_maybe_si"
8646   [(set (reg FLAGS_REG)
8647         (compare (and:QI
8648                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8649                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8650                  (const_int 0)))
8651    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8652         (and:QI (match_dup 1) (match_dup 2)))]
8653   "ix86_binary_operator_ok (AND, QImode, operands)
8654    && ix86_match_ccmode (insn,
8655                          CONST_INT_P (operands[2])
8656                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8657 {
8658   if (which_alternative == 2)
8659     {
8660       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8661         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8662       return "and{l}\t{%2, %k0|%k0, %2}";
8663     }
8664   return "and{b}\t{%2, %0|%0, %2}";
8665 }
8666   [(set_attr "type" "alu")
8667    (set_attr "mode" "QI,QI,SI")])
8668
8669 (define_insn "*and<mode>_2"
8670   [(set (reg FLAGS_REG)
8671         (compare (and:SWI124
8672                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8673                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8674                  (const_int 0)))
8675    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8676         (and:SWI124 (match_dup 1) (match_dup 2)))]
8677   "ix86_match_ccmode (insn, CCNOmode)
8678    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8679   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8680   [(set_attr "type" "alu")
8681    (set_attr "mode" "<MODE>")])
8682
8683 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8684 (define_insn "*andsi_2_zext"
8685   [(set (reg FLAGS_REG)
8686         (compare (and:SI
8687                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8688                   (match_operand:SI 2 "general_operand" "g"))
8689                  (const_int 0)))
8690    (set (match_operand:DI 0 "register_operand" "=r")
8691         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8692   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8693    && ix86_binary_operator_ok (AND, SImode, operands)"
8694   "and{l}\t{%2, %k0|%k0, %2}"
8695   [(set_attr "type" "alu")
8696    (set_attr "mode" "SI")])
8697
8698 (define_insn "*andqi_2_slp"
8699   [(set (reg FLAGS_REG)
8700         (compare (and:QI
8701                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8702                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8703                  (const_int 0)))
8704    (set (strict_low_part (match_dup 0))
8705         (and:QI (match_dup 0) (match_dup 1)))]
8706   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8707    && ix86_match_ccmode (insn, CCNOmode)
8708    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8709   "and{b}\t{%1, %0|%0, %1}"
8710   [(set_attr "type" "alu1")
8711    (set_attr "mode" "QI")])
8712
8713 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8714 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8715 ;; for a QImode operand, which of course failed.
8716 (define_insn "andqi_ext_0"
8717   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8718                          (const_int 8)
8719                          (const_int 8))
8720         (and:SI
8721           (zero_extract:SI
8722             (match_operand 1 "ext_register_operand" "0")
8723             (const_int 8)
8724             (const_int 8))
8725           (match_operand 2 "const_int_operand" "n")))
8726    (clobber (reg:CC FLAGS_REG))]
8727   ""
8728   "and{b}\t{%2, %h0|%h0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "length_immediate" "1")
8731    (set_attr "modrm" "1")
8732    (set_attr "mode" "QI")])
8733
8734 ;; Generated by peephole translating test to and.  This shows up
8735 ;; often in fp comparisons.
8736 (define_insn "*andqi_ext_0_cc"
8737   [(set (reg FLAGS_REG)
8738         (compare
8739           (and:SI
8740             (zero_extract:SI
8741               (match_operand 1 "ext_register_operand" "0")
8742               (const_int 8)
8743               (const_int 8))
8744             (match_operand 2 "const_int_operand" "n"))
8745           (const_int 0)))
8746    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8747                          (const_int 8)
8748                          (const_int 8))
8749         (and:SI
8750           (zero_extract:SI
8751             (match_dup 1)
8752             (const_int 8)
8753             (const_int 8))
8754           (match_dup 2)))]
8755   "ix86_match_ccmode (insn, CCNOmode)"
8756   "and{b}\t{%2, %h0|%h0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "length_immediate" "1")
8759    (set_attr "modrm" "1")
8760    (set_attr "mode" "QI")])
8761
8762 (define_insn "*andqi_ext_1_rex64"
8763   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8764                          (const_int 8)
8765                          (const_int 8))
8766         (and:SI
8767           (zero_extract:SI
8768             (match_operand 1 "ext_register_operand" "0")
8769             (const_int 8)
8770             (const_int 8))
8771           (zero_extend:SI
8772             (match_operand 2 "ext_register_operand" "Q"))))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "TARGET_64BIT"
8775   "and{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "length_immediate" "0")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*andqi_ext_1"
8781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782                          (const_int 8)
8783                          (const_int 8))
8784         (and:SI
8785           (zero_extract:SI
8786             (match_operand 1 "ext_register_operand" "0")
8787             (const_int 8)
8788             (const_int 8))
8789           (zero_extend:SI
8790             (match_operand:QI 2 "general_operand" "Qm"))))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "!TARGET_64BIT"
8793   "and{b}\t{%2, %h0|%h0, %2}"
8794   [(set_attr "type" "alu")
8795    (set_attr "length_immediate" "0")
8796    (set_attr "mode" "QI")])
8797
8798 (define_insn "*andqi_ext_2"
8799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8800                          (const_int 8)
8801                          (const_int 8))
8802         (and:SI
8803           (zero_extract:SI
8804             (match_operand 1 "ext_register_operand" "%0")
8805             (const_int 8)
8806             (const_int 8))
8807           (zero_extract:SI
8808             (match_operand 2 "ext_register_operand" "Q")
8809             (const_int 8)
8810             (const_int 8))))
8811    (clobber (reg:CC FLAGS_REG))]
8812   ""
8813   "and{b}\t{%h2, %h0|%h0, %h2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "length_immediate" "0")
8816    (set_attr "mode" "QI")])
8817
8818 ;; Convert wide AND instructions with immediate operand to shorter QImode
8819 ;; equivalents when possible.
8820 ;; Don't do the splitting with memory operands, since it introduces risk
8821 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8822 ;; for size, but that can (should?) be handled by generic code instead.
8823 (define_split
8824   [(set (match_operand 0 "register_operand" "")
8825         (and (match_operand 1 "register_operand" "")
8826              (match_operand 2 "const_int_operand" "")))
8827    (clobber (reg:CC FLAGS_REG))]
8828    "reload_completed
8829     && QI_REG_P (operands[0])
8830     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8831     && !(~INTVAL (operands[2]) & ~(255 << 8))
8832     && GET_MODE (operands[0]) != QImode"
8833   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8834                    (and:SI (zero_extract:SI (match_dup 1)
8835                                             (const_int 8) (const_int 8))
8836                            (match_dup 2)))
8837               (clobber (reg:CC FLAGS_REG))])]
8838   "operands[0] = gen_lowpart (SImode, operands[0]);
8839    operands[1] = gen_lowpart (SImode, operands[1]);
8840    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8841
8842 ;; Since AND can be encoded with sign extended immediate, this is only
8843 ;; profitable when 7th bit is not set.
8844 (define_split
8845   [(set (match_operand 0 "register_operand" "")
8846         (and (match_operand 1 "general_operand" "")
8847              (match_operand 2 "const_int_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849    "reload_completed
8850     && ANY_QI_REG_P (operands[0])
8851     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8852     && !(~INTVAL (operands[2]) & ~255)
8853     && !(INTVAL (operands[2]) & 128)
8854     && GET_MODE (operands[0]) != QImode"
8855   [(parallel [(set (strict_low_part (match_dup 0))
8856                    (and:QI (match_dup 1)
8857                            (match_dup 2)))
8858               (clobber (reg:CC FLAGS_REG))])]
8859   "operands[0] = gen_lowpart (QImode, operands[0]);
8860    operands[1] = gen_lowpart (QImode, operands[1]);
8861    operands[2] = gen_lowpart (QImode, operands[2]);")
8862 \f
8863 ;; Logical inclusive and exclusive OR instructions
8864
8865 ;; %%% This used to optimize known byte-wide and operations to memory.
8866 ;; If this is considered useful, it should be done with splitters.
8867
8868 (define_expand "<code><mode>3"
8869   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8870         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8871                      (match_operand:SWIM 2 "<general_operand>" "")))]
8872   ""
8873   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8874
8875 (define_insn "*<code><mode>_1"
8876   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8877         (any_or:SWI248
8878          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8879          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8880    (clobber (reg:CC FLAGS_REG))]
8881   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8882   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "<MODE>")])
8885
8886 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8887 (define_insn "*<code>qi_1"
8888   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8889         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8890                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8893   "@
8894    <logicprefix>{b}\t{%2, %0|%0, %2}
8895    <logicprefix>{b}\t{%2, %0|%0, %2}
8896    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "QI,QI,SI")])
8899
8900 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8901 (define_insn "*<code>si_1_zext"
8902   [(set (match_operand:DI 0 "register_operand" "=r")
8903         (zero_extend:DI
8904          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8905                     (match_operand:SI 2 "general_operand" "g"))))
8906    (clobber (reg:CC FLAGS_REG))]
8907   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8908   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8909   [(set_attr "type" "alu")
8910    (set_attr "mode" "SI")])
8911
8912 (define_insn "*<code>si_1_zext_imm"
8913   [(set (match_operand:DI 0 "register_operand" "=r")
8914         (any_or:DI
8915          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8916          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8917    (clobber (reg:CC FLAGS_REG))]
8918   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8919   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8920   [(set_attr "type" "alu")
8921    (set_attr "mode" "SI")])
8922
8923 (define_insn "*<code>qi_1_slp"
8924   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8925         (any_or:QI (match_dup 0)
8926                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8927    (clobber (reg:CC FLAGS_REG))]
8928   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8929    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8930   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8931   [(set_attr "type" "alu1")
8932    (set_attr "mode" "QI")])
8933
8934 (define_insn "*<code><mode>_2"
8935   [(set (reg FLAGS_REG)
8936         (compare (any_or:SWI
8937                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8938                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8939                  (const_int 0)))
8940    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8941         (any_or:SWI (match_dup 1) (match_dup 2)))]
8942   "ix86_match_ccmode (insn, CCNOmode)
8943    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8944   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8945   [(set_attr "type" "alu")
8946    (set_attr "mode" "<MODE>")])
8947
8948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8949 ;; ??? Special case for immediate operand is missing - it is tricky.
8950 (define_insn "*<code>si_2_zext"
8951   [(set (reg FLAGS_REG)
8952         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8953                             (match_operand:SI 2 "general_operand" "g"))
8954                  (const_int 0)))
8955    (set (match_operand:DI 0 "register_operand" "=r")
8956         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8957   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8958    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8959   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8960   [(set_attr "type" "alu")
8961    (set_attr "mode" "SI")])
8962
8963 (define_insn "*<code>si_2_zext_imm"
8964   [(set (reg FLAGS_REG)
8965         (compare (any_or:SI
8966                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8967                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8968                  (const_int 0)))
8969    (set (match_operand:DI 0 "register_operand" "=r")
8970         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8971   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8972    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8973   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8974   [(set_attr "type" "alu")
8975    (set_attr "mode" "SI")])
8976
8977 (define_insn "*<code>qi_2_slp"
8978   [(set (reg FLAGS_REG)
8979         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8980                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8981                  (const_int 0)))
8982    (set (strict_low_part (match_dup 0))
8983         (any_or:QI (match_dup 0) (match_dup 1)))]
8984   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8985    && ix86_match_ccmode (insn, CCNOmode)
8986    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8987   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8988   [(set_attr "type" "alu1")
8989    (set_attr "mode" "QI")])
8990
8991 (define_insn "*<code><mode>_3"
8992   [(set (reg FLAGS_REG)
8993         (compare (any_or:SWI
8994                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8995                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8996                  (const_int 0)))
8997    (clobber (match_scratch:SWI 0 "=<r>"))]
8998   "ix86_match_ccmode (insn, CCNOmode)
8999    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9000   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
9001   [(set_attr "type" "alu")
9002    (set_attr "mode" "<MODE>")])
9003
9004 (define_insn "*<code>qi_ext_0"
9005   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9006                          (const_int 8)
9007                          (const_int 8))
9008         (any_or:SI
9009           (zero_extract:SI
9010             (match_operand 1 "ext_register_operand" "0")
9011             (const_int 8)
9012             (const_int 8))
9013           (match_operand 2 "const_int_operand" "n")))
9014    (clobber (reg:CC FLAGS_REG))]
9015   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9016   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9017   [(set_attr "type" "alu")
9018    (set_attr "length_immediate" "1")
9019    (set_attr "modrm" "1")
9020    (set_attr "mode" "QI")])
9021
9022 (define_insn "*<code>qi_ext_1_rex64"
9023   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9024                          (const_int 8)
9025                          (const_int 8))
9026         (any_or:SI
9027           (zero_extract:SI
9028             (match_operand 1 "ext_register_operand" "0")
9029             (const_int 8)
9030             (const_int 8))
9031           (zero_extend:SI
9032             (match_operand 2 "ext_register_operand" "Q"))))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "TARGET_64BIT
9035    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9036   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "length_immediate" "0")
9039    (set_attr "mode" "QI")])
9040
9041 (define_insn "*<code>qi_ext_1"
9042   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9043                          (const_int 8)
9044                          (const_int 8))
9045         (any_or:SI
9046           (zero_extract:SI
9047             (match_operand 1 "ext_register_operand" "0")
9048             (const_int 8)
9049             (const_int 8))
9050           (zero_extend:SI
9051             (match_operand:QI 2 "general_operand" "Qm"))))
9052    (clobber (reg:CC FLAGS_REG))]
9053   "!TARGET_64BIT
9054    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9055   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "length_immediate" "0")
9058    (set_attr "mode" "QI")])
9059
9060 (define_insn "*<code>qi_ext_2"
9061   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9062                          (const_int 8)
9063                          (const_int 8))
9064         (any_or:SI
9065           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9066                            (const_int 8)
9067                            (const_int 8))
9068           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9069                            (const_int 8)
9070                            (const_int 8))))
9071    (clobber (reg:CC FLAGS_REG))]
9072   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9073   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
9074   [(set_attr "type" "alu")
9075    (set_attr "length_immediate" "0")
9076    (set_attr "mode" "QI")])
9077
9078 (define_split
9079   [(set (match_operand 0 "register_operand" "")
9080         (any_or (match_operand 1 "register_operand" "")
9081                 (match_operand 2 "const_int_operand" "")))
9082    (clobber (reg:CC FLAGS_REG))]
9083    "reload_completed
9084     && QI_REG_P (operands[0])
9085     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9086     && !(INTVAL (operands[2]) & ~(255 << 8))
9087     && GET_MODE (operands[0]) != QImode"
9088   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9089                    (any_or:SI (zero_extract:SI (match_dup 1)
9090                                                (const_int 8) (const_int 8))
9091                               (match_dup 2)))
9092               (clobber (reg:CC FLAGS_REG))])]
9093   "operands[0] = gen_lowpart (SImode, operands[0]);
9094    operands[1] = gen_lowpart (SImode, operands[1]);
9095    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9096
9097 ;; Since OR can be encoded with sign extended immediate, this is only
9098 ;; profitable when 7th bit is set.
9099 (define_split
9100   [(set (match_operand 0 "register_operand" "")
9101         (any_or (match_operand 1 "general_operand" "")
9102                 (match_operand 2 "const_int_operand" "")))
9103    (clobber (reg:CC FLAGS_REG))]
9104    "reload_completed
9105     && ANY_QI_REG_P (operands[0])
9106     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9107     && !(INTVAL (operands[2]) & ~255)
9108     && (INTVAL (operands[2]) & 128)
9109     && GET_MODE (operands[0]) != QImode"
9110   [(parallel [(set (strict_low_part (match_dup 0))
9111                    (any_or:QI (match_dup 1)
9112                               (match_dup 2)))
9113               (clobber (reg:CC FLAGS_REG))])]
9114   "operands[0] = gen_lowpart (QImode, operands[0]);
9115    operands[1] = gen_lowpart (QImode, operands[1]);
9116    operands[2] = gen_lowpart (QImode, operands[2]);")
9117
9118 (define_expand "xorqi_cc_ext_1"
9119   [(parallel [
9120      (set (reg:CCNO FLAGS_REG)
9121           (compare:CCNO
9122             (xor:SI
9123               (zero_extract:SI
9124                 (match_operand 1 "ext_register_operand" "")
9125                 (const_int 8)
9126                 (const_int 8))
9127               (match_operand:QI 2 "general_operand" ""))
9128             (const_int 0)))
9129      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9130                            (const_int 8)
9131                            (const_int 8))
9132           (xor:SI
9133             (zero_extract:SI
9134              (match_dup 1)
9135              (const_int 8)
9136              (const_int 8))
9137             (match_dup 2)))])]
9138   ""
9139   "")
9140
9141 (define_insn "*xorqi_cc_ext_1_rex64"
9142   [(set (reg FLAGS_REG)
9143         (compare
9144           (xor:SI
9145             (zero_extract:SI
9146               (match_operand 1 "ext_register_operand" "0")
9147               (const_int 8)
9148               (const_int 8))
9149             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9150           (const_int 0)))
9151    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9152                          (const_int 8)
9153                          (const_int 8))
9154         (xor:SI
9155           (zero_extract:SI
9156            (match_dup 1)
9157            (const_int 8)
9158            (const_int 8))
9159           (match_dup 2)))]
9160   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9161   "xor{b}\t{%2, %h0|%h0, %2}"
9162   [(set_attr "type" "alu")
9163    (set_attr "modrm" "1")
9164    (set_attr "mode" "QI")])
9165
9166 (define_insn "*xorqi_cc_ext_1"
9167   [(set (reg FLAGS_REG)
9168         (compare
9169           (xor:SI
9170             (zero_extract:SI
9171               (match_operand 1 "ext_register_operand" "0")
9172               (const_int 8)
9173               (const_int 8))
9174             (match_operand:QI 2 "general_operand" "qmn"))
9175           (const_int 0)))
9176    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9177                          (const_int 8)
9178                          (const_int 8))
9179         (xor:SI
9180           (zero_extract:SI
9181            (match_dup 1)
9182            (const_int 8)
9183            (const_int 8))
9184           (match_dup 2)))]
9185   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9186   "xor{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "modrm" "1")
9189    (set_attr "mode" "QI")])
9190 \f
9191 ;; Negation instructions
9192
9193 (define_expand "neg<mode>2"
9194   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9195         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9196   ""
9197   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9198
9199 (define_insn_and_split "*neg<dwi>2_doubleword"
9200   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9201         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9204   "#"
9205   "reload_completed"
9206   [(parallel
9207     [(set (reg:CCZ FLAGS_REG)
9208           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9209      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9210    (parallel
9211     [(set (match_dup 2)
9212           (plus:DWIH (match_dup 3)
9213                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9214                                 (const_int 0))))
9215      (clobber (reg:CC FLAGS_REG))])
9216    (parallel
9217     [(set (match_dup 2)
9218           (neg:DWIH (match_dup 2)))
9219      (clobber (reg:CC FLAGS_REG))])]
9220   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9221
9222 (define_insn "*neg<mode>2_1"
9223   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9224         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9227   "neg{<imodesuffix>}\t%0"
9228   [(set_attr "type" "negnot")
9229    (set_attr "mode" "<MODE>")])
9230
9231 ;; Combine is quite creative about this pattern.
9232 (define_insn "*negsi2_1_zext"
9233   [(set (match_operand:DI 0 "register_operand" "=r")
9234         (lshiftrt:DI
9235           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9236                              (const_int 32)))
9237         (const_int 32)))
9238    (clobber (reg:CC FLAGS_REG))]
9239   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9240   "neg{l}\t%k0"
9241   [(set_attr "type" "negnot")
9242    (set_attr "mode" "SI")])
9243
9244 ;; The problem with neg is that it does not perform (compare x 0),
9245 ;; it really performs (compare 0 x), which leaves us with the zero
9246 ;; flag being the only useful item.
9247
9248 (define_insn "*neg<mode>2_cmpz"
9249   [(set (reg:CCZ FLAGS_REG)
9250         (compare:CCZ
9251           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9252                    (const_int 0)))
9253    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9254         (neg:SWI (match_dup 1)))]
9255   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9256   "neg{<imodesuffix>}\t%0"
9257   [(set_attr "type" "negnot")
9258    (set_attr "mode" "<MODE>")])
9259
9260 (define_insn "*negsi2_cmpz_zext"
9261   [(set (reg:CCZ FLAGS_REG)
9262         (compare:CCZ
9263           (lshiftrt:DI
9264             (neg:DI (ashift:DI
9265                       (match_operand:DI 1 "register_operand" "0")
9266                       (const_int 32)))
9267             (const_int 32))
9268           (const_int 0)))
9269    (set (match_operand:DI 0 "register_operand" "=r")
9270         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9271                                         (const_int 32)))
9272                      (const_int 32)))]
9273   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9274   "neg{l}\t%k0"
9275   [(set_attr "type" "negnot")
9276    (set_attr "mode" "SI")])
9277
9278 ;; Changing of sign for FP values is doable using integer unit too.
9279
9280 (define_expand "<code><mode>2"
9281   [(set (match_operand:X87MODEF 0 "register_operand" "")
9282         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9283   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9284   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9285
9286 (define_insn "*absneg<mode>2_mixed"
9287   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9288         (match_operator:MODEF 3 "absneg_operator"
9289           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9290    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9293   "#")
9294
9295 (define_insn "*absneg<mode>2_sse"
9296   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9297         (match_operator:MODEF 3 "absneg_operator"
9298           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9299    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9300    (clobber (reg:CC FLAGS_REG))]
9301   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9302   "#")
9303
9304 (define_insn "*absneg<mode>2_i387"
9305   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9306         (match_operator:X87MODEF 3 "absneg_operator"
9307           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9308    (use (match_operand 2 "" ""))
9309    (clobber (reg:CC FLAGS_REG))]
9310   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9311   "#")
9312
9313 (define_expand "<code>tf2"
9314   [(set (match_operand:TF 0 "register_operand" "")
9315         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9316   "TARGET_SSE2"
9317   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9318
9319 (define_insn "*absnegtf2_sse"
9320   [(set (match_operand:TF 0 "register_operand" "=x,x")
9321         (match_operator:TF 3 "absneg_operator"
9322           [(match_operand:TF 1 "register_operand" "0,x")]))
9323    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9324    (clobber (reg:CC FLAGS_REG))]
9325   "TARGET_SSE2"
9326   "#")
9327
9328 ;; Splitters for fp abs and neg.
9329
9330 (define_split
9331   [(set (match_operand 0 "fp_register_operand" "")
9332         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9333    (use (match_operand 2 "" ""))
9334    (clobber (reg:CC FLAGS_REG))]
9335   "reload_completed"
9336   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9337
9338 (define_split
9339   [(set (match_operand 0 "register_operand" "")
9340         (match_operator 3 "absneg_operator"
9341           [(match_operand 1 "register_operand" "")]))
9342    (use (match_operand 2 "nonimmediate_operand" ""))
9343    (clobber (reg:CC FLAGS_REG))]
9344   "reload_completed && SSE_REG_P (operands[0])"
9345   [(set (match_dup 0) (match_dup 3))]
9346 {
9347   enum machine_mode mode = GET_MODE (operands[0]);
9348   enum machine_mode vmode = GET_MODE (operands[2]);
9349   rtx tmp;
9350
9351   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9352   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9353   if (operands_match_p (operands[0], operands[2]))
9354     {
9355       tmp = operands[1];
9356       operands[1] = operands[2];
9357       operands[2] = tmp;
9358     }
9359   if (GET_CODE (operands[3]) == ABS)
9360     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9361   else
9362     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9363   operands[3] = tmp;
9364 })
9365
9366 (define_split
9367   [(set (match_operand:SF 0 "register_operand" "")
9368         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9369    (use (match_operand:V4SF 2 "" ""))
9370    (clobber (reg:CC FLAGS_REG))]
9371   "reload_completed"
9372   [(parallel [(set (match_dup 0) (match_dup 1))
9373               (clobber (reg:CC FLAGS_REG))])]
9374 {
9375   rtx tmp;
9376   operands[0] = gen_lowpart (SImode, operands[0]);
9377   if (GET_CODE (operands[1]) == ABS)
9378     {
9379       tmp = gen_int_mode (0x7fffffff, SImode);
9380       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9381     }
9382   else
9383     {
9384       tmp = gen_int_mode (0x80000000, SImode);
9385       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9386     }
9387   operands[1] = tmp;
9388 })
9389
9390 (define_split
9391   [(set (match_operand:DF 0 "register_operand" "")
9392         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9393    (use (match_operand 2 "" ""))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "reload_completed"
9396   [(parallel [(set (match_dup 0) (match_dup 1))
9397               (clobber (reg:CC FLAGS_REG))])]
9398 {
9399   rtx tmp;
9400   if (TARGET_64BIT)
9401     {
9402       tmp = gen_lowpart (DImode, operands[0]);
9403       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9404       operands[0] = tmp;
9405
9406       if (GET_CODE (operands[1]) == ABS)
9407         tmp = const0_rtx;
9408       else
9409         tmp = gen_rtx_NOT (DImode, tmp);
9410     }
9411   else
9412     {
9413       operands[0] = gen_highpart (SImode, operands[0]);
9414       if (GET_CODE (operands[1]) == ABS)
9415         {
9416           tmp = gen_int_mode (0x7fffffff, SImode);
9417           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9418         }
9419       else
9420         {
9421           tmp = gen_int_mode (0x80000000, SImode);
9422           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9423         }
9424     }
9425   operands[1] = tmp;
9426 })
9427
9428 (define_split
9429   [(set (match_operand:XF 0 "register_operand" "")
9430         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9431    (use (match_operand 2 "" ""))
9432    (clobber (reg:CC FLAGS_REG))]
9433   "reload_completed"
9434   [(parallel [(set (match_dup 0) (match_dup 1))
9435               (clobber (reg:CC FLAGS_REG))])]
9436 {
9437   rtx tmp;
9438   operands[0] = gen_rtx_REG (SImode,
9439                              true_regnum (operands[0])
9440                              + (TARGET_64BIT ? 1 : 2));
9441   if (GET_CODE (operands[1]) == ABS)
9442     {
9443       tmp = GEN_INT (0x7fff);
9444       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9445     }
9446   else
9447     {
9448       tmp = GEN_INT (0x8000);
9449       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9450     }
9451   operands[1] = tmp;
9452 })
9453
9454 ;; Conditionalize these after reload. If they match before reload, we
9455 ;; lose the clobber and ability to use integer instructions.
9456
9457 (define_insn "*<code><mode>2_1"
9458   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9459         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9460   "TARGET_80387
9461    && (reload_completed
9462        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9463   "f<absnegprefix>"
9464   [(set_attr "type" "fsgn")
9465    (set_attr "mode" "<MODE>")])
9466
9467 (define_insn "*<code>extendsfdf2"
9468   [(set (match_operand:DF 0 "register_operand" "=f")
9469         (absneg:DF (float_extend:DF
9470                      (match_operand:SF 1 "register_operand" "0"))))]
9471   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9472   "f<absnegprefix>"
9473   [(set_attr "type" "fsgn")
9474    (set_attr "mode" "DF")])
9475
9476 (define_insn "*<code>extendsfxf2"
9477   [(set (match_operand:XF 0 "register_operand" "=f")
9478         (absneg:XF (float_extend:XF
9479                      (match_operand:SF 1 "register_operand" "0"))))]
9480   "TARGET_80387"
9481   "f<absnegprefix>"
9482   [(set_attr "type" "fsgn")
9483    (set_attr "mode" "XF")])
9484
9485 (define_insn "*<code>extenddfxf2"
9486   [(set (match_operand:XF 0 "register_operand" "=f")
9487         (absneg:XF (float_extend:XF
9488                       (match_operand:DF 1 "register_operand" "0"))))]
9489   "TARGET_80387"
9490   "f<absnegprefix>"
9491   [(set_attr "type" "fsgn")
9492    (set_attr "mode" "XF")])
9493
9494 ;; Copysign instructions
9495
9496 (define_mode_iterator CSGNMODE [SF DF TF])
9497 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9498
9499 (define_expand "copysign<mode>3"
9500   [(match_operand:CSGNMODE 0 "register_operand" "")
9501    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9502    (match_operand:CSGNMODE 2 "register_operand" "")]
9503   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9504    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9505 {
9506   ix86_expand_copysign (operands);
9507   DONE;
9508 })
9509
9510 (define_insn_and_split "copysign<mode>3_const"
9511   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9512         (unspec:CSGNMODE
9513           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9514            (match_operand:CSGNMODE 2 "register_operand" "0")
9515            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9516           UNSPEC_COPYSIGN))]
9517   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9518    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9519   "#"
9520   "&& reload_completed"
9521   [(const_int 0)]
9522 {
9523   ix86_split_copysign_const (operands);
9524   DONE;
9525 })
9526
9527 (define_insn "copysign<mode>3_var"
9528   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9529         (unspec:CSGNMODE
9530           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9531            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9532            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9533            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9534           UNSPEC_COPYSIGN))
9535    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9536   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9537    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9538   "#")
9539
9540 (define_split
9541   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9542         (unspec:CSGNMODE
9543           [(match_operand:CSGNMODE 2 "register_operand" "")
9544            (match_operand:CSGNMODE 3 "register_operand" "")
9545            (match_operand:<CSGNVMODE> 4 "" "")
9546            (match_operand:<CSGNVMODE> 5 "" "")]
9547           UNSPEC_COPYSIGN))
9548    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9549   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9550     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9551    && reload_completed"
9552   [(const_int 0)]
9553 {
9554   ix86_split_copysign_var (operands);
9555   DONE;
9556 })
9557 \f
9558 ;; One complement instructions
9559
9560 (define_expand "one_cmpl<mode>2"
9561   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9562         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9563   ""
9564   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9565
9566 (define_insn "*one_cmpl<mode>2_1"
9567   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9568         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9569   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9570   "not{<imodesuffix>}\t%0"
9571   [(set_attr "type" "negnot")
9572    (set_attr "mode" "<MODE>")])
9573
9574 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9575 (define_insn "*one_cmplqi2_1"
9576   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9577         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9578   "ix86_unary_operator_ok (NOT, QImode, operands)"
9579   "@
9580    not{b}\t%0
9581    not{l}\t%k0"
9582   [(set_attr "type" "negnot")
9583    (set_attr "mode" "QI,SI")])
9584
9585 ;; ??? Currently never generated - xor is used instead.
9586 (define_insn "*one_cmplsi2_1_zext"
9587   [(set (match_operand:DI 0 "register_operand" "=r")
9588         (zero_extend:DI
9589           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9590   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9591   "not{l}\t%k0"
9592   [(set_attr "type" "negnot")
9593    (set_attr "mode" "SI")])
9594
9595 (define_insn "*one_cmpl<mode>2_2"
9596   [(set (reg FLAGS_REG)
9597         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9598                  (const_int 0)))
9599    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9600         (not:SWI (match_dup 1)))]
9601   "ix86_match_ccmode (insn, CCNOmode)
9602    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9603   "#"
9604   [(set_attr "type" "alu1")
9605    (set_attr "mode" "<MODE>")])
9606
9607 (define_split
9608   [(set (match_operand 0 "flags_reg_operand" "")
9609         (match_operator 2 "compare_operator"
9610           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9611            (const_int 0)]))
9612    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9613         (not:SWI (match_dup 3)))]
9614   "ix86_match_ccmode (insn, CCNOmode)"
9615   [(parallel [(set (match_dup 0)
9616                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9617                                     (const_int 0)]))
9618               (set (match_dup 1)
9619                    (xor:SWI (match_dup 3) (const_int -1)))])]
9620   "")
9621
9622 ;; ??? Currently never generated - xor is used instead.
9623 (define_insn "*one_cmplsi2_2_zext"
9624   [(set (reg FLAGS_REG)
9625         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9626                  (const_int 0)))
9627    (set (match_operand:DI 0 "register_operand" "=r")
9628         (zero_extend:DI (not:SI (match_dup 1))))]
9629   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9630    && ix86_unary_operator_ok (NOT, SImode, operands)"
9631   "#"
9632   [(set_attr "type" "alu1")
9633    (set_attr "mode" "SI")])
9634
9635 (define_split
9636   [(set (match_operand 0 "flags_reg_operand" "")
9637         (match_operator 2 "compare_operator"
9638           [(not:SI (match_operand:SI 3 "register_operand" ""))
9639            (const_int 0)]))
9640    (set (match_operand:DI 1 "register_operand" "")
9641         (zero_extend:DI (not:SI (match_dup 3))))]
9642   "ix86_match_ccmode (insn, CCNOmode)"
9643   [(parallel [(set (match_dup 0)
9644                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9645                                     (const_int 0)]))
9646               (set (match_dup 1)
9647                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9648   "")
9649 \f
9650 ;; Arithmetic shift instructions
9651
9652 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9653 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9654 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9655 ;; from the assembler input.
9656 ;;
9657 ;; This instruction shifts the target reg/mem as usual, but instead of
9658 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9659 ;; is a left shift double, bits are taken from the high order bits of
9660 ;; reg, else if the insn is a shift right double, bits are taken from the
9661 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9662 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9663 ;;
9664 ;; Since sh[lr]d does not change the `reg' operand, that is done
9665 ;; separately, making all shifts emit pairs of shift double and normal
9666 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9667 ;; support a 63 bit shift, each shift where the count is in a reg expands
9668 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9669 ;;
9670 ;; If the shift count is a constant, we need never emit more than one
9671 ;; shift pair, instead using moves and sign extension for counts greater
9672 ;; than 31.
9673
9674 (define_expand "ashlti3"
9675   [(set (match_operand:TI 0 "register_operand" "")
9676         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9677                    (match_operand:QI 2 "nonmemory_operand" "")))]
9678   "TARGET_64BIT"
9679   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9680
9681 (define_insn "*ashlti3_1"
9682   [(set (match_operand:TI 0 "register_operand" "=&r,r")
9683         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9684                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9685    (clobber (reg:CC FLAGS_REG))]
9686   "TARGET_64BIT"
9687   "#"
9688   [(set_attr "type" "multi")])
9689
9690 (define_peephole2
9691   [(match_scratch:DI 3 "r")
9692    (parallel [(set (match_operand:TI 0 "register_operand" "")
9693                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9694                               (match_operand:QI 2 "nonmemory_operand" "")))
9695               (clobber (reg:CC FLAGS_REG))])
9696    (match_dup 3)]
9697   "TARGET_64BIT"
9698   [(const_int 0)]
9699   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9700
9701 (define_split
9702   [(set (match_operand:TI 0 "register_operand" "")
9703         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9704                    (match_operand:QI 2 "nonmemory_operand" "")))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9707                     ? epilogue_completed : reload_completed)"
9708   [(const_int 0)]
9709   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9710
9711 (define_insn "x86_64_shld"
9712   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9713         (ior:DI (ashift:DI (match_dup 0)
9714                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9715                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9716                   (minus:QI (const_int 64) (match_dup 2)))))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "TARGET_64BIT"
9719   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9720   [(set_attr "type" "ishift")
9721    (set_attr "prefix_0f" "1")
9722    (set_attr "mode" "DI")
9723    (set_attr "athlon_decode" "vector")
9724    (set_attr "amdfam10_decode" "vector")])
9725
9726 (define_expand "x86_64_shift_adj_1"
9727   [(set (reg:CCZ FLAGS_REG)
9728         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9729                              (const_int 64))
9730                      (const_int 0)))
9731    (set (match_operand:DI 0 "register_operand" "")
9732         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9733                          (match_operand:DI 1 "register_operand" "")
9734                          (match_dup 0)))
9735    (set (match_dup 1)
9736         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9737                          (match_operand:DI 3 "register_operand" "r")
9738                          (match_dup 1)))]
9739   "TARGET_64BIT"
9740   "")
9741
9742 (define_expand "x86_64_shift_adj_2"
9743   [(use (match_operand:DI 0 "register_operand" ""))
9744    (use (match_operand:DI 1 "register_operand" ""))
9745    (use (match_operand:QI 2 "register_operand" ""))]
9746   "TARGET_64BIT"
9747 {
9748   rtx label = gen_label_rtx ();
9749   rtx tmp;
9750
9751   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9752
9753   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9754   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9755   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9756                               gen_rtx_LABEL_REF (VOIDmode, label),
9757                               pc_rtx);
9758   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9759   JUMP_LABEL (tmp) = label;
9760
9761   emit_move_insn (operands[0], operands[1]);
9762   ix86_expand_clear (operands[1]);
9763
9764   emit_label (label);
9765   LABEL_NUSES (label) = 1;
9766
9767   DONE;
9768 })
9769
9770 (define_expand "ashldi3"
9771   [(set (match_operand:DI 0 "shiftdi_operand" "")
9772         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9773                    (match_operand:QI 2 "nonmemory_operand" "")))]
9774   ""
9775   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9776
9777 (define_insn "*ashldi3_1_rex64"
9778   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9779         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9780                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9783 {
9784   switch (get_attr_type (insn))
9785     {
9786     case TYPE_ALU:
9787       gcc_assert (operands[2] == const1_rtx);
9788       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9789       return "add{q}\t%0, %0";
9790
9791     case TYPE_LEA:
9792       gcc_assert (CONST_INT_P (operands[2]));
9793       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9794       operands[1] = gen_rtx_MULT (DImode, operands[1],
9795                                   GEN_INT (1 << INTVAL (operands[2])));
9796       return "lea{q}\t{%a1, %0|%0, %a1}";
9797
9798     default:
9799       if (REG_P (operands[2]))
9800         return "sal{q}\t{%b2, %0|%0, %b2}";
9801       else if (operands[2] == const1_rtx
9802                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9803         return "sal{q}\t%0";
9804       else
9805         return "sal{q}\t{%2, %0|%0, %2}";
9806     }
9807 }
9808   [(set (attr "type")
9809      (cond [(eq_attr "alternative" "1")
9810               (const_string "lea")
9811             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9812                           (const_int 0))
9813                       (match_operand 0 "register_operand" ""))
9814                  (match_operand 2 "const1_operand" ""))
9815               (const_string "alu")
9816            ]
9817            (const_string "ishift")))
9818    (set (attr "length_immediate")
9819      (if_then_else
9820        (ior (eq_attr "type" "alu")
9821             (and (eq_attr "type" "ishift")
9822                  (and (match_operand 2 "const1_operand" "")
9823                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9824                           (const_int 0)))))
9825        (const_string "0")
9826        (const_string "*")))
9827    (set_attr "mode" "DI")])
9828
9829 ;; Convert lea to the lea pattern to avoid flags dependency.
9830 (define_split
9831   [(set (match_operand:DI 0 "register_operand" "")
9832         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9833                    (match_operand:QI 2 "immediate_operand" "")))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "TARGET_64BIT && reload_completed
9836    && true_regnum (operands[0]) != true_regnum (operands[1])"
9837   [(set (match_dup 0)
9838         (mult:DI (match_dup 1)
9839                  (match_dup 2)))]
9840   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9841
9842 ;; This pattern can't accept a variable shift count, since shifts by
9843 ;; zero don't affect the flags.  We assume that shifts by constant
9844 ;; zero are optimized away.
9845 (define_insn "*ashldi3_cmp_rex64"
9846   [(set (reg FLAGS_REG)
9847         (compare
9848           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9849                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9850           (const_int 0)))
9851    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9852         (ashift:DI (match_dup 1) (match_dup 2)))]
9853   "TARGET_64BIT
9854    && (optimize_function_for_size_p (cfun)
9855        || !TARGET_PARTIAL_FLAG_REG_STALL
9856        || (operands[2] == const1_rtx
9857            && (TARGET_SHIFT1
9858                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9859    && ix86_match_ccmode (insn, CCGOCmode)
9860    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9861 {
9862   switch (get_attr_type (insn))
9863     {
9864     case TYPE_ALU:
9865       gcc_assert (operands[2] == const1_rtx);
9866       return "add{q}\t%0, %0";
9867
9868     default:
9869       if (REG_P (operands[2]))
9870         return "sal{q}\t{%b2, %0|%0, %b2}";
9871       else if (operands[2] == const1_rtx
9872                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9873         return "sal{q}\t%0";
9874       else
9875         return "sal{q}\t{%2, %0|%0, %2}";
9876     }
9877 }
9878   [(set (attr "type")
9879      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9880                           (const_int 0))
9881                       (match_operand 0 "register_operand" ""))
9882                  (match_operand 2 "const1_operand" ""))
9883               (const_string "alu")
9884            ]
9885            (const_string "ishift")))
9886    (set (attr "length_immediate")
9887      (if_then_else
9888        (ior (eq_attr "type" "alu")
9889             (and (eq_attr "type" "ishift")
9890                  (and (match_operand 2 "const1_operand" "")
9891                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9892                           (const_int 0)))))
9893        (const_string "0")
9894        (const_string "*")))
9895    (set_attr "mode" "DI")])
9896
9897 (define_insn "*ashldi3_cconly_rex64"
9898   [(set (reg FLAGS_REG)
9899         (compare
9900           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9901                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9902           (const_int 0)))
9903    (clobber (match_scratch:DI 0 "=r"))]
9904   "TARGET_64BIT
9905    && (optimize_function_for_size_p (cfun)
9906        || !TARGET_PARTIAL_FLAG_REG_STALL
9907        || (operands[2] == const1_rtx
9908            && (TARGET_SHIFT1
9909                || TARGET_DOUBLE_WITH_ADD)))
9910    && ix86_match_ccmode (insn, CCGOCmode)
9911    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9912 {
9913   switch (get_attr_type (insn))
9914     {
9915     case TYPE_ALU:
9916       gcc_assert (operands[2] == const1_rtx);
9917       return "add{q}\t%0, %0";
9918
9919     default:
9920       if (REG_P (operands[2]))
9921         return "sal{q}\t{%b2, %0|%0, %b2}";
9922       else if (operands[2] == const1_rtx
9923                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9924         return "sal{q}\t%0";
9925       else
9926         return "sal{q}\t{%2, %0|%0, %2}";
9927     }
9928 }
9929   [(set (attr "type")
9930      (cond [(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" "DI")])
9947
9948 (define_insn "*ashldi3_1"
9949   [(set (match_operand:DI 0 "register_operand" "=&r,r")
9950         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9951                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9952    (clobber (reg:CC FLAGS_REG))]
9953   "!TARGET_64BIT"
9954   "#"
9955   [(set_attr "type" "multi")])
9956
9957 ;; By default we don't ask for a scratch register, because when DImode
9958 ;; values are manipulated, registers are already at a premium.  But if
9959 ;; we have one handy, we won't turn it away.
9960 (define_peephole2
9961   [(match_scratch:SI 3 "r")
9962    (parallel [(set (match_operand:DI 0 "register_operand" "")
9963                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9964                               (match_operand:QI 2 "nonmemory_operand" "")))
9965               (clobber (reg:CC FLAGS_REG))])
9966    (match_dup 3)]
9967   "!TARGET_64BIT && TARGET_CMOVE"
9968   [(const_int 0)]
9969   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9970
9971 (define_split
9972   [(set (match_operand:DI 0 "register_operand" "")
9973         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9974                    (match_operand:QI 2 "nonmemory_operand" "")))
9975    (clobber (reg:CC FLAGS_REG))]
9976   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9977                      ? epilogue_completed : reload_completed)"
9978   [(const_int 0)]
9979   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9980
9981 (define_insn "x86_shld"
9982   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9983         (ior:SI (ashift:SI (match_dup 0)
9984                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9985                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9986                   (minus:QI (const_int 32) (match_dup 2)))))
9987    (clobber (reg:CC FLAGS_REG))]
9988   ""
9989   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9990   [(set_attr "type" "ishift")
9991    (set_attr "prefix_0f" "1")
9992    (set_attr "mode" "SI")
9993    (set_attr "pent_pair" "np")
9994    (set_attr "athlon_decode" "vector")
9995    (set_attr "amdfam10_decode" "vector")])
9996
9997 (define_expand "x86_shift_adj_1"
9998   [(set (reg:CCZ FLAGS_REG)
9999         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10000                              (const_int 32))
10001                      (const_int 0)))
10002    (set (match_operand:SI 0 "register_operand" "")
10003         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10004                          (match_operand:SI 1 "register_operand" "")
10005                          (match_dup 0)))
10006    (set (match_dup 1)
10007         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10008                          (match_operand:SI 3 "register_operand" "r")
10009                          (match_dup 1)))]
10010   "TARGET_CMOVE"
10011   "")
10012
10013 (define_expand "x86_shift_adj_2"
10014   [(use (match_operand:SI 0 "register_operand" ""))
10015    (use (match_operand:SI 1 "register_operand" ""))
10016    (use (match_operand:QI 2 "register_operand" ""))]
10017   ""
10018 {
10019   rtx label = gen_label_rtx ();
10020   rtx tmp;
10021
10022   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10023
10024   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10025   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10026   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10027                               gen_rtx_LABEL_REF (VOIDmode, label),
10028                               pc_rtx);
10029   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10030   JUMP_LABEL (tmp) = label;
10031
10032   emit_move_insn (operands[0], operands[1]);
10033   ix86_expand_clear (operands[1]);
10034
10035   emit_label (label);
10036   LABEL_NUSES (label) = 1;
10037
10038   DONE;
10039 })
10040
10041 (define_expand "ashlsi3"
10042   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10043         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10044                    (match_operand:QI 2 "nonmemory_operand" "")))]
10045   ""
10046   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10047
10048 (define_insn "*ashlsi3_1"
10049   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10050         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10051                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10052    (clobber (reg:CC FLAGS_REG))]
10053   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10054 {
10055   switch (get_attr_type (insn))
10056     {
10057     case TYPE_ALU:
10058       gcc_assert (operands[2] == const1_rtx);
10059       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10060       return "add{l}\t%0, %0";
10061
10062     case TYPE_LEA:
10063       return "#";
10064
10065     default:
10066       if (REG_P (operands[2]))
10067         return "sal{l}\t{%b2, %0|%0, %b2}";
10068       else if (operands[2] == const1_rtx
10069                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10070         return "sal{l}\t%0";
10071       else
10072         return "sal{l}\t{%2, %0|%0, %2}";
10073     }
10074 }
10075   [(set (attr "type")
10076      (cond [(eq_attr "alternative" "1")
10077               (const_string "lea")
10078             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10079                           (const_int 0))
10080                       (match_operand 0 "register_operand" ""))
10081                  (match_operand 2 "const1_operand" ""))
10082               (const_string "alu")
10083            ]
10084            (const_string "ishift")))
10085    (set (attr "length_immediate")
10086      (if_then_else
10087        (ior (eq_attr "type" "alu")
10088             (and (eq_attr "type" "ishift")
10089                  (and (match_operand 2 "const1_operand" "")
10090                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10091                           (const_int 0)))))
10092        (const_string "0")
10093        (const_string "*")))
10094    (set_attr "mode" "SI")])
10095
10096 ;; Convert lea to the lea pattern to avoid flags dependency.
10097 (define_split
10098   [(set (match_operand 0 "register_operand" "")
10099         (ashift (match_operand 1 "index_register_operand" "")
10100                 (match_operand:QI 2 "const_int_operand" "")))
10101    (clobber (reg:CC FLAGS_REG))]
10102   "reload_completed
10103    && true_regnum (operands[0]) != true_regnum (operands[1])
10104    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10105   [(const_int 0)]
10106 {
10107   rtx pat;
10108   enum machine_mode mode = GET_MODE (operands[0]);
10109
10110   if (GET_MODE_SIZE (mode) < 4)
10111     operands[0] = gen_lowpart (SImode, operands[0]);
10112   if (mode != Pmode)
10113     operands[1] = gen_lowpart (Pmode, operands[1]);
10114   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10115
10116   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10117   if (Pmode != SImode)
10118     pat = gen_rtx_SUBREG (SImode, pat, 0);
10119   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10120   DONE;
10121 })
10122
10123 ;; Rare case of shifting RSP is handled by generating move and shift
10124 (define_split
10125   [(set (match_operand 0 "register_operand" "")
10126         (ashift (match_operand 1 "register_operand" "")
10127                 (match_operand:QI 2 "const_int_operand" "")))
10128    (clobber (reg:CC FLAGS_REG))]
10129   "reload_completed
10130    && true_regnum (operands[0]) != true_regnum (operands[1])"
10131   [(const_int 0)]
10132 {
10133   rtx pat, clob;
10134   emit_move_insn (operands[0], operands[1]);
10135   pat = gen_rtx_SET (VOIDmode, operands[0],
10136                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10137                                      operands[0], operands[2]));
10138   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10139   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10140   DONE;
10141 })
10142
10143 (define_insn "*ashlsi3_1_zext"
10144   [(set (match_operand:DI 0 "register_operand" "=r,r")
10145         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10146                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10147    (clobber (reg:CC FLAGS_REG))]
10148   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10149 {
10150   switch (get_attr_type (insn))
10151     {
10152     case TYPE_ALU:
10153       gcc_assert (operands[2] == const1_rtx);
10154       return "add{l}\t%k0, %k0";
10155
10156     case TYPE_LEA:
10157       return "#";
10158
10159     default:
10160       if (REG_P (operands[2]))
10161         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10162       else if (operands[2] == const1_rtx
10163                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10164         return "sal{l}\t%k0";
10165       else
10166         return "sal{l}\t{%2, %k0|%k0, %2}";
10167     }
10168 }
10169   [(set (attr "type")
10170      (cond [(eq_attr "alternative" "1")
10171               (const_string "lea")
10172             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10173                      (const_int 0))
10174                  (match_operand 2 "const1_operand" ""))
10175               (const_string "alu")
10176            ]
10177            (const_string "ishift")))
10178    (set (attr "length_immediate")
10179      (if_then_else
10180        (ior (eq_attr "type" "alu")
10181             (and (eq_attr "type" "ishift")
10182                  (and (match_operand 2 "const1_operand" "")
10183                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10184                           (const_int 0)))))
10185        (const_string "0")
10186        (const_string "*")))
10187    (set_attr "mode" "SI")])
10188
10189 ;; Convert lea to the lea pattern to avoid flags dependency.
10190 (define_split
10191   [(set (match_operand:DI 0 "register_operand" "")
10192         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10193                                 (match_operand:QI 2 "const_int_operand" ""))))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "TARGET_64BIT && reload_completed
10196    && true_regnum (operands[0]) != true_regnum (operands[1])"
10197   [(set (match_dup 0) (zero_extend:DI
10198                         (subreg:SI (mult:SI (match_dup 1)
10199                                             (match_dup 2)) 0)))]
10200 {
10201   operands[1] = gen_lowpart (Pmode, operands[1]);
10202   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10203 })
10204
10205 ;; This pattern can't accept a variable shift count, since shifts by
10206 ;; zero don't affect the flags.  We assume that shifts by constant
10207 ;; zero are optimized away.
10208 (define_insn "*ashlsi3_cmp"
10209   [(set (reg FLAGS_REG)
10210         (compare
10211           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10212                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10213           (const_int 0)))
10214    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10215         (ashift:SI (match_dup 1) (match_dup 2)))]
10216    "(optimize_function_for_size_p (cfun)
10217      || !TARGET_PARTIAL_FLAG_REG_STALL
10218      || (operands[2] == const1_rtx
10219          && (TARGET_SHIFT1
10220              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10221    && ix86_match_ccmode (insn, CCGOCmode)
10222    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10223 {
10224   switch (get_attr_type (insn))
10225     {
10226     case TYPE_ALU:
10227       gcc_assert (operands[2] == const1_rtx);
10228       return "add{l}\t%0, %0";
10229
10230     default:
10231       if (REG_P (operands[2]))
10232         return "sal{l}\t{%b2, %0|%0, %b2}";
10233       else if (operands[2] == const1_rtx
10234                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10235         return "sal{l}\t%0";
10236       else
10237         return "sal{l}\t{%2, %0|%0, %2}";
10238     }
10239 }
10240   [(set (attr "type")
10241      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10242                           (const_int 0))
10243                       (match_operand 0 "register_operand" ""))
10244                  (match_operand 2 "const1_operand" ""))
10245               (const_string "alu")
10246            ]
10247            (const_string "ishift")))
10248    (set (attr "length_immediate")
10249      (if_then_else
10250        (ior (eq_attr "type" "alu")
10251             (and (eq_attr "type" "ishift")
10252                  (and (match_operand 2 "const1_operand" "")
10253                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10254                           (const_int 0)))))
10255        (const_string "0")
10256        (const_string "*")))
10257    (set_attr "mode" "SI")])
10258
10259 (define_insn "*ashlsi3_cconly"
10260   [(set (reg FLAGS_REG)
10261         (compare
10262           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10263                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10264           (const_int 0)))
10265    (clobber (match_scratch:SI 0 "=r"))]
10266   "(optimize_function_for_size_p (cfun)
10267     || !TARGET_PARTIAL_FLAG_REG_STALL
10268     || (operands[2] == const1_rtx
10269         && (TARGET_SHIFT1
10270             || TARGET_DOUBLE_WITH_ADD)))
10271    && ix86_match_ccmode (insn, CCGOCmode)
10272    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10273 {
10274   switch (get_attr_type (insn))
10275     {
10276     case TYPE_ALU:
10277       gcc_assert (operands[2] == const1_rtx);
10278       return "add{l}\t%0, %0";
10279
10280     default:
10281       if (REG_P (operands[2]))
10282         return "sal{l}\t{%b2, %0|%0, %b2}";
10283       else if (operands[2] == const1_rtx
10284                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285         return "sal{l}\t%0";
10286       else
10287         return "sal{l}\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" "SI")])
10308
10309 (define_insn "*ashlsi3_cmp_zext"
10310   [(set (reg FLAGS_REG)
10311         (compare
10312           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10313                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10314           (const_int 0)))
10315    (set (match_operand:DI 0 "register_operand" "=r")
10316         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10317   "TARGET_64BIT
10318    && (optimize_function_for_size_p (cfun)
10319        || !TARGET_PARTIAL_FLAG_REG_STALL
10320        || (operands[2] == const1_rtx
10321            && (TARGET_SHIFT1
10322                || TARGET_DOUBLE_WITH_ADD)))
10323    && ix86_match_ccmode (insn, CCGOCmode)
10324    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10325 {
10326   switch (get_attr_type (insn))
10327     {
10328     case TYPE_ALU:
10329       gcc_assert (operands[2] == const1_rtx);
10330       return "add{l}\t%k0, %k0";
10331
10332     default:
10333       if (REG_P (operands[2]))
10334         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10335       else if (operands[2] == const1_rtx
10336                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10337         return "sal{l}\t%k0";
10338       else
10339         return "sal{l}\t{%2, %k0|%k0, %2}";
10340     }
10341 }
10342   [(set (attr "type")
10343      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10344                      (const_int 0))
10345                  (match_operand 2 "const1_operand" ""))
10346               (const_string "alu")
10347            ]
10348            (const_string "ishift")))
10349    (set (attr "length_immediate")
10350      (if_then_else
10351        (ior (eq_attr "type" "alu")
10352             (and (eq_attr "type" "ishift")
10353                  (and (match_operand 2 "const1_operand" "")
10354                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10355                           (const_int 0)))))
10356        (const_string "0")
10357        (const_string "*")))
10358    (set_attr "mode" "SI")])
10359
10360 (define_expand "ashlhi3"
10361   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10362         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10363                    (match_operand:QI 2 "nonmemory_operand" "")))]
10364   "TARGET_HIMODE_MATH"
10365   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10366
10367 (define_insn "*ashlhi3_1_lea"
10368   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10369         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10370                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "!TARGET_PARTIAL_REG_STALL
10373    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10374 {
10375   switch (get_attr_type (insn))
10376     {
10377     case TYPE_LEA:
10378       return "#";
10379     case TYPE_ALU:
10380       gcc_assert (operands[2] == const1_rtx);
10381       return "add{w}\t%0, %0";
10382
10383     default:
10384       if (REG_P (operands[2]))
10385         return "sal{w}\t{%b2, %0|%0, %b2}";
10386       else if (operands[2] == const1_rtx
10387                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10388         return "sal{w}\t%0";
10389       else
10390         return "sal{w}\t{%2, %0|%0, %2}";
10391     }
10392 }
10393   [(set (attr "type")
10394      (cond [(eq_attr "alternative" "1")
10395               (const_string "lea")
10396             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10397                           (const_int 0))
10398                       (match_operand 0 "register_operand" ""))
10399                  (match_operand 2 "const1_operand" ""))
10400               (const_string "alu")
10401            ]
10402            (const_string "ishift")))
10403    (set (attr "length_immediate")
10404      (if_then_else
10405        (ior (eq_attr "type" "alu")
10406             (and (eq_attr "type" "ishift")
10407                  (and (match_operand 2 "const1_operand" "")
10408                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10409                           (const_int 0)))))
10410        (const_string "0")
10411        (const_string "*")))
10412    (set_attr "mode" "HI,SI")])
10413
10414 (define_insn "*ashlhi3_1"
10415   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10416         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10417                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10418    (clobber (reg:CC FLAGS_REG))]
10419   "TARGET_PARTIAL_REG_STALL
10420    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10421 {
10422   switch (get_attr_type (insn))
10423     {
10424     case TYPE_ALU:
10425       gcc_assert (operands[2] == const1_rtx);
10426       return "add{w}\t%0, %0";
10427
10428     default:
10429       if (REG_P (operands[2]))
10430         return "sal{w}\t{%b2, %0|%0, %b2}";
10431       else if (operands[2] == const1_rtx
10432                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10433         return "sal{w}\t%0";
10434       else
10435         return "sal{w}\t{%2, %0|%0, %2}";
10436     }
10437 }
10438   [(set (attr "type")
10439      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10440                           (const_int 0))
10441                       (match_operand 0 "register_operand" ""))
10442                  (match_operand 2 "const1_operand" ""))
10443               (const_string "alu")
10444            ]
10445            (const_string "ishift")))
10446    (set (attr "length_immediate")
10447      (if_then_else
10448        (ior (eq_attr "type" "alu")
10449             (and (eq_attr "type" "ishift")
10450                  (and (match_operand 2 "const1_operand" "")
10451                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10452                           (const_int 0)))))
10453        (const_string "0")
10454        (const_string "*")))
10455    (set_attr "mode" "HI")])
10456
10457 ;; This pattern can't accept a variable shift count, since shifts by
10458 ;; zero don't affect the flags.  We assume that shifts by constant
10459 ;; zero are optimized away.
10460 (define_insn "*ashlhi3_cmp"
10461   [(set (reg FLAGS_REG)
10462         (compare
10463           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10464                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10465           (const_int 0)))
10466    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10467         (ashift:HI (match_dup 1) (match_dup 2)))]
10468   "(optimize_function_for_size_p (cfun)
10469     || !TARGET_PARTIAL_FLAG_REG_STALL
10470     || (operands[2] == const1_rtx
10471         && (TARGET_SHIFT1
10472             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10473    && ix86_match_ccmode (insn, CCGOCmode)
10474    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10475 {
10476   switch (get_attr_type (insn))
10477     {
10478     case TYPE_ALU:
10479       gcc_assert (operands[2] == const1_rtx);
10480       return "add{w}\t%0, %0";
10481
10482     default:
10483       if (REG_P (operands[2]))
10484         return "sal{w}\t{%b2, %0|%0, %b2}";
10485       else if (operands[2] == const1_rtx
10486                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10487         return "sal{w}\t%0";
10488       else
10489         return "sal{w}\t{%2, %0|%0, %2}";
10490     }
10491 }
10492   [(set (attr "type")
10493      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10494                           (const_int 0))
10495                       (match_operand 0 "register_operand" ""))
10496                  (match_operand 2 "const1_operand" ""))
10497               (const_string "alu")
10498            ]
10499            (const_string "ishift")))
10500    (set (attr "length_immediate")
10501      (if_then_else
10502        (ior (eq_attr "type" "alu")
10503             (and (eq_attr "type" "ishift")
10504                  (and (match_operand 2 "const1_operand" "")
10505                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10506                           (const_int 0)))))
10507        (const_string "0")
10508        (const_string "*")))
10509    (set_attr "mode" "HI")])
10510
10511 (define_insn "*ashlhi3_cconly"
10512   [(set (reg FLAGS_REG)
10513         (compare
10514           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10515                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10516           (const_int 0)))
10517    (clobber (match_scratch:HI 0 "=r"))]
10518   "(optimize_function_for_size_p (cfun)
10519     || !TARGET_PARTIAL_FLAG_REG_STALL
10520     || (operands[2] == const1_rtx
10521         && (TARGET_SHIFT1
10522             || TARGET_DOUBLE_WITH_ADD)))
10523    && ix86_match_ccmode (insn, CCGOCmode)
10524    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10525 {
10526   switch (get_attr_type (insn))
10527     {
10528     case TYPE_ALU:
10529       gcc_assert (operands[2] == const1_rtx);
10530       return "add{w}\t%0, %0";
10531
10532     default:
10533       if (REG_P (operands[2]))
10534         return "sal{w}\t{%b2, %0|%0, %b2}";
10535       else if (operands[2] == const1_rtx
10536                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10537         return "sal{w}\t%0";
10538       else
10539         return "sal{w}\t{%2, %0|%0, %2}";
10540     }
10541 }
10542   [(set (attr "type")
10543      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10544                           (const_int 0))
10545                       (match_operand 0 "register_operand" ""))
10546                  (match_operand 2 "const1_operand" ""))
10547               (const_string "alu")
10548            ]
10549            (const_string "ishift")))
10550    (set (attr "length_immediate")
10551      (if_then_else
10552        (ior (eq_attr "type" "alu")
10553             (and (eq_attr "type" "ishift")
10554                  (and (match_operand 2 "const1_operand" "")
10555                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10556                           (const_int 0)))))
10557        (const_string "0")
10558        (const_string "*")))
10559    (set_attr "mode" "HI")])
10560
10561 (define_expand "ashlqi3"
10562   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10563         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10564                    (match_operand:QI 2 "nonmemory_operand" "")))]
10565   "TARGET_QIMODE_MATH"
10566   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10567
10568 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10569
10570 (define_insn "*ashlqi3_1_lea"
10571   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10572         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10573                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10574    (clobber (reg:CC FLAGS_REG))]
10575   "!TARGET_PARTIAL_REG_STALL
10576    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10577 {
10578   switch (get_attr_type (insn))
10579     {
10580     case TYPE_LEA:
10581       return "#";
10582     case TYPE_ALU:
10583       gcc_assert (operands[2] == const1_rtx);
10584       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10585         return "add{l}\t%k0, %k0";
10586       else
10587         return "add{b}\t%0, %0";
10588
10589     default:
10590       if (REG_P (operands[2]))
10591         {
10592           if (get_attr_mode (insn) == MODE_SI)
10593             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10594           else
10595             return "sal{b}\t{%b2, %0|%0, %b2}";
10596         }
10597       else if (operands[2] == const1_rtx
10598                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10599         {
10600           if (get_attr_mode (insn) == MODE_SI)
10601             return "sal{l}\t%0";
10602           else
10603             return "sal{b}\t%0";
10604         }
10605       else
10606         {
10607           if (get_attr_mode (insn) == MODE_SI)
10608             return "sal{l}\t{%2, %k0|%k0, %2}";
10609           else
10610             return "sal{b}\t{%2, %0|%0, %2}";
10611         }
10612     }
10613 }
10614   [(set (attr "type")
10615      (cond [(eq_attr "alternative" "2")
10616               (const_string "lea")
10617             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10618                           (const_int 0))
10619                       (match_operand 0 "register_operand" ""))
10620                  (match_operand 2 "const1_operand" ""))
10621               (const_string "alu")
10622            ]
10623            (const_string "ishift")))
10624    (set (attr "length_immediate")
10625      (if_then_else
10626        (ior (eq_attr "type" "alu")
10627             (and (eq_attr "type" "ishift")
10628                  (and (match_operand 2 "const1_operand" "")
10629                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10630                           (const_int 0)))))
10631        (const_string "0")
10632        (const_string "*")))
10633    (set_attr "mode" "QI,SI,SI")])
10634
10635 (define_insn "*ashlqi3_1"
10636   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10637         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10638                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10639    (clobber (reg:CC FLAGS_REG))]
10640   "TARGET_PARTIAL_REG_STALL
10641    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10642 {
10643   switch (get_attr_type (insn))
10644     {
10645     case TYPE_ALU:
10646       gcc_assert (operands[2] == const1_rtx);
10647       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10648         return "add{l}\t%k0, %k0";
10649       else
10650         return "add{b}\t%0, %0";
10651
10652     default:
10653       if (REG_P (operands[2]))
10654         {
10655           if (get_attr_mode (insn) == MODE_SI)
10656             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10657           else
10658             return "sal{b}\t{%b2, %0|%0, %b2}";
10659         }
10660       else if (operands[2] == const1_rtx
10661                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10662         {
10663           if (get_attr_mode (insn) == MODE_SI)
10664             return "sal{l}\t%0";
10665           else
10666             return "sal{b}\t%0";
10667         }
10668       else
10669         {
10670           if (get_attr_mode (insn) == MODE_SI)
10671             return "sal{l}\t{%2, %k0|%k0, %2}";
10672           else
10673             return "sal{b}\t{%2, %0|%0, %2}";
10674         }
10675     }
10676 }
10677   [(set (attr "type")
10678      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679                           (const_int 0))
10680                       (match_operand 0 "register_operand" ""))
10681                  (match_operand 2 "const1_operand" ""))
10682               (const_string "alu")
10683            ]
10684            (const_string "ishift")))
10685    (set (attr "length_immediate")
10686      (if_then_else
10687        (ior (eq_attr "type" "alu")
10688             (and (eq_attr "type" "ishift")
10689                  (and (match_operand 2 "const1_operand" "")
10690                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10691                           (const_int 0)))))
10692        (const_string "0")
10693        (const_string "*")))
10694    (set_attr "mode" "QI,SI")])
10695
10696 ;; This pattern can't accept a variable shift count, since shifts by
10697 ;; zero don't affect the flags.  We assume that shifts by constant
10698 ;; zero are optimized away.
10699 (define_insn "*ashlqi3_cmp"
10700   [(set (reg FLAGS_REG)
10701         (compare
10702           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10703                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10704           (const_int 0)))
10705    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10706         (ashift:QI (match_dup 1) (match_dup 2)))]
10707   "(optimize_function_for_size_p (cfun)
10708     || !TARGET_PARTIAL_FLAG_REG_STALL
10709     || (operands[2] == const1_rtx
10710         && (TARGET_SHIFT1
10711             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10712    && ix86_match_ccmode (insn, CCGOCmode)
10713    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10714 {
10715   switch (get_attr_type (insn))
10716     {
10717     case TYPE_ALU:
10718       gcc_assert (operands[2] == const1_rtx);
10719       return "add{b}\t%0, %0";
10720
10721     default:
10722       if (REG_P (operands[2]))
10723         return "sal{b}\t{%b2, %0|%0, %b2}";
10724       else if (operands[2] == const1_rtx
10725                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10726         return "sal{b}\t%0";
10727       else
10728         return "sal{b}\t{%2, %0|%0, %2}";
10729     }
10730 }
10731   [(set (attr "type")
10732      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10733                           (const_int 0))
10734                       (match_operand 0 "register_operand" ""))
10735                  (match_operand 2 "const1_operand" ""))
10736               (const_string "alu")
10737            ]
10738            (const_string "ishift")))
10739    (set (attr "length_immediate")
10740      (if_then_else
10741        (ior (eq_attr "type" "alu")
10742             (and (eq_attr "type" "ishift")
10743                  (and (match_operand 2 "const1_operand" "")
10744                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10745                           (const_int 0)))))
10746        (const_string "0")
10747        (const_string "*")))
10748    (set_attr "mode" "QI")])
10749
10750 (define_insn "*ashlqi3_cconly"
10751   [(set (reg FLAGS_REG)
10752         (compare
10753           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10754                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10755           (const_int 0)))
10756    (clobber (match_scratch:QI 0 "=q"))]
10757   "(optimize_function_for_size_p (cfun)
10758     || !TARGET_PARTIAL_FLAG_REG_STALL
10759     || (operands[2] == const1_rtx
10760         && (TARGET_SHIFT1
10761             || TARGET_DOUBLE_WITH_ADD)))
10762    && ix86_match_ccmode (insn, CCGOCmode)
10763    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10764 {
10765   switch (get_attr_type (insn))
10766     {
10767     case TYPE_ALU:
10768       gcc_assert (operands[2] == const1_rtx);
10769       return "add{b}\t%0, %0";
10770
10771     default:
10772       if (REG_P (operands[2]))
10773         return "sal{b}\t{%b2, %0|%0, %b2}";
10774       else if (operands[2] == const1_rtx
10775                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10776         return "sal{b}\t%0";
10777       else
10778         return "sal{b}\t{%2, %0|%0, %2}";
10779     }
10780 }
10781   [(set (attr "type")
10782      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10783                           (const_int 0))
10784                       (match_operand 0 "register_operand" ""))
10785                  (match_operand 2 "const1_operand" ""))
10786               (const_string "alu")
10787            ]
10788            (const_string "ishift")))
10789    (set (attr "length_immediate")
10790      (if_then_else
10791        (ior (eq_attr "type" "alu")
10792             (and (eq_attr "type" "ishift")
10793                  (and (match_operand 2 "const1_operand" "")
10794                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10795                           (const_int 0)))))
10796        (const_string "0")
10797        (const_string "*")))
10798    (set_attr "mode" "QI")])
10799
10800 ;; See comment above `ashldi3' about how this works.
10801
10802 (define_expand "ashrti3"
10803   [(set (match_operand:TI 0 "register_operand" "")
10804         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10805                      (match_operand:QI 2 "nonmemory_operand" "")))]
10806   "TARGET_64BIT"
10807   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10808
10809 (define_insn "*ashrti3_1"
10810   [(set (match_operand:TI 0 "register_operand" "=r")
10811         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10812                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
10813    (clobber (reg:CC FLAGS_REG))]
10814   "TARGET_64BIT"
10815   "#"
10816   [(set_attr "type" "multi")])
10817
10818 (define_peephole2
10819   [(match_scratch:DI 3 "r")
10820    (parallel [(set (match_operand:TI 0 "register_operand" "")
10821                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10822                                 (match_operand:QI 2 "nonmemory_operand" "")))
10823               (clobber (reg:CC FLAGS_REG))])
10824    (match_dup 3)]
10825   "TARGET_64BIT"
10826   [(const_int 0)]
10827   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10828
10829 (define_split
10830   [(set (match_operand:TI 0 "register_operand" "")
10831         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10832                      (match_operand:QI 2 "nonmemory_operand" "")))
10833    (clobber (reg:CC FLAGS_REG))]
10834   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10835                     ? epilogue_completed : reload_completed)"
10836   [(const_int 0)]
10837   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10838
10839 (define_insn "x86_64_shrd"
10840   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10841         (ior:DI (ashiftrt:DI (match_dup 0)
10842                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10843                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10844                   (minus:QI (const_int 64) (match_dup 2)))))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "TARGET_64BIT"
10847   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10848   [(set_attr "type" "ishift")
10849    (set_attr "prefix_0f" "1")
10850    (set_attr "mode" "DI")
10851    (set_attr "athlon_decode" "vector")
10852    (set_attr "amdfam10_decode" "vector")])
10853
10854 (define_expand "ashrdi3"
10855   [(set (match_operand:DI 0 "shiftdi_operand" "")
10856         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10857                      (match_operand:QI 2 "nonmemory_operand" "")))]
10858   ""
10859   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10860
10861 (define_expand "x86_64_shift_adj_3"
10862   [(use (match_operand:DI 0 "register_operand" ""))
10863    (use (match_operand:DI 1 "register_operand" ""))
10864    (use (match_operand:QI 2 "register_operand" ""))]
10865   ""
10866 {
10867   rtx label = gen_label_rtx ();
10868   rtx tmp;
10869
10870   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10871
10872   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10873   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10874   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10875                               gen_rtx_LABEL_REF (VOIDmode, label),
10876                               pc_rtx);
10877   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10878   JUMP_LABEL (tmp) = label;
10879
10880   emit_move_insn (operands[0], operands[1]);
10881   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10882
10883   emit_label (label);
10884   LABEL_NUSES (label) = 1;
10885
10886   DONE;
10887 })
10888
10889 (define_insn "ashrdi3_63_rex64"
10890   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10891         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10892                      (match_operand:DI 2 "const_int_operand" "i,i")))
10893    (clobber (reg:CC FLAGS_REG))]
10894   "TARGET_64BIT && INTVAL (operands[2]) == 63
10895    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10896    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10897   "@
10898    {cqto|cqo}
10899    sar{q}\t{%2, %0|%0, %2}"
10900   [(set_attr "type" "imovx,ishift")
10901    (set_attr "prefix_0f" "0,*")
10902    (set_attr "length_immediate" "0,*")
10903    (set_attr "modrm" "0,1")
10904    (set_attr "mode" "DI")])
10905
10906 (define_insn "*ashrdi3_1_one_bit_rex64"
10907   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10908         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10909                      (match_operand:QI 2 "const1_operand" "")))
10910    (clobber (reg:CC FLAGS_REG))]
10911   "TARGET_64BIT
10912    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10913    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10914   "sar{q}\t%0"
10915   [(set_attr "type" "ishift")
10916    (set_attr "length_immediate" "0")
10917    (set_attr "mode" "DI")])
10918
10919 (define_insn "*ashrdi3_1_rex64"
10920   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10921         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10922                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10923    (clobber (reg:CC FLAGS_REG))]
10924   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10925   "@
10926    sar{q}\t{%2, %0|%0, %2}
10927    sar{q}\t{%b2, %0|%0, %b2}"
10928   [(set_attr "type" "ishift")
10929    (set_attr "mode" "DI")])
10930
10931 ;; This pattern can't accept a variable shift count, since shifts by
10932 ;; zero don't affect the flags.  We assume that shifts by constant
10933 ;; zero are optimized away.
10934 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10935   [(set (reg FLAGS_REG)
10936         (compare
10937           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10938                        (match_operand:QI 2 "const1_operand" ""))
10939           (const_int 0)))
10940    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10941         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10942   "TARGET_64BIT
10943    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10944    && ix86_match_ccmode (insn, CCGOCmode)
10945    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10946   "sar{q}\t%0"
10947   [(set_attr "type" "ishift")
10948    (set_attr "length_immediate" "0")
10949    (set_attr "mode" "DI")])
10950
10951 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10952   [(set (reg FLAGS_REG)
10953         (compare
10954           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10955                        (match_operand:QI 2 "const1_operand" ""))
10956           (const_int 0)))
10957    (clobber (match_scratch:DI 0 "=r"))]
10958   "TARGET_64BIT
10959    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10960    && ix86_match_ccmode (insn, CCGOCmode)
10961    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10962   "sar{q}\t%0"
10963   [(set_attr "type" "ishift")
10964    (set_attr "length_immediate" "0")
10965    (set_attr "mode" "DI")])
10966
10967 ;; This pattern can't accept a variable shift count, since shifts by
10968 ;; zero don't affect the flags.  We assume that shifts by constant
10969 ;; zero are optimized away.
10970 (define_insn "*ashrdi3_cmp_rex64"
10971   [(set (reg FLAGS_REG)
10972         (compare
10973           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10974                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10975           (const_int 0)))
10976    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10977         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10978   "TARGET_64BIT
10979    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10980    && ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10982   "sar{q}\t{%2, %0|%0, %2}"
10983   [(set_attr "type" "ishift")
10984    (set_attr "mode" "DI")])
10985
10986 (define_insn "*ashrdi3_cconly_rex64"
10987   [(set (reg FLAGS_REG)
10988         (compare
10989           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10990                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10991           (const_int 0)))
10992    (clobber (match_scratch:DI 0 "=r"))]
10993   "TARGET_64BIT
10994    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10995    && ix86_match_ccmode (insn, CCGOCmode)
10996    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10997   "sar{q}\t{%2, %0|%0, %2}"
10998   [(set_attr "type" "ishift")
10999    (set_attr "mode" "DI")])
11000
11001 (define_insn "*ashrdi3_1"
11002   [(set (match_operand:DI 0 "register_operand" "=r")
11003         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11004                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "!TARGET_64BIT"
11007   "#"
11008   [(set_attr "type" "multi")])
11009
11010 ;; By default we don't ask for a scratch register, because when DImode
11011 ;; values are manipulated, registers are already at a premium.  But if
11012 ;; we have one handy, we won't turn it away.
11013 (define_peephole2
11014   [(match_scratch:SI 3 "r")
11015    (parallel [(set (match_operand:DI 0 "register_operand" "")
11016                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11017                                 (match_operand:QI 2 "nonmemory_operand" "")))
11018               (clobber (reg:CC FLAGS_REG))])
11019    (match_dup 3)]
11020   "!TARGET_64BIT && TARGET_CMOVE"
11021   [(const_int 0)]
11022   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11023
11024 (define_split
11025   [(set (match_operand:DI 0 "register_operand" "")
11026         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11027                      (match_operand:QI 2 "nonmemory_operand" "")))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11030                      ? epilogue_completed : reload_completed)"
11031   [(const_int 0)]
11032   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11033
11034 (define_insn "x86_shrd"
11035   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11036         (ior:SI (ashiftrt:SI (match_dup 0)
11037                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11038                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11039                   (minus:QI (const_int 32) (match_dup 2)))))
11040    (clobber (reg:CC FLAGS_REG))]
11041   ""
11042   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11043   [(set_attr "type" "ishift")
11044    (set_attr "prefix_0f" "1")
11045    (set_attr "pent_pair" "np")
11046    (set_attr "mode" "SI")])
11047
11048 (define_expand "x86_shift_adj_3"
11049   [(use (match_operand:SI 0 "register_operand" ""))
11050    (use (match_operand:SI 1 "register_operand" ""))
11051    (use (match_operand:QI 2 "register_operand" ""))]
11052   ""
11053 {
11054   rtx label = gen_label_rtx ();
11055   rtx tmp;
11056
11057   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11058
11059   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11060   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11061   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11062                               gen_rtx_LABEL_REF (VOIDmode, label),
11063                               pc_rtx);
11064   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11065   JUMP_LABEL (tmp) = label;
11066
11067   emit_move_insn (operands[0], operands[1]);
11068   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11069
11070   emit_label (label);
11071   LABEL_NUSES (label) = 1;
11072
11073   DONE;
11074 })
11075
11076 (define_expand "ashrsi3_31"
11077   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11078                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11079                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11080               (clobber (reg:CC FLAGS_REG))])]
11081   "")
11082
11083 (define_insn "*ashrsi3_31"
11084   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11085         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11086                      (match_operand:SI 2 "const_int_operand" "i,i")))
11087    (clobber (reg:CC FLAGS_REG))]
11088   "INTVAL (operands[2]) == 31
11089    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11090    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11091   "@
11092    {cltd|cdq}
11093    sar{l}\t{%2, %0|%0, %2}"
11094   [(set_attr "type" "imovx,ishift")
11095    (set_attr "prefix_0f" "0,*")
11096    (set_attr "length_immediate" "0,*")
11097    (set_attr "modrm" "0,1")
11098    (set_attr "mode" "SI")])
11099
11100 (define_insn "*ashrsi3_31_zext"
11101   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11102         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11103                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11106    && INTVAL (operands[2]) == 31
11107    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11108   "@
11109    {cltd|cdq}
11110    sar{l}\t{%2, %k0|%k0, %2}"
11111   [(set_attr "type" "imovx,ishift")
11112    (set_attr "prefix_0f" "0,*")
11113    (set_attr "length_immediate" "0,*")
11114    (set_attr "modrm" "0,1")
11115    (set_attr "mode" "SI")])
11116
11117 (define_expand "ashrsi3"
11118   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11119         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11120                      (match_operand:QI 2 "nonmemory_operand" "")))]
11121   ""
11122   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11123
11124 (define_insn "*ashrsi3_1_one_bit"
11125   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11126         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11127                      (match_operand:QI 2 "const1_operand" "")))
11128    (clobber (reg:CC FLAGS_REG))]
11129   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11130    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11131   "sar{l}\t%0"
11132   [(set_attr "type" "ishift")
11133    (set_attr "length_immediate" "0")
11134    (set_attr "mode" "SI")])
11135
11136 (define_insn "*ashrsi3_1_one_bit_zext"
11137   [(set (match_operand:DI 0 "register_operand" "=r")
11138         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11139                                      (match_operand:QI 2 "const1_operand" ""))))
11140    (clobber (reg:CC FLAGS_REG))]
11141   "TARGET_64BIT
11142    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11143    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11144   "sar{l}\t%k0"
11145   [(set_attr "type" "ishift")
11146    (set_attr "length_immediate" "0")
11147    (set_attr "mode" "SI")])
11148
11149 (define_insn "*ashrsi3_1"
11150   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11151         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11152                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11155   "@
11156    sar{l}\t{%2, %0|%0, %2}
11157    sar{l}\t{%b2, %0|%0, %b2}"
11158   [(set_attr "type" "ishift")
11159    (set_attr "mode" "SI")])
11160
11161 (define_insn "*ashrsi3_1_zext"
11162   [(set (match_operand:DI 0 "register_operand" "=r,r")
11163         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11164                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11165    (clobber (reg:CC FLAGS_REG))]
11166   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11167   "@
11168    sar{l}\t{%2, %k0|%k0, %2}
11169    sar{l}\t{%b2, %k0|%k0, %b2}"
11170   [(set_attr "type" "ishift")
11171    (set_attr "mode" "SI")])
11172
11173 ;; This pattern can't accept a variable shift count, since shifts by
11174 ;; zero don't affect the flags.  We assume that shifts by constant
11175 ;; zero are optimized away.
11176 (define_insn "*ashrsi3_one_bit_cmp"
11177   [(set (reg FLAGS_REG)
11178         (compare
11179           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11180                        (match_operand:QI 2 "const1_operand" ""))
11181           (const_int 0)))
11182    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11183         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11184   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11185    && ix86_match_ccmode (insn, CCGOCmode)
11186    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11187   "sar{l}\t%0"
11188   [(set_attr "type" "ishift")
11189    (set_attr "length_immediate" "0")
11190    (set_attr "mode" "SI")])
11191
11192 (define_insn "*ashrsi3_one_bit_cconly"
11193   [(set (reg FLAGS_REG)
11194         (compare
11195           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11196                        (match_operand:QI 2 "const1_operand" ""))
11197           (const_int 0)))
11198    (clobber (match_scratch:SI 0 "=r"))]
11199   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11200    && ix86_match_ccmode (insn, CCGOCmode)
11201    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11202   "sar{l}\t%0"
11203   [(set_attr "type" "ishift")
11204    (set_attr "length_immediate" "0")
11205    (set_attr "mode" "SI")])
11206
11207 (define_insn "*ashrsi3_one_bit_cmp_zext"
11208   [(set (reg FLAGS_REG)
11209         (compare
11210           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11211                        (match_operand:QI 2 "const1_operand" ""))
11212           (const_int 0)))
11213    (set (match_operand:DI 0 "register_operand" "=r")
11214         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11215   "TARGET_64BIT
11216    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11217    && ix86_match_ccmode (insn, CCmode)
11218    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11219   "sar{l}\t%k0"
11220   [(set_attr "type" "ishift")
11221    (set_attr "length_immediate" "0")
11222    (set_attr "mode" "SI")])
11223
11224 ;; This pattern can't accept a variable shift count, since shifts by
11225 ;; zero don't affect the flags.  We assume that shifts by constant
11226 ;; zero are optimized away.
11227 (define_insn "*ashrsi3_cmp"
11228   [(set (reg FLAGS_REG)
11229         (compare
11230           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11231                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11232           (const_int 0)))
11233    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11234         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11235   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11236    && ix86_match_ccmode (insn, CCGOCmode)
11237    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11238   "sar{l}\t{%2, %0|%0, %2}"
11239   [(set_attr "type" "ishift")
11240    (set_attr "mode" "SI")])
11241
11242 (define_insn "*ashrsi3_cconly"
11243   [(set (reg FLAGS_REG)
11244         (compare
11245           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11246                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11247           (const_int 0)))
11248    (clobber (match_scratch:SI 0 "=r"))]
11249   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11250    && ix86_match_ccmode (insn, CCGOCmode)
11251    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11252   "sar{l}\t{%2, %0|%0, %2}"
11253   [(set_attr "type" "ishift")
11254    (set_attr "mode" "SI")])
11255
11256 (define_insn "*ashrsi3_cmp_zext"
11257   [(set (reg FLAGS_REG)
11258         (compare
11259           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11260                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11261           (const_int 0)))
11262    (set (match_operand:DI 0 "register_operand" "=r")
11263         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11264   "TARGET_64BIT
11265    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11266    && ix86_match_ccmode (insn, CCGOCmode)
11267    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11268   "sar{l}\t{%2, %k0|%k0, %2}"
11269   [(set_attr "type" "ishift")
11270    (set_attr "mode" "SI")])
11271
11272 (define_expand "ashrhi3"
11273   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11274         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11275                      (match_operand:QI 2 "nonmemory_operand" "")))]
11276   "TARGET_HIMODE_MATH"
11277   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11278
11279 (define_insn "*ashrhi3_1_one_bit"
11280   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11281         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11282                      (match_operand:QI 2 "const1_operand" "")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11285    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11286   "sar{w}\t%0"
11287   [(set_attr "type" "ishift")
11288    (set_attr "length_immediate" "0")
11289    (set_attr "mode" "HI")])
11290
11291 (define_insn "*ashrhi3_1"
11292   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11293         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11294                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11295    (clobber (reg:CC FLAGS_REG))]
11296   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11297   "@
11298    sar{w}\t{%2, %0|%0, %2}
11299    sar{w}\t{%b2, %0|%0, %b2}"
11300   [(set_attr "type" "ishift")
11301    (set_attr "mode" "HI")])
11302
11303 ;; This pattern can't accept a variable shift count, since shifts by
11304 ;; zero don't affect the flags.  We assume that shifts by constant
11305 ;; zero are optimized away.
11306 (define_insn "*ashrhi3_one_bit_cmp"
11307   [(set (reg FLAGS_REG)
11308         (compare
11309           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11310                        (match_operand:QI 2 "const1_operand" ""))
11311           (const_int 0)))
11312    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11313         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11314   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11315    && ix86_match_ccmode (insn, CCGOCmode)
11316    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11317   "sar{w}\t%0"
11318   [(set_attr "type" "ishift")
11319    (set_attr "length_immediate" "0")
11320    (set_attr "mode" "HI")])
11321
11322 (define_insn "*ashrhi3_one_bit_cconly"
11323   [(set (reg FLAGS_REG)
11324         (compare
11325           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11326                        (match_operand:QI 2 "const1_operand" ""))
11327           (const_int 0)))
11328    (clobber (match_scratch:HI 0 "=r"))]
11329   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11330    && ix86_match_ccmode (insn, CCGOCmode)
11331    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11332   "sar{w}\t%0"
11333   [(set_attr "type" "ishift")
11334    (set_attr "length_immediate" "0")
11335    (set_attr "mode" "HI")])
11336
11337 ;; This pattern can't accept a variable shift count, since shifts by
11338 ;; zero don't affect the flags.  We assume that shifts by constant
11339 ;; zero are optimized away.
11340 (define_insn "*ashrhi3_cmp"
11341   [(set (reg FLAGS_REG)
11342         (compare
11343           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11344                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11345           (const_int 0)))
11346    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11347         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11348   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11349    && ix86_match_ccmode (insn, CCGOCmode)
11350    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11351   "sar{w}\t{%2, %0|%0, %2}"
11352   [(set_attr "type" "ishift")
11353    (set_attr "mode" "HI")])
11354
11355 (define_insn "*ashrhi3_cconly"
11356   [(set (reg FLAGS_REG)
11357         (compare
11358           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11359                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11360           (const_int 0)))
11361    (clobber (match_scratch:HI 0 "=r"))]
11362   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11363    && ix86_match_ccmode (insn, CCGOCmode)
11364    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11365   "sar{w}\t{%2, %0|%0, %2}"
11366   [(set_attr "type" "ishift")
11367    (set_attr "mode" "HI")])
11368
11369 (define_expand "ashrqi3"
11370   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11371         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11372                      (match_operand:QI 2 "nonmemory_operand" "")))]
11373   "TARGET_QIMODE_MATH"
11374   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11375
11376 (define_insn "*ashrqi3_1_one_bit"
11377   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11378         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11379                      (match_operand:QI 2 "const1_operand" "")))
11380    (clobber (reg:CC FLAGS_REG))]
11381   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11382    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11383   "sar{b}\t%0"
11384   [(set_attr "type" "ishift")
11385    (set_attr "length_immediate" "0")
11386    (set_attr "mode" "QI")])
11387
11388 (define_insn "*ashrqi3_1_one_bit_slp"
11389   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11390         (ashiftrt:QI (match_dup 0)
11391                      (match_operand:QI 1 "const1_operand" "")))
11392    (clobber (reg:CC FLAGS_REG))]
11393   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11394    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11395    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11396   "sar{b}\t%0"
11397   [(set_attr "type" "ishift1")
11398    (set_attr "length_immediate" "0")
11399    (set_attr "mode" "QI")])
11400
11401 (define_insn "*ashrqi3_1"
11402   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11403         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11404                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11407   "@
11408    sar{b}\t{%2, %0|%0, %2}
11409    sar{b}\t{%b2, %0|%0, %b2}"
11410   [(set_attr "type" "ishift")
11411    (set_attr "mode" "QI")])
11412
11413 (define_insn "*ashrqi3_1_slp"
11414   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11415         (ashiftrt:QI (match_dup 0)
11416                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11417    (clobber (reg:CC FLAGS_REG))]
11418   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11419    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11420   "@
11421    sar{b}\t{%1, %0|%0, %1}
11422    sar{b}\t{%b1, %0|%0, %b1}"
11423   [(set_attr "type" "ishift1")
11424    (set_attr "mode" "QI")])
11425
11426 ;; This pattern can't accept a variable shift count, since shifts by
11427 ;; zero don't affect the flags.  We assume that shifts by constant
11428 ;; zero are optimized away.
11429 (define_insn "*ashrqi3_one_bit_cmp"
11430   [(set (reg FLAGS_REG)
11431         (compare
11432           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11433                        (match_operand:QI 2 "const1_operand" "I"))
11434           (const_int 0)))
11435    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11436         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11437   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11438    && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11440   "sar{b}\t%0"
11441   [(set_attr "type" "ishift")
11442    (set_attr "length_immediate" "0")
11443    (set_attr "mode" "QI")])
11444
11445 (define_insn "*ashrqi3_one_bit_cconly"
11446   [(set (reg FLAGS_REG)
11447         (compare
11448           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11449                        (match_operand:QI 2 "const1_operand" ""))
11450           (const_int 0)))
11451    (clobber (match_scratch:QI 0 "=q"))]
11452   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11453    && ix86_match_ccmode (insn, CCGOCmode)
11454    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11455   "sar{b}\t%0"
11456   [(set_attr "type" "ishift")
11457    (set_attr "length_immediate" "0")
11458    (set_attr "mode" "QI")])
11459
11460 ;; This pattern can't accept a variable shift count, since shifts by
11461 ;; zero don't affect the flags.  We assume that shifts by constant
11462 ;; zero are optimized away.
11463 (define_insn "*ashrqi3_cmp"
11464   [(set (reg FLAGS_REG)
11465         (compare
11466           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11467                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11468           (const_int 0)))
11469    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11470         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11471   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11472    && ix86_match_ccmode (insn, CCGOCmode)
11473    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11474   "sar{b}\t{%2, %0|%0, %2}"
11475   [(set_attr "type" "ishift")
11476    (set_attr "mode" "QI")])
11477
11478 (define_insn "*ashrqi3_cconly"
11479   [(set (reg FLAGS_REG)
11480         (compare
11481           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11482                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11483           (const_int 0)))
11484    (clobber (match_scratch:QI 0 "=q"))]
11485   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11486    && ix86_match_ccmode (insn, CCGOCmode)
11487    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11488   "sar{b}\t{%2, %0|%0, %2}"
11489   [(set_attr "type" "ishift")
11490    (set_attr "mode" "QI")])
11491
11492 \f
11493 ;; Logical shift instructions
11494
11495 ;; See comment above `ashldi3' about how this works.
11496
11497 (define_expand "lshrti3"
11498   [(set (match_operand:TI 0 "register_operand" "")
11499         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11500                      (match_operand:QI 2 "nonmemory_operand" "")))]
11501   "TARGET_64BIT"
11502   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11503
11504 (define_insn "*lshrti3_1"
11505   [(set (match_operand:TI 0 "register_operand" "=r")
11506         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11507                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "TARGET_64BIT"
11510   "#"
11511   [(set_attr "type" "multi")])
11512
11513 (define_peephole2
11514   [(match_scratch:DI 3 "r")
11515    (parallel [(set (match_operand:TI 0 "register_operand" "")
11516                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11517                                 (match_operand:QI 2 "nonmemory_operand" "")))
11518               (clobber (reg:CC FLAGS_REG))])
11519    (match_dup 3)]
11520   "TARGET_64BIT"
11521   [(const_int 0)]
11522   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11523
11524 (define_split
11525   [(set (match_operand:TI 0 "register_operand" "")
11526         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11527                      (match_operand:QI 2 "nonmemory_operand" "")))
11528    (clobber (reg:CC FLAGS_REG))]
11529   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11530                     ? epilogue_completed : reload_completed)"
11531   [(const_int 0)]
11532   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11533
11534 (define_expand "lshrdi3"
11535   [(set (match_operand:DI 0 "shiftdi_operand" "")
11536         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11537                      (match_operand:QI 2 "nonmemory_operand" "")))]
11538   ""
11539   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11540
11541 (define_insn "*lshrdi3_1_one_bit_rex64"
11542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11543         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11544                      (match_operand:QI 2 "const1_operand" "")))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT
11547    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11548    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11549   "shr{q}\t%0"
11550   [(set_attr "type" "ishift")
11551    (set_attr "length_immediate" "0")
11552    (set_attr "mode" "DI")])
11553
11554 (define_insn "*lshrdi3_1_rex64"
11555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11556         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11557                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11558    (clobber (reg:CC FLAGS_REG))]
11559   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11560   "@
11561    shr{q}\t{%2, %0|%0, %2}
11562    shr{q}\t{%b2, %0|%0, %b2}"
11563   [(set_attr "type" "ishift")
11564    (set_attr "mode" "DI")])
11565
11566 ;; This pattern can't accept a variable shift count, since shifts by
11567 ;; zero don't affect the flags.  We assume that shifts by constant
11568 ;; zero are optimized away.
11569 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11570   [(set (reg FLAGS_REG)
11571         (compare
11572           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11573                        (match_operand:QI 2 "const1_operand" ""))
11574           (const_int 0)))
11575    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11576         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11577   "TARGET_64BIT
11578    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11579    && ix86_match_ccmode (insn, CCGOCmode)
11580    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11581   "shr{q}\t%0"
11582   [(set_attr "type" "ishift")
11583    (set_attr "length_immediate" "0")
11584    (set_attr "mode" "DI")])
11585
11586 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11587   [(set (reg FLAGS_REG)
11588         (compare
11589           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11590                        (match_operand:QI 2 "const1_operand" ""))
11591           (const_int 0)))
11592    (clobber (match_scratch:DI 0 "=r"))]
11593   "TARGET_64BIT
11594    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11595    && ix86_match_ccmode (insn, CCGOCmode)
11596    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11597   "shr{q}\t%0"
11598   [(set_attr "type" "ishift")
11599    (set_attr "length_immediate" "0")
11600    (set_attr "mode" "DI")])
11601
11602 ;; This pattern can't accept a variable shift count, since shifts by
11603 ;; zero don't affect the flags.  We assume that shifts by constant
11604 ;; zero are optimized away.
11605 (define_insn "*lshrdi3_cmp_rex64"
11606   [(set (reg FLAGS_REG)
11607         (compare
11608           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11609                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11610           (const_int 0)))
11611    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11612         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11613   "TARGET_64BIT
11614    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11615    && ix86_match_ccmode (insn, CCGOCmode)
11616    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11617   "shr{q}\t{%2, %0|%0, %2}"
11618   [(set_attr "type" "ishift")
11619    (set_attr "mode" "DI")])
11620
11621 (define_insn "*lshrdi3_cconly_rex64"
11622   [(set (reg FLAGS_REG)
11623         (compare
11624           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11625                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11626           (const_int 0)))
11627    (clobber (match_scratch:DI 0 "=r"))]
11628   "TARGET_64BIT
11629    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11630    && ix86_match_ccmode (insn, CCGOCmode)
11631    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11632   "shr{q}\t{%2, %0|%0, %2}"
11633   [(set_attr "type" "ishift")
11634    (set_attr "mode" "DI")])
11635
11636 (define_insn "*lshrdi3_1"
11637   [(set (match_operand:DI 0 "register_operand" "=r")
11638         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11639                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "!TARGET_64BIT"
11642   "#"
11643   [(set_attr "type" "multi")])
11644
11645 ;; By default we don't ask for a scratch register, because when DImode
11646 ;; values are manipulated, registers are already at a premium.  But if
11647 ;; we have one handy, we won't turn it away.
11648 (define_peephole2
11649   [(match_scratch:SI 3 "r")
11650    (parallel [(set (match_operand:DI 0 "register_operand" "")
11651                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11652                                 (match_operand:QI 2 "nonmemory_operand" "")))
11653               (clobber (reg:CC FLAGS_REG))])
11654    (match_dup 3)]
11655   "!TARGET_64BIT && TARGET_CMOVE"
11656   [(const_int 0)]
11657   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11658
11659 (define_split
11660   [(set (match_operand:DI 0 "register_operand" "")
11661         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11662                      (match_operand:QI 2 "nonmemory_operand" "")))
11663    (clobber (reg:CC FLAGS_REG))]
11664   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11665                      ? epilogue_completed : reload_completed)"
11666   [(const_int 0)]
11667   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11668
11669 (define_expand "lshrsi3"
11670   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11671         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11672                      (match_operand:QI 2 "nonmemory_operand" "")))]
11673   ""
11674   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11675
11676 (define_insn "*lshrsi3_1_one_bit"
11677   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11678         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679                      (match_operand:QI 2 "const1_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11682    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11683   "shr{l}\t%0"
11684   [(set_attr "type" "ishift")
11685    (set_attr "length_immediate" "0")
11686    (set_attr "mode" "SI")])
11687
11688 (define_insn "*lshrsi3_1_one_bit_zext"
11689   [(set (match_operand:DI 0 "register_operand" "=r")
11690         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11691                      (match_operand:QI 2 "const1_operand" "")))
11692    (clobber (reg:CC FLAGS_REG))]
11693   "TARGET_64BIT
11694    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11695    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11696   "shr{l}\t%k0"
11697   [(set_attr "type" "ishift")
11698    (set_attr "length_immediate" "0")
11699    (set_attr "mode" "SI")])
11700
11701 (define_insn "*lshrsi3_1"
11702   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11703         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11704                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11705    (clobber (reg:CC FLAGS_REG))]
11706   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11707   "@
11708    shr{l}\t{%2, %0|%0, %2}
11709    shr{l}\t{%b2, %0|%0, %b2}"
11710   [(set_attr "type" "ishift")
11711    (set_attr "mode" "SI")])
11712
11713 (define_insn "*lshrsi3_1_zext"
11714   [(set (match_operand:DI 0 "register_operand" "=r,r")
11715         (zero_extend:DI
11716           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11717                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11718    (clobber (reg:CC FLAGS_REG))]
11719   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11720   "@
11721    shr{l}\t{%2, %k0|%k0, %2}
11722    shr{l}\t{%b2, %k0|%k0, %b2}"
11723   [(set_attr "type" "ishift")
11724    (set_attr "mode" "SI")])
11725
11726 ;; This pattern can't accept a variable shift count, since shifts by
11727 ;; zero don't affect the flags.  We assume that shifts by constant
11728 ;; zero are optimized away.
11729 (define_insn "*lshrsi3_one_bit_cmp"
11730   [(set (reg FLAGS_REG)
11731         (compare
11732           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11733                        (match_operand:QI 2 "const1_operand" ""))
11734           (const_int 0)))
11735    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11736         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11737   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11738    && ix86_match_ccmode (insn, CCGOCmode)
11739    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11740   "shr{l}\t%0"
11741   [(set_attr "type" "ishift")
11742    (set_attr "length_immediate" "0")
11743    (set_attr "mode" "SI")])
11744
11745 (define_insn "*lshrsi3_one_bit_cconly"
11746   [(set (reg FLAGS_REG)
11747         (compare
11748           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11749                        (match_operand:QI 2 "const1_operand" ""))
11750           (const_int 0)))
11751    (clobber (match_scratch:SI 0 "=r"))]
11752   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11753    && ix86_match_ccmode (insn, CCGOCmode)
11754    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11755   "shr{l}\t%0"
11756   [(set_attr "type" "ishift")
11757    (set_attr "length_immediate" "0")
11758    (set_attr "mode" "SI")])
11759
11760 (define_insn "*lshrsi3_cmp_one_bit_zext"
11761   [(set (reg FLAGS_REG)
11762         (compare
11763           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11764                        (match_operand:QI 2 "const1_operand" ""))
11765           (const_int 0)))
11766    (set (match_operand:DI 0 "register_operand" "=r")
11767         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11768   "TARGET_64BIT
11769    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11770    && ix86_match_ccmode (insn, CCGOCmode)
11771    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11772   "shr{l}\t%k0"
11773   [(set_attr "type" "ishift")
11774    (set_attr "length_immediate" "0")
11775    (set_attr "mode" "SI")])
11776
11777 ;; This pattern can't accept a variable shift count, since shifts by
11778 ;; zero don't affect the flags.  We assume that shifts by constant
11779 ;; zero are optimized away.
11780 (define_insn "*lshrsi3_cmp"
11781   [(set (reg FLAGS_REG)
11782         (compare
11783           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11784                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11785           (const_int 0)))
11786    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11787         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11788   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11789    && ix86_match_ccmode (insn, CCGOCmode)
11790    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11791   "shr{l}\t{%2, %0|%0, %2}"
11792   [(set_attr "type" "ishift")
11793    (set_attr "mode" "SI")])
11794
11795 (define_insn "*lshrsi3_cconly"
11796   [(set (reg FLAGS_REG)
11797       (compare
11798         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11799                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800         (const_int 0)))
11801    (clobber (match_scratch:SI 0 "=r"))]
11802   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11803    && ix86_match_ccmode (insn, CCGOCmode)
11804    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11805   "shr{l}\t{%2, %0|%0, %2}"
11806   [(set_attr "type" "ishift")
11807    (set_attr "mode" "SI")])
11808
11809 (define_insn "*lshrsi3_cmp_zext"
11810   [(set (reg FLAGS_REG)
11811         (compare
11812           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11813                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11814           (const_int 0)))
11815    (set (match_operand:DI 0 "register_operand" "=r")
11816         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11817   "TARGET_64BIT
11818    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11819    && ix86_match_ccmode (insn, CCGOCmode)
11820    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11821   "shr{l}\t{%2, %k0|%k0, %2}"
11822   [(set_attr "type" "ishift")
11823    (set_attr "mode" "SI")])
11824
11825 (define_expand "lshrhi3"
11826   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11827         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11828                      (match_operand:QI 2 "nonmemory_operand" "")))]
11829   "TARGET_HIMODE_MATH"
11830   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11831
11832 (define_insn "*lshrhi3_1_one_bit"
11833   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11834         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11835                      (match_operand:QI 2 "const1_operand" "")))
11836    (clobber (reg:CC FLAGS_REG))]
11837   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11838    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11839   "shr{w}\t%0"
11840   [(set_attr "type" "ishift")
11841    (set_attr "length_immediate" "0")
11842    (set_attr "mode" "HI")])
11843
11844 (define_insn "*lshrhi3_1"
11845   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11846         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11847                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11848    (clobber (reg:CC FLAGS_REG))]
11849   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11850   "@
11851    shr{w}\t{%2, %0|%0, %2}
11852    shr{w}\t{%b2, %0|%0, %b2}"
11853   [(set_attr "type" "ishift")
11854    (set_attr "mode" "HI")])
11855
11856 ;; This pattern can't accept a variable shift count, since shifts by
11857 ;; zero don't affect the flags.  We assume that shifts by constant
11858 ;; zero are optimized away.
11859 (define_insn "*lshrhi3_one_bit_cmp"
11860   [(set (reg FLAGS_REG)
11861         (compare
11862           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863                        (match_operand:QI 2 "const1_operand" ""))
11864           (const_int 0)))
11865    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11866         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11867   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11868    && ix86_match_ccmode (insn, CCGOCmode)
11869    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11870   "shr{w}\t%0"
11871   [(set_attr "type" "ishift")
11872    (set_attr "length_immediate" "0")
11873    (set_attr "mode" "HI")])
11874
11875 (define_insn "*lshrhi3_one_bit_cconly"
11876   [(set (reg FLAGS_REG)
11877         (compare
11878           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11879                        (match_operand:QI 2 "const1_operand" ""))
11880           (const_int 0)))
11881    (clobber (match_scratch:HI 0 "=r"))]
11882   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11883    && ix86_match_ccmode (insn, CCGOCmode)
11884    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11885   "shr{w}\t%0"
11886   [(set_attr "type" "ishift")
11887    (set_attr "length_immediate" "0")
11888    (set_attr "mode" "HI")])
11889
11890 ;; This pattern can't accept a variable shift count, since shifts by
11891 ;; zero don't affect the flags.  We assume that shifts by constant
11892 ;; zero are optimized away.
11893 (define_insn "*lshrhi3_cmp"
11894   [(set (reg FLAGS_REG)
11895         (compare
11896           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11897                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11898           (const_int 0)))
11899    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11900         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11901   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11902    && ix86_match_ccmode (insn, CCGOCmode)
11903    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11904   "shr{w}\t{%2, %0|%0, %2}"
11905   [(set_attr "type" "ishift")
11906    (set_attr "mode" "HI")])
11907
11908 (define_insn "*lshrhi3_cconly"
11909   [(set (reg FLAGS_REG)
11910         (compare
11911           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11912                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11913           (const_int 0)))
11914    (clobber (match_scratch:HI 0 "=r"))]
11915   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11916    && ix86_match_ccmode (insn, CCGOCmode)
11917    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11918   "shr{w}\t{%2, %0|%0, %2}"
11919   [(set_attr "type" "ishift")
11920    (set_attr "mode" "HI")])
11921
11922 (define_expand "lshrqi3"
11923   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11924         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11925                      (match_operand:QI 2 "nonmemory_operand" "")))]
11926   "TARGET_QIMODE_MATH"
11927   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11928
11929 (define_insn "*lshrqi3_1_one_bit"
11930   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11931         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11932                      (match_operand:QI 2 "const1_operand" "")))
11933    (clobber (reg:CC FLAGS_REG))]
11934   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11935    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11936   "shr{b}\t%0"
11937   [(set_attr "type" "ishift")
11938    (set_attr "length_immediate" "0")
11939    (set_attr "mode" "QI")])
11940
11941 (define_insn "*lshrqi3_1_one_bit_slp"
11942   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11943         (lshiftrt:QI (match_dup 0)
11944                      (match_operand:QI 1 "const1_operand" "")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11947    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11948   "shr{b}\t%0"
11949   [(set_attr "type" "ishift1")
11950    (set_attr "length_immediate" "0")
11951    (set_attr "mode" "QI")])
11952
11953 (define_insn "*lshrqi3_1"
11954   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11955         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11956                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11959   "@
11960    shr{b}\t{%2, %0|%0, %2}
11961    shr{b}\t{%b2, %0|%0, %b2}"
11962   [(set_attr "type" "ishift")
11963    (set_attr "mode" "QI")])
11964
11965 (define_insn "*lshrqi3_1_slp"
11966   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11967         (lshiftrt:QI (match_dup 0)
11968                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11971    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11972   "@
11973    shr{b}\t{%1, %0|%0, %1}
11974    shr{b}\t{%b1, %0|%0, %b1}"
11975   [(set_attr "type" "ishift1")
11976    (set_attr "mode" "QI")])
11977
11978 ;; This pattern can't accept a variable shift count, since shifts by
11979 ;; zero don't affect the flags.  We assume that shifts by constant
11980 ;; zero are optimized away.
11981 (define_insn "*lshrqi2_one_bit_cmp"
11982   [(set (reg FLAGS_REG)
11983         (compare
11984           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11985                        (match_operand:QI 2 "const1_operand" ""))
11986           (const_int 0)))
11987    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11988         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11989   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11990    && ix86_match_ccmode (insn, CCGOCmode)
11991    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11992   "shr{b}\t%0"
11993   [(set_attr "type" "ishift")
11994    (set_attr "length_immediate" "0")
11995    (set_attr "mode" "QI")])
11996
11997 (define_insn "*lshrqi2_one_bit_cconly"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const1_operand" ""))
12002           (const_int 0)))
12003    (clobber (match_scratch:QI 0 "=q"))]
12004   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12005    && ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12007   "shr{b}\t%0"
12008   [(set_attr "type" "ishift")
12009    (set_attr "length_immediate" "0")
12010    (set_attr "mode" "QI")])
12011
12012 ;; This pattern can't accept a variable shift count, since shifts by
12013 ;; zero don't affect the flags.  We assume that shifts by constant
12014 ;; zero are optimized away.
12015 (define_insn "*lshrqi2_cmp"
12016   [(set (reg FLAGS_REG)
12017         (compare
12018           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12019                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12020           (const_int 0)))
12021    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12022         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12023   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12024    && ix86_match_ccmode (insn, CCGOCmode)
12025    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12026   "shr{b}\t{%2, %0|%0, %2}"
12027   [(set_attr "type" "ishift")
12028    (set_attr "mode" "QI")])
12029
12030 (define_insn "*lshrqi2_cconly"
12031   [(set (reg FLAGS_REG)
12032         (compare
12033           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12034                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12035           (const_int 0)))
12036    (clobber (match_scratch:QI 0 "=q"))]
12037   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12038    && ix86_match_ccmode (insn, CCGOCmode)
12039    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12040   "shr{b}\t{%2, %0|%0, %2}"
12041   [(set_attr "type" "ishift")
12042    (set_attr "mode" "QI")])
12043 \f
12044 ;; Rotate instructions
12045
12046 (define_expand "rotldi3"
12047   [(set (match_operand:DI 0 "shiftdi_operand" "")
12048         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12049                    (match_operand:QI 2 "nonmemory_operand" "")))]
12050  ""
12051 {
12052   if (TARGET_64BIT)
12053     {
12054       ix86_expand_binary_operator (ROTATE, DImode, operands);
12055       DONE;
12056     }
12057   if (!const_1_to_31_operand (operands[2], VOIDmode))
12058     FAIL;
12059   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12060   DONE;
12061 })
12062
12063 ;; Implement rotation using two double-precision shift instructions
12064 ;; and a scratch register.
12065 (define_insn_and_split "ix86_rotldi3"
12066  [(set (match_operand:DI 0 "register_operand" "=r")
12067        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12068                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12069   (clobber (reg:CC FLAGS_REG))
12070   (clobber (match_scratch:SI 3 "=&r"))]
12071  "!TARGET_64BIT"
12072  ""
12073  "&& reload_completed"
12074  [(set (match_dup 3) (match_dup 4))
12075   (parallel
12076    [(set (match_dup 4)
12077          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12078                  (lshiftrt:SI (match_dup 5)
12079                               (minus:QI (const_int 32) (match_dup 2)))))
12080     (clobber (reg:CC FLAGS_REG))])
12081   (parallel
12082    [(set (match_dup 5)
12083          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12084                  (lshiftrt:SI (match_dup 3)
12085                               (minus:QI (const_int 32) (match_dup 2)))))
12086     (clobber (reg:CC FLAGS_REG))])]
12087  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12088
12089 (define_insn "*rotlsi3_1_one_bit_rex64"
12090   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12091         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092                    (match_operand:QI 2 "const1_operand" "")))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "TARGET_64BIT
12095    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12096    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12097   "rol{q}\t%0"
12098   [(set_attr "type" "rotate")
12099    (set_attr "length_immediate" "0")
12100    (set_attr "mode" "DI")])
12101
12102 (define_insn "*rotldi3_1_rex64"
12103   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12104         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12105                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12108   "@
12109    rol{q}\t{%2, %0|%0, %2}
12110    rol{q}\t{%b2, %0|%0, %b2}"
12111   [(set_attr "type" "rotate")
12112    (set_attr "mode" "DI")])
12113
12114 (define_expand "rotlsi3"
12115   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12116         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12117                    (match_operand:QI 2 "nonmemory_operand" "")))]
12118   ""
12119   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12120
12121 (define_insn "*rotlsi3_1_one_bit"
12122   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12123         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12124                    (match_operand:QI 2 "const1_operand" "")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12127    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12128   "rol{l}\t%0"
12129   [(set_attr "type" "rotate")
12130    (set_attr "length_immediate" "0")
12131    (set_attr "mode" "SI")])
12132
12133 (define_insn "*rotlsi3_1_one_bit_zext"
12134   [(set (match_operand:DI 0 "register_operand" "=r")
12135         (zero_extend:DI
12136           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12137                      (match_operand:QI 2 "const1_operand" ""))))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "TARGET_64BIT
12140    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12141    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12142   "rol{l}\t%k0"
12143   [(set_attr "type" "rotate")
12144    (set_attr "length_immediate" "0")
12145    (set_attr "mode" "SI")])
12146
12147 (define_insn "*rotlsi3_1"
12148   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12149         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12150                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12153   "@
12154    rol{l}\t{%2, %0|%0, %2}
12155    rol{l}\t{%b2, %0|%0, %b2}"
12156   [(set_attr "type" "rotate")
12157    (set_attr "mode" "SI")])
12158
12159 (define_insn "*rotlsi3_1_zext"
12160   [(set (match_operand:DI 0 "register_operand" "=r,r")
12161         (zero_extend:DI
12162           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12163                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12164    (clobber (reg:CC FLAGS_REG))]
12165   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12166   "@
12167    rol{l}\t{%2, %k0|%k0, %2}
12168    rol{l}\t{%b2, %k0|%k0, %b2}"
12169   [(set_attr "type" "rotate")
12170    (set_attr "mode" "SI")])
12171
12172 (define_expand "rotlhi3"
12173   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12174         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12175                    (match_operand:QI 2 "nonmemory_operand" "")))]
12176   "TARGET_HIMODE_MATH"
12177   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12178
12179 (define_insn "*rotlhi3_1_one_bit"
12180   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12181         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12182                    (match_operand:QI 2 "const1_operand" "")))
12183    (clobber (reg:CC FLAGS_REG))]
12184   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12185    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12186   "rol{w}\t%0"
12187   [(set_attr "type" "rotate")
12188    (set_attr "length_immediate" "0")
12189    (set_attr "mode" "HI")])
12190
12191 (define_insn "*rotlhi3_1"
12192   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12193         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12194                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12195    (clobber (reg:CC FLAGS_REG))]
12196   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12197   "@
12198    rol{w}\t{%2, %0|%0, %2}
12199    rol{w}\t{%b2, %0|%0, %b2}"
12200   [(set_attr "type" "rotate")
12201    (set_attr "mode" "HI")])
12202
12203 (define_split
12204  [(set (match_operand:HI 0 "register_operand" "")
12205        (rotate:HI (match_dup 0) (const_int 8)))
12206   (clobber (reg:CC FLAGS_REG))]
12207  "reload_completed"
12208  [(parallel [(set (strict_low_part (match_dup 0))
12209                   (bswap:HI (match_dup 0)))
12210              (clobber (reg:CC FLAGS_REG))])]
12211  "")
12212
12213 (define_expand "rotlqi3"
12214   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12215         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12216                    (match_operand:QI 2 "nonmemory_operand" "")))]
12217   "TARGET_QIMODE_MATH"
12218   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12219
12220 (define_insn "*rotlqi3_1_one_bit_slp"
12221   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12222         (rotate:QI (match_dup 0)
12223                    (match_operand:QI 1 "const1_operand" "")))
12224    (clobber (reg:CC FLAGS_REG))]
12225   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12226    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12227   "rol{b}\t%0"
12228   [(set_attr "type" "rotate1")
12229    (set_attr "length_immediate" "0")
12230    (set_attr "mode" "QI")])
12231
12232 (define_insn "*rotlqi3_1_one_bit"
12233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12234         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12235                    (match_operand:QI 2 "const1_operand" "")))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12238    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12239   "rol{b}\t%0"
12240   [(set_attr "type" "rotate")
12241    (set_attr "length_immediate" "0")
12242    (set_attr "mode" "QI")])
12243
12244 (define_insn "*rotlqi3_1_slp"
12245   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12246         (rotate:QI (match_dup 0)
12247                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12248    (clobber (reg:CC FLAGS_REG))]
12249   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12250    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12251   "@
12252    rol{b}\t{%1, %0|%0, %1}
12253    rol{b}\t{%b1, %0|%0, %b1}"
12254   [(set_attr "type" "rotate1")
12255    (set_attr "mode" "QI")])
12256
12257 (define_insn "*rotlqi3_1"
12258   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12259         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12260                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12261    (clobber (reg:CC FLAGS_REG))]
12262   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12263   "@
12264    rol{b}\t{%2, %0|%0, %2}
12265    rol{b}\t{%b2, %0|%0, %b2}"
12266   [(set_attr "type" "rotate")
12267    (set_attr "mode" "QI")])
12268
12269 (define_expand "rotrdi3"
12270   [(set (match_operand:DI 0 "shiftdi_operand" "")
12271         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12272                    (match_operand:QI 2 "nonmemory_operand" "")))]
12273  ""
12274 {
12275   if (TARGET_64BIT)
12276     {
12277       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12278       DONE;
12279     }
12280   if (!const_1_to_31_operand (operands[2], VOIDmode))
12281     FAIL;
12282   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12283   DONE;
12284 })
12285
12286 ;; Implement rotation using two double-precision shift instructions
12287 ;; and a scratch register.
12288 (define_insn_and_split "ix86_rotrdi3"
12289  [(set (match_operand:DI 0 "register_operand" "=r")
12290        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12291                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12292   (clobber (reg:CC FLAGS_REG))
12293   (clobber (match_scratch:SI 3 "=&r"))]
12294  "!TARGET_64BIT"
12295  ""
12296  "&& reload_completed"
12297  [(set (match_dup 3) (match_dup 4))
12298   (parallel
12299    [(set (match_dup 4)
12300          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12301                  (ashift:SI (match_dup 5)
12302                             (minus:QI (const_int 32) (match_dup 2)))))
12303     (clobber (reg:CC FLAGS_REG))])
12304   (parallel
12305    [(set (match_dup 5)
12306          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12307                  (ashift:SI (match_dup 3)
12308                             (minus:QI (const_int 32) (match_dup 2)))))
12309     (clobber (reg:CC FLAGS_REG))])]
12310  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12311
12312 (define_insn "*rotrdi3_1_one_bit_rex64"
12313   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12314         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12315                      (match_operand:QI 2 "const1_operand" "")))
12316    (clobber (reg:CC FLAGS_REG))]
12317   "TARGET_64BIT
12318    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12319    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12320   "ror{q}\t%0"
12321   [(set_attr "type" "rotate")
12322    (set_attr "length_immediate" "0")
12323    (set_attr "mode" "DI")])
12324
12325 (define_insn "*rotrdi3_1_rex64"
12326   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12327         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12328                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12329    (clobber (reg:CC FLAGS_REG))]
12330   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12331   "@
12332    ror{q}\t{%2, %0|%0, %2}
12333    ror{q}\t{%b2, %0|%0, %b2}"
12334   [(set_attr "type" "rotate")
12335    (set_attr "mode" "DI")])
12336
12337 (define_expand "rotrsi3"
12338   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12339         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12340                      (match_operand:QI 2 "nonmemory_operand" "")))]
12341   ""
12342   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12343
12344 (define_insn "*rotrsi3_1_one_bit"
12345   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12346         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12347                      (match_operand:QI 2 "const1_operand" "")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12350    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12351   "ror{l}\t%0"
12352   [(set_attr "type" "rotate")
12353    (set_attr "length_immediate" "0")
12354    (set_attr "mode" "SI")])
12355
12356 (define_insn "*rotrsi3_1_one_bit_zext"
12357   [(set (match_operand:DI 0 "register_operand" "=r")
12358         (zero_extend:DI
12359           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12360                        (match_operand:QI 2 "const1_operand" ""))))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_64BIT
12363    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12364    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12365   "ror{l}\t%k0"
12366   [(set_attr "type" "rotate")
12367    (set_attr "length_immediate" "0")
12368    (set_attr "mode" "SI")])
12369
12370 (define_insn "*rotrsi3_1"
12371   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12372         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12373                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12376   "@
12377    ror{l}\t{%2, %0|%0, %2}
12378    ror{l}\t{%b2, %0|%0, %b2}"
12379   [(set_attr "type" "rotate")
12380    (set_attr "mode" "SI")])
12381
12382 (define_insn "*rotrsi3_1_zext"
12383   [(set (match_operand:DI 0 "register_operand" "=r,r")
12384         (zero_extend:DI
12385           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12386                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12389   "@
12390    ror{l}\t{%2, %k0|%k0, %2}
12391    ror{l}\t{%b2, %k0|%k0, %b2}"
12392   [(set_attr "type" "rotate")
12393    (set_attr "mode" "SI")])
12394
12395 (define_expand "rotrhi3"
12396   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12397         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))]
12399   "TARGET_HIMODE_MATH"
12400   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12401
12402 (define_insn "*rotrhi3_one_bit"
12403   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12404         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405                      (match_operand:QI 2 "const1_operand" "")))
12406    (clobber (reg:CC FLAGS_REG))]
12407   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12409   "ror{w}\t%0"
12410   [(set_attr "type" "rotate")
12411    (set_attr "length_immediate" "0")
12412    (set_attr "mode" "HI")])
12413
12414 (define_insn "*rotrhi3_1"
12415   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12416         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12417                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12418    (clobber (reg:CC FLAGS_REG))]
12419   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12420   "@
12421    ror{w}\t{%2, %0|%0, %2}
12422    ror{w}\t{%b2, %0|%0, %b2}"
12423   [(set_attr "type" "rotate")
12424    (set_attr "mode" "HI")])
12425
12426 (define_split
12427  [(set (match_operand:HI 0 "register_operand" "")
12428        (rotatert:HI (match_dup 0) (const_int 8)))
12429   (clobber (reg:CC FLAGS_REG))]
12430  "reload_completed"
12431  [(parallel [(set (strict_low_part (match_dup 0))
12432                   (bswap:HI (match_dup 0)))
12433              (clobber (reg:CC FLAGS_REG))])]
12434  "")
12435
12436 (define_expand "rotrqi3"
12437   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12438         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12439                      (match_operand:QI 2 "nonmemory_operand" "")))]
12440   "TARGET_QIMODE_MATH"
12441   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12442
12443 (define_insn "*rotrqi3_1_one_bit"
12444   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12445         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12446                      (match_operand:QI 2 "const1_operand" "")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12449    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12450   "ror{b}\t%0"
12451   [(set_attr "type" "rotate")
12452    (set_attr "length_immediate" "0")
12453    (set_attr "mode" "QI")])
12454
12455 (define_insn "*rotrqi3_1_one_bit_slp"
12456   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12457         (rotatert:QI (match_dup 0)
12458                      (match_operand:QI 1 "const1_operand" "")))
12459    (clobber (reg:CC FLAGS_REG))]
12460   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12461    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12462   "ror{b}\t%0"
12463   [(set_attr "type" "rotate1")
12464    (set_attr "length_immediate" "0")
12465    (set_attr "mode" "QI")])
12466
12467 (define_insn "*rotrqi3_1"
12468   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12469         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12470                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12471    (clobber (reg:CC FLAGS_REG))]
12472   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12473   "@
12474    ror{b}\t{%2, %0|%0, %2}
12475    ror{b}\t{%b2, %0|%0, %b2}"
12476   [(set_attr "type" "rotate")
12477    (set_attr "mode" "QI")])
12478
12479 (define_insn "*rotrqi3_1_slp"
12480   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12481         (rotatert:QI (match_dup 0)
12482                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12483    (clobber (reg:CC FLAGS_REG))]
12484   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12485    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12486   "@
12487    ror{b}\t{%1, %0|%0, %1}
12488    ror{b}\t{%b1, %0|%0, %b1}"
12489   [(set_attr "type" "rotate1")
12490    (set_attr "mode" "QI")])
12491 \f
12492 ;; Bit set / bit test instructions
12493
12494 (define_expand "extv"
12495   [(set (match_operand:SI 0 "register_operand" "")
12496         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12497                          (match_operand:SI 2 "const8_operand" "")
12498                          (match_operand:SI 3 "const8_operand" "")))]
12499   ""
12500 {
12501   /* Handle extractions from %ah et al.  */
12502   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12503     FAIL;
12504
12505   /* From mips.md: extract_bit_field doesn't verify that our source
12506      matches the predicate, so check it again here.  */
12507   if (! ext_register_operand (operands[1], VOIDmode))
12508     FAIL;
12509 })
12510
12511 (define_expand "extzv"
12512   [(set (match_operand:SI 0 "register_operand" "")
12513         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12514                          (match_operand:SI 2 "const8_operand" "")
12515                          (match_operand:SI 3 "const8_operand" "")))]
12516   ""
12517 {
12518   /* Handle extractions from %ah et al.  */
12519   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12520     FAIL;
12521
12522   /* From mips.md: extract_bit_field doesn't verify that our source
12523      matches the predicate, so check it again here.  */
12524   if (! ext_register_operand (operands[1], VOIDmode))
12525     FAIL;
12526 })
12527
12528 (define_expand "insv"
12529   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12530                       (match_operand 1 "const8_operand" "")
12531                       (match_operand 2 "const8_operand" ""))
12532         (match_operand 3 "register_operand" ""))]
12533   ""
12534 {
12535   /* Handle insertions to %ah et al.  */
12536   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12537     FAIL;
12538
12539   /* From mips.md: insert_bit_field doesn't verify that our source
12540      matches the predicate, so check it again here.  */
12541   if (! ext_register_operand (operands[0], VOIDmode))
12542     FAIL;
12543
12544   if (TARGET_64BIT)
12545     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12546   else
12547     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12548
12549   DONE;
12550 })
12551
12552 ;; %%% bts, btr, btc, bt.
12553 ;; In general these instructions are *slow* when applied to memory,
12554 ;; since they enforce atomic operation.  When applied to registers,
12555 ;; it depends on the cpu implementation.  They're never faster than
12556 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12557 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12558 ;; within the instruction itself, so operating on bits in the high
12559 ;; 32-bits of a register becomes easier.
12560 ;;
12561 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12562 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12563 ;; negdf respectively, so they can never be disabled entirely.
12564
12565 (define_insn "*btsq"
12566   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12567                          (const_int 1)
12568                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12569         (const_int 1))
12570    (clobber (reg:CC FLAGS_REG))]
12571   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12572   "bts{q}\t{%1, %0|%0, %1}"
12573   [(set_attr "type" "alu1")
12574    (set_attr "prefix_0f" "1")
12575    (set_attr "mode" "DI")])
12576
12577 (define_insn "*btrq"
12578   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12579                          (const_int 1)
12580                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12581         (const_int 0))
12582    (clobber (reg:CC FLAGS_REG))]
12583   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12584   "btr{q}\t{%1, %0|%0, %1}"
12585   [(set_attr "type" "alu1")
12586    (set_attr "prefix_0f" "1")
12587    (set_attr "mode" "DI")])
12588
12589 (define_insn "*btcq"
12590   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12591                          (const_int 1)
12592                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12593         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12594    (clobber (reg:CC FLAGS_REG))]
12595   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12596   "btc{q}\t{%1, %0|%0, %1}"
12597   [(set_attr "type" "alu1")
12598    (set_attr "prefix_0f" "1")
12599    (set_attr "mode" "DI")])
12600
12601 ;; Allow Nocona to avoid these instructions if a register is available.
12602
12603 (define_peephole2
12604   [(match_scratch:DI 2 "r")
12605    (parallel [(set (zero_extract:DI
12606                      (match_operand:DI 0 "register_operand" "")
12607                      (const_int 1)
12608                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12609                    (const_int 1))
12610               (clobber (reg:CC FLAGS_REG))])]
12611   "TARGET_64BIT && !TARGET_USE_BT"
12612   [(const_int 0)]
12613 {
12614   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12615   rtx op1;
12616
12617   if (HOST_BITS_PER_WIDE_INT >= 64)
12618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619   else if (i < HOST_BITS_PER_WIDE_INT)
12620     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12621   else
12622     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12623
12624   op1 = immed_double_const (lo, hi, DImode);
12625   if (i >= 31)
12626     {
12627       emit_move_insn (operands[2], op1);
12628       op1 = operands[2];
12629     }
12630
12631   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12632   DONE;
12633 })
12634
12635 (define_peephole2
12636   [(match_scratch:DI 2 "r")
12637    (parallel [(set (zero_extract:DI
12638                      (match_operand:DI 0 "register_operand" "")
12639                      (const_int 1)
12640                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12641                    (const_int 0))
12642               (clobber (reg:CC FLAGS_REG))])]
12643   "TARGET_64BIT && !TARGET_USE_BT"
12644   [(const_int 0)]
12645 {
12646   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12647   rtx op1;
12648
12649   if (HOST_BITS_PER_WIDE_INT >= 64)
12650     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12651   else if (i < HOST_BITS_PER_WIDE_INT)
12652     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653   else
12654     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12655
12656   op1 = immed_double_const (~lo, ~hi, DImode);
12657   if (i >= 32)
12658     {
12659       emit_move_insn (operands[2], op1);
12660       op1 = operands[2];
12661     }
12662
12663   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12664   DONE;
12665 })
12666
12667 (define_peephole2
12668   [(match_scratch:DI 2 "r")
12669    (parallel [(set (zero_extract:DI
12670                      (match_operand:DI 0 "register_operand" "")
12671                      (const_int 1)
12672                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12673               (not:DI (zero_extract:DI
12674                         (match_dup 0) (const_int 1) (match_dup 1))))
12675               (clobber (reg:CC FLAGS_REG))])]
12676   "TARGET_64BIT && !TARGET_USE_BT"
12677   [(const_int 0)]
12678 {
12679   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12680   rtx op1;
12681
12682   if (HOST_BITS_PER_WIDE_INT >= 64)
12683     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12684   else if (i < HOST_BITS_PER_WIDE_INT)
12685     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12686   else
12687     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12688
12689   op1 = immed_double_const (lo, hi, DImode);
12690   if (i >= 31)
12691     {
12692       emit_move_insn (operands[2], op1);
12693       op1 = operands[2];
12694     }
12695
12696   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12697   DONE;
12698 })
12699
12700 (define_insn "*btdi_rex64"
12701   [(set (reg:CCC FLAGS_REG)
12702         (compare:CCC
12703           (zero_extract:DI
12704             (match_operand:DI 0 "register_operand" "r")
12705             (const_int 1)
12706             (match_operand:DI 1 "nonmemory_operand" "rN"))
12707           (const_int 0)))]
12708   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12709   "bt{q}\t{%1, %0|%0, %1}"
12710   [(set_attr "type" "alu1")
12711    (set_attr "prefix_0f" "1")
12712    (set_attr "mode" "DI")])
12713
12714 (define_insn "*btsi"
12715   [(set (reg:CCC FLAGS_REG)
12716         (compare:CCC
12717           (zero_extract:SI
12718             (match_operand:SI 0 "register_operand" "r")
12719             (const_int 1)
12720             (match_operand:SI 1 "nonmemory_operand" "rN"))
12721           (const_int 0)))]
12722   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12723   "bt{l}\t{%1, %0|%0, %1}"
12724   [(set_attr "type" "alu1")
12725    (set_attr "prefix_0f" "1")
12726    (set_attr "mode" "SI")])
12727 \f
12728 ;; Store-flag instructions.
12729
12730 ;; For all sCOND expanders, also expand the compare or test insn that
12731 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12732
12733 (define_insn_and_split "*setcc_di_1"
12734   [(set (match_operand:DI 0 "register_operand" "=q")
12735         (match_operator:DI 1 "ix86_comparison_operator"
12736           [(reg FLAGS_REG) (const_int 0)]))]
12737   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12738   "#"
12739   "&& reload_completed"
12740   [(set (match_dup 2) (match_dup 1))
12741    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12742 {
12743   PUT_MODE (operands[1], QImode);
12744   operands[2] = gen_lowpart (QImode, operands[0]);
12745 })
12746
12747 (define_insn_and_split "*setcc_si_1_and"
12748   [(set (match_operand:SI 0 "register_operand" "=q")
12749         (match_operator:SI 1 "ix86_comparison_operator"
12750           [(reg FLAGS_REG) (const_int 0)]))
12751    (clobber (reg:CC FLAGS_REG))]
12752   "!TARGET_PARTIAL_REG_STALL
12753    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12754   "#"
12755   "&& reload_completed"
12756   [(set (match_dup 2) (match_dup 1))
12757    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12758               (clobber (reg:CC FLAGS_REG))])]
12759 {
12760   PUT_MODE (operands[1], QImode);
12761   operands[2] = gen_lowpart (QImode, operands[0]);
12762 })
12763
12764 (define_insn_and_split "*setcc_si_1_movzbl"
12765   [(set (match_operand:SI 0 "register_operand" "=q")
12766         (match_operator:SI 1 "ix86_comparison_operator"
12767           [(reg FLAGS_REG) (const_int 0)]))]
12768   "!TARGET_PARTIAL_REG_STALL
12769    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12770   "#"
12771   "&& reload_completed"
12772   [(set (match_dup 2) (match_dup 1))
12773    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12774 {
12775   PUT_MODE (operands[1], QImode);
12776   operands[2] = gen_lowpart (QImode, operands[0]);
12777 })
12778
12779 (define_insn "*setcc_qi"
12780   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12781         (match_operator:QI 1 "ix86_comparison_operator"
12782           [(reg FLAGS_REG) (const_int 0)]))]
12783   ""
12784   "set%C1\t%0"
12785   [(set_attr "type" "setcc")
12786    (set_attr "mode" "QI")])
12787
12788 (define_insn "*setcc_qi_slp"
12789   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12790         (match_operator:QI 1 "ix86_comparison_operator"
12791           [(reg FLAGS_REG) (const_int 0)]))]
12792   ""
12793   "set%C1\t%0"
12794   [(set_attr "type" "setcc")
12795    (set_attr "mode" "QI")])
12796
12797 ;; In general it is not safe to assume too much about CCmode registers,
12798 ;; so simplify-rtx stops when it sees a second one.  Under certain
12799 ;; conditions this is safe on x86, so help combine not create
12800 ;;
12801 ;;      seta    %al
12802 ;;      testb   %al, %al
12803 ;;      sete    %al
12804
12805 (define_split
12806   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12807         (ne:QI (match_operator 1 "ix86_comparison_operator"
12808                  [(reg FLAGS_REG) (const_int 0)])
12809             (const_int 0)))]
12810   ""
12811   [(set (match_dup 0) (match_dup 1))]
12812 {
12813   PUT_MODE (operands[1], QImode);
12814 })
12815
12816 (define_split
12817   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12818         (ne:QI (match_operator 1 "ix86_comparison_operator"
12819                  [(reg FLAGS_REG) (const_int 0)])
12820             (const_int 0)))]
12821   ""
12822   [(set (match_dup 0) (match_dup 1))]
12823 {
12824   PUT_MODE (operands[1], QImode);
12825 })
12826
12827 (define_split
12828   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12829         (eq:QI (match_operator 1 "ix86_comparison_operator"
12830                  [(reg FLAGS_REG) (const_int 0)])
12831             (const_int 0)))]
12832   ""
12833   [(set (match_dup 0) (match_dup 1))]
12834 {
12835   rtx new_op1 = copy_rtx (operands[1]);
12836   operands[1] = new_op1;
12837   PUT_MODE (new_op1, QImode);
12838   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12839                                              GET_MODE (XEXP (new_op1, 0))));
12840
12841   /* Make sure that (a) the CCmode we have for the flags is strong
12842      enough for the reversed compare or (b) we have a valid FP compare.  */
12843   if (! ix86_comparison_operator (new_op1, VOIDmode))
12844     FAIL;
12845 })
12846
12847 (define_split
12848   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12849         (eq:QI (match_operator 1 "ix86_comparison_operator"
12850                  [(reg FLAGS_REG) (const_int 0)])
12851             (const_int 0)))]
12852   ""
12853   [(set (match_dup 0) (match_dup 1))]
12854 {
12855   rtx new_op1 = copy_rtx (operands[1]);
12856   operands[1] = new_op1;
12857   PUT_MODE (new_op1, QImode);
12858   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12859                                              GET_MODE (XEXP (new_op1, 0))));
12860
12861   /* Make sure that (a) the CCmode we have for the flags is strong
12862      enough for the reversed compare or (b) we have a valid FP compare.  */
12863   if (! ix86_comparison_operator (new_op1, VOIDmode))
12864     FAIL;
12865 })
12866
12867 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12868 ;; subsequent logical operations are used to imitate conditional moves.
12869 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12870 ;; it directly.
12871
12872 (define_insn "*avx_setcc<mode>"
12873   [(set (match_operand:MODEF 0 "register_operand" "=x")
12874         (match_operator:MODEF 1 "avx_comparison_float_operator"
12875           [(match_operand:MODEF 2 "register_operand" "x")
12876            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12877   "TARGET_AVX"
12878   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12879   [(set_attr "type" "ssecmp")
12880    (set_attr "prefix" "vex")
12881    (set_attr "length_immediate" "1")
12882    (set_attr "mode" "<MODE>")])
12883
12884 (define_insn "*sse_setcc<mode>"
12885   [(set (match_operand:MODEF 0 "register_operand" "=x")
12886         (match_operator:MODEF 1 "sse_comparison_operator"
12887           [(match_operand:MODEF 2 "register_operand" "0")
12888            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12889   "SSE_FLOAT_MODE_P (<MODE>mode)"
12890   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12891   [(set_attr "type" "ssecmp")
12892    (set_attr "length_immediate" "1")
12893    (set_attr "mode" "<MODE>")])
12894 \f
12895 ;; Basic conditional jump instructions.
12896 ;; We ignore the overflow flag for signed branch instructions.
12897
12898 (define_insn "*jcc_1"
12899   [(set (pc)
12900         (if_then_else (match_operator 1 "ix86_comparison_operator"
12901                                       [(reg FLAGS_REG) (const_int 0)])
12902                       (label_ref (match_operand 0 "" ""))
12903                       (pc)))]
12904   ""
12905   "%+j%C1\t%l0"
12906   [(set_attr "type" "ibr")
12907    (set_attr "modrm" "0")
12908    (set (attr "length")
12909            (if_then_else (and (ge (minus (match_dup 0) (pc))
12910                                   (const_int -126))
12911                               (lt (minus (match_dup 0) (pc))
12912                                   (const_int 128)))
12913              (const_int 2)
12914              (const_int 6)))])
12915
12916 (define_insn "*jcc_2"
12917   [(set (pc)
12918         (if_then_else (match_operator 1 "ix86_comparison_operator"
12919                                       [(reg FLAGS_REG) (const_int 0)])
12920                       (pc)
12921                       (label_ref (match_operand 0 "" ""))))]
12922   ""
12923   "%+j%c1\t%l0"
12924   [(set_attr "type" "ibr")
12925    (set_attr "modrm" "0")
12926    (set (attr "length")
12927            (if_then_else (and (ge (minus (match_dup 0) (pc))
12928                                   (const_int -126))
12929                               (lt (minus (match_dup 0) (pc))
12930                                   (const_int 128)))
12931              (const_int 2)
12932              (const_int 6)))])
12933
12934 ;; In general it is not safe to assume too much about CCmode registers,
12935 ;; so simplify-rtx stops when it sees a second one.  Under certain
12936 ;; conditions this is safe on x86, so help combine not create
12937 ;;
12938 ;;      seta    %al
12939 ;;      testb   %al, %al
12940 ;;      je      Lfoo
12941
12942 (define_split
12943   [(set (pc)
12944         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12945                                       [(reg FLAGS_REG) (const_int 0)])
12946                           (const_int 0))
12947                       (label_ref (match_operand 1 "" ""))
12948                       (pc)))]
12949   ""
12950   [(set (pc)
12951         (if_then_else (match_dup 0)
12952                       (label_ref (match_dup 1))
12953                       (pc)))]
12954 {
12955   PUT_MODE (operands[0], VOIDmode);
12956 })
12957
12958 (define_split
12959   [(set (pc)
12960         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12961                                       [(reg FLAGS_REG) (const_int 0)])
12962                           (const_int 0))
12963                       (label_ref (match_operand 1 "" ""))
12964                       (pc)))]
12965   ""
12966   [(set (pc)
12967         (if_then_else (match_dup 0)
12968                       (label_ref (match_dup 1))
12969                       (pc)))]
12970 {
12971   rtx new_op0 = copy_rtx (operands[0]);
12972   operands[0] = new_op0;
12973   PUT_MODE (new_op0, VOIDmode);
12974   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12975                                              GET_MODE (XEXP (new_op0, 0))));
12976
12977   /* Make sure that (a) the CCmode we have for the flags is strong
12978      enough for the reversed compare or (b) we have a valid FP compare.  */
12979   if (! ix86_comparison_operator (new_op0, VOIDmode))
12980     FAIL;
12981 })
12982
12983 ;; zero_extend in SImode is correct, since this is what combine pass
12984 ;; generates from shift insn with QImode operand.  Actually, the mode of
12985 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12986 ;; appropriate modulo of the bit offset value.
12987
12988 (define_insn_and_split "*jcc_btdi_rex64"
12989   [(set (pc)
12990         (if_then_else (match_operator 0 "bt_comparison_operator"
12991                         [(zero_extract:DI
12992                            (match_operand:DI 1 "register_operand" "r")
12993                            (const_int 1)
12994                            (zero_extend:SI
12995                              (match_operand:QI 2 "register_operand" "r")))
12996                          (const_int 0)])
12997                       (label_ref (match_operand 3 "" ""))
12998                       (pc)))
12999    (clobber (reg:CC FLAGS_REG))]
13000   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13001   "#"
13002   "&& 1"
13003   [(set (reg:CCC FLAGS_REG)
13004         (compare:CCC
13005           (zero_extract:DI
13006             (match_dup 1)
13007             (const_int 1)
13008             (match_dup 2))
13009           (const_int 0)))
13010    (set (pc)
13011         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13012                       (label_ref (match_dup 3))
13013                       (pc)))]
13014 {
13015   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13016
13017   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13018 })
13019
13020 ;; avoid useless masking of bit offset operand
13021 (define_insn_and_split "*jcc_btdi_mask_rex64"
13022   [(set (pc)
13023         (if_then_else (match_operator 0 "bt_comparison_operator"
13024                         [(zero_extract:DI
13025                            (match_operand:DI 1 "register_operand" "r")
13026                            (const_int 1)
13027                            (and:SI
13028                              (match_operand:SI 2 "register_operand" "r")
13029                              (match_operand:SI 3 "const_int_operand" "n")))])
13030                       (label_ref (match_operand 4 "" ""))
13031                       (pc)))
13032    (clobber (reg:CC FLAGS_REG))]
13033   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13034    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13035   "#"
13036   "&& 1"
13037   [(set (reg:CCC FLAGS_REG)
13038         (compare:CCC
13039           (zero_extract:DI
13040             (match_dup 1)
13041             (const_int 1)
13042             (match_dup 2))
13043           (const_int 0)))
13044    (set (pc)
13045         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13046                       (label_ref (match_dup 4))
13047                       (pc)))]
13048 {
13049   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13050
13051   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13052 })
13053
13054 (define_insn_and_split "*jcc_btsi"
13055   [(set (pc)
13056         (if_then_else (match_operator 0 "bt_comparison_operator"
13057                         [(zero_extract:SI
13058                            (match_operand:SI 1 "register_operand" "r")
13059                            (const_int 1)
13060                            (zero_extend:SI
13061                              (match_operand:QI 2 "register_operand" "r")))
13062                          (const_int 0)])
13063                       (label_ref (match_operand 3 "" ""))
13064                       (pc)))
13065    (clobber (reg:CC FLAGS_REG))]
13066   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13067   "#"
13068   "&& 1"
13069   [(set (reg:CCC FLAGS_REG)
13070         (compare:CCC
13071           (zero_extract:SI
13072             (match_dup 1)
13073             (const_int 1)
13074             (match_dup 2))
13075           (const_int 0)))
13076    (set (pc)
13077         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13078                       (label_ref (match_dup 3))
13079                       (pc)))]
13080 {
13081   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13082
13083   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13084 })
13085
13086 ;; avoid useless masking of bit offset operand
13087 (define_insn_and_split "*jcc_btsi_mask"
13088   [(set (pc)
13089         (if_then_else (match_operator 0 "bt_comparison_operator"
13090                         [(zero_extract:SI
13091                            (match_operand:SI 1 "register_operand" "r")
13092                            (const_int 1)
13093                            (and:SI
13094                              (match_operand:SI 2 "register_operand" "r")
13095                              (match_operand:SI 3 "const_int_operand" "n")))])
13096                       (label_ref (match_operand 4 "" ""))
13097                       (pc)))
13098    (clobber (reg:CC FLAGS_REG))]
13099   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13100    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13101   "#"
13102   "&& 1"
13103   [(set (reg:CCC FLAGS_REG)
13104         (compare:CCC
13105           (zero_extract:SI
13106             (match_dup 1)
13107             (const_int 1)
13108             (match_dup 2))
13109           (const_int 0)))
13110    (set (pc)
13111         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13112                       (label_ref (match_dup 4))
13113                       (pc)))]
13114   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13115
13116 (define_insn_and_split "*jcc_btsi_1"
13117   [(set (pc)
13118         (if_then_else (match_operator 0 "bt_comparison_operator"
13119                         [(and:SI
13120                            (lshiftrt:SI
13121                              (match_operand:SI 1 "register_operand" "r")
13122                              (match_operand:QI 2 "register_operand" "r"))
13123                            (const_int 1))
13124                          (const_int 0)])
13125                       (label_ref (match_operand 3 "" ""))
13126                       (pc)))
13127    (clobber (reg:CC FLAGS_REG))]
13128   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13129   "#"
13130   "&& 1"
13131   [(set (reg:CCC FLAGS_REG)
13132         (compare:CCC
13133           (zero_extract:SI
13134             (match_dup 1)
13135             (const_int 1)
13136             (match_dup 2))
13137           (const_int 0)))
13138    (set (pc)
13139         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13140                       (label_ref (match_dup 3))
13141                       (pc)))]
13142 {
13143   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13144
13145   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13146 })
13147
13148 ;; avoid useless masking of bit offset operand
13149 (define_insn_and_split "*jcc_btsi_mask_1"
13150   [(set (pc)
13151         (if_then_else
13152           (match_operator 0 "bt_comparison_operator"
13153             [(and:SI
13154                (lshiftrt:SI
13155                  (match_operand:SI 1 "register_operand" "r")
13156                  (subreg:QI
13157                    (and:SI
13158                      (match_operand:SI 2 "register_operand" "r")
13159                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13160                (const_int 1))
13161              (const_int 0)])
13162           (label_ref (match_operand 4 "" ""))
13163           (pc)))
13164    (clobber (reg:CC FLAGS_REG))]
13165   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13166    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13167   "#"
13168   "&& 1"
13169   [(set (reg:CCC FLAGS_REG)
13170         (compare:CCC
13171           (zero_extract:SI
13172             (match_dup 1)
13173             (const_int 1)
13174             (match_dup 2))
13175           (const_int 0)))
13176    (set (pc)
13177         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13178                       (label_ref (match_dup 4))
13179                       (pc)))]
13180   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13181
13182 ;; Define combination compare-and-branch fp compare instructions to help
13183 ;; combine.
13184
13185 (define_insn "*fp_jcc_3_387"
13186   [(set (pc)
13187         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13188                         [(match_operand 1 "register_operand" "f")
13189                          (match_operand 2 "nonimmediate_operand" "fm")])
13190           (label_ref (match_operand 3 "" ""))
13191           (pc)))
13192    (clobber (reg:CCFP FPSR_REG))
13193    (clobber (reg:CCFP FLAGS_REG))
13194    (clobber (match_scratch:HI 4 "=a"))]
13195   "TARGET_80387
13196    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13197    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13198    && SELECT_CC_MODE (GET_CODE (operands[0]),
13199                       operands[1], operands[2]) == CCFPmode
13200    && !TARGET_CMOVE"
13201   "#")
13202
13203 (define_insn "*fp_jcc_4_387"
13204   [(set (pc)
13205         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13206                         [(match_operand 1 "register_operand" "f")
13207                          (match_operand 2 "nonimmediate_operand" "fm")])
13208           (pc)
13209           (label_ref (match_operand 3 "" ""))))
13210    (clobber (reg:CCFP FPSR_REG))
13211    (clobber (reg:CCFP FLAGS_REG))
13212    (clobber (match_scratch:HI 4 "=a"))]
13213   "TARGET_80387
13214    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13215    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13216    && SELECT_CC_MODE (GET_CODE (operands[0]),
13217                       operands[1], operands[2]) == CCFPmode
13218    && !TARGET_CMOVE"
13219   "#")
13220
13221 (define_insn "*fp_jcc_5_387"
13222   [(set (pc)
13223         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13224                         [(match_operand 1 "register_operand" "f")
13225                          (match_operand 2 "register_operand" "f")])
13226           (label_ref (match_operand 3 "" ""))
13227           (pc)))
13228    (clobber (reg:CCFP FPSR_REG))
13229    (clobber (reg:CCFP FLAGS_REG))
13230    (clobber (match_scratch:HI 4 "=a"))]
13231   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13232    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13233    && !TARGET_CMOVE"
13234   "#")
13235
13236 (define_insn "*fp_jcc_6_387"
13237   [(set (pc)
13238         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13239                         [(match_operand 1 "register_operand" "f")
13240                          (match_operand 2 "register_operand" "f")])
13241           (pc)
13242           (label_ref (match_operand 3 "" ""))))
13243    (clobber (reg:CCFP FPSR_REG))
13244    (clobber (reg:CCFP FLAGS_REG))
13245    (clobber (match_scratch:HI 4 "=a"))]
13246   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13247    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13248    && !TARGET_CMOVE"
13249   "#")
13250
13251 (define_insn "*fp_jcc_7_387"
13252   [(set (pc)
13253         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13254                         [(match_operand 1 "register_operand" "f")
13255                          (match_operand 2 "const0_operand" "")])
13256           (label_ref (match_operand 3 "" ""))
13257           (pc)))
13258    (clobber (reg:CCFP FPSR_REG))
13259    (clobber (reg:CCFP FLAGS_REG))
13260    (clobber (match_scratch:HI 4 "=a"))]
13261   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13262    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263    && SELECT_CC_MODE (GET_CODE (operands[0]),
13264                       operands[1], operands[2]) == CCFPmode
13265    && !TARGET_CMOVE"
13266   "#")
13267
13268 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13269 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13270 ;; with a precedence over other operators and is always put in the first
13271 ;; place. Swap condition and operands to match ficom instruction.
13272
13273 (define_insn "*fp_jcc_8<mode>_387"
13274   [(set (pc)
13275         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13276                         [(match_operator 1 "float_operator"
13277                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13278                            (match_operand 3 "register_operand" "f,f")])
13279           (label_ref (match_operand 4 "" ""))
13280           (pc)))
13281    (clobber (reg:CCFP FPSR_REG))
13282    (clobber (reg:CCFP FLAGS_REG))
13283    (clobber (match_scratch:HI 5 "=a,a"))]
13284   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13285    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13286    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13287    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13288    && !TARGET_CMOVE"
13289   "#")
13290
13291 (define_split
13292   [(set (pc)
13293         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13294                         [(match_operand 1 "register_operand" "")
13295                          (match_operand 2 "nonimmediate_operand" "")])
13296           (match_operand 3 "" "")
13297           (match_operand 4 "" "")))
13298    (clobber (reg:CCFP FPSR_REG))
13299    (clobber (reg:CCFP FLAGS_REG))]
13300   "reload_completed"
13301   [(const_int 0)]
13302 {
13303   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13304                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13305   DONE;
13306 })
13307
13308 (define_split
13309   [(set (pc)
13310         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13311                         [(match_operand 1 "register_operand" "")
13312                          (match_operand 2 "general_operand" "")])
13313           (match_operand 3 "" "")
13314           (match_operand 4 "" "")))
13315    (clobber (reg:CCFP FPSR_REG))
13316    (clobber (reg:CCFP FLAGS_REG))
13317    (clobber (match_scratch:HI 5 "=a"))]
13318   "reload_completed"
13319   [(const_int 0)]
13320 {
13321   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13322                         operands[3], operands[4], operands[5], NULL_RTX);
13323   DONE;
13324 })
13325
13326 (define_split
13327   [(set (pc)
13328         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13329                         [(match_operator 1 "float_operator"
13330                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13331                            (match_operand 3 "register_operand" "")])
13332           (match_operand 4 "" "")
13333           (match_operand 5 "" "")))
13334    (clobber (reg:CCFP FPSR_REG))
13335    (clobber (reg:CCFP FLAGS_REG))
13336    (clobber (match_scratch:HI 6 "=a"))]
13337   "reload_completed"
13338   [(const_int 0)]
13339 {
13340   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13341   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13342                         operands[3], operands[7],
13343                         operands[4], operands[5], operands[6], NULL_RTX);
13344   DONE;
13345 })
13346
13347 ;; %%% Kill this when reload knows how to do it.
13348 (define_split
13349   [(set (pc)
13350         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13351                         [(match_operator 1 "float_operator"
13352                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13353                            (match_operand 3 "register_operand" "")])
13354           (match_operand 4 "" "")
13355           (match_operand 5 "" "")))
13356    (clobber (reg:CCFP FPSR_REG))
13357    (clobber (reg:CCFP FLAGS_REG))
13358    (clobber (match_scratch:HI 6 "=a"))]
13359   "reload_completed"
13360   [(const_int 0)]
13361 {
13362   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13363   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13364   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13365                         operands[3], operands[7],
13366                         operands[4], operands[5], operands[6], operands[2]);
13367   DONE;
13368 })
13369 \f
13370 ;; Unconditional and other jump instructions
13371
13372 (define_insn "jump"
13373   [(set (pc)
13374         (label_ref (match_operand 0 "" "")))]
13375   ""
13376   "jmp\t%l0"
13377   [(set_attr "type" "ibr")
13378    (set (attr "length")
13379            (if_then_else (and (ge (minus (match_dup 0) (pc))
13380                                   (const_int -126))
13381                               (lt (minus (match_dup 0) (pc))
13382                                   (const_int 128)))
13383              (const_int 2)
13384              (const_int 5)))
13385    (set_attr "modrm" "0")])
13386
13387 (define_expand "indirect_jump"
13388   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13389   ""
13390   "")
13391
13392 (define_insn "*indirect_jump"
13393   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13394   ""
13395   "jmp\t%A0"
13396   [(set_attr "type" "ibr")
13397    (set_attr "length_immediate" "0")])
13398
13399 (define_expand "tablejump"
13400   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13401               (use (label_ref (match_operand 1 "" "")))])]
13402   ""
13403 {
13404   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13405      relative.  Convert the relative address to an absolute address.  */
13406   if (flag_pic)
13407     {
13408       rtx op0, op1;
13409       enum rtx_code code;
13410
13411       /* We can't use @GOTOFF for text labels on VxWorks;
13412          see gotoff_operand.  */
13413       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13414         {
13415           code = PLUS;
13416           op0 = operands[0];
13417           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13418         }
13419       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13420         {
13421           code = PLUS;
13422           op0 = operands[0];
13423           op1 = pic_offset_table_rtx;
13424         }
13425       else
13426         {
13427           code = MINUS;
13428           op0 = pic_offset_table_rtx;
13429           op1 = operands[0];
13430         }
13431
13432       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13433                                          OPTAB_DIRECT);
13434     }
13435 })
13436
13437 (define_insn "*tablejump_1"
13438   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13439    (use (label_ref (match_operand 1 "" "")))]
13440   ""
13441   "jmp\t%A0"
13442   [(set_attr "type" "ibr")
13443    (set_attr "length_immediate" "0")])
13444 \f
13445 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13446
13447 (define_peephole2
13448   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13449    (set (match_operand:QI 1 "register_operand" "")
13450         (match_operator:QI 2 "ix86_comparison_operator"
13451           [(reg FLAGS_REG) (const_int 0)]))
13452    (set (match_operand 3 "q_regs_operand" "")
13453         (zero_extend (match_dup 1)))]
13454   "(peep2_reg_dead_p (3, operands[1])
13455     || operands_match_p (operands[1], operands[3]))
13456    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13457   [(set (match_dup 4) (match_dup 0))
13458    (set (strict_low_part (match_dup 5))
13459         (match_dup 2))]
13460 {
13461   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13462   operands[5] = gen_lowpart (QImode, operands[3]);
13463   ix86_expand_clear (operands[3]);
13464 })
13465
13466 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13467
13468 (define_peephole2
13469   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13470    (set (match_operand:QI 1 "register_operand" "")
13471         (match_operator:QI 2 "ix86_comparison_operator"
13472           [(reg FLAGS_REG) (const_int 0)]))
13473    (parallel [(set (match_operand 3 "q_regs_operand" "")
13474                    (zero_extend (match_dup 1)))
13475               (clobber (reg:CC FLAGS_REG))])]
13476   "(peep2_reg_dead_p (3, operands[1])
13477     || operands_match_p (operands[1], operands[3]))
13478    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13479   [(set (match_dup 4) (match_dup 0))
13480    (set (strict_low_part (match_dup 5))
13481         (match_dup 2))]
13482 {
13483   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13484   operands[5] = gen_lowpart (QImode, operands[3]);
13485   ix86_expand_clear (operands[3]);
13486 })
13487 \f
13488 ;; Call instructions.
13489
13490 ;; The predicates normally associated with named expanders are not properly
13491 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13492 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13493
13494 ;; P6 processors will jump to the address after the decrement when %esp
13495 ;; is used as a call operand, so they will execute return address as a code.
13496 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13497  
13498 ;; Call subroutine returning no value.
13499
13500 (define_expand "call_pop"
13501   [(parallel [(call (match_operand:QI 0 "" "")
13502                     (match_operand:SI 1 "" ""))
13503               (set (reg:SI SP_REG)
13504                    (plus:SI (reg:SI SP_REG)
13505                             (match_operand:SI 3 "" "")))])]
13506   "!TARGET_64BIT"
13507 {
13508   ix86_expand_call (NULL, operands[0], operands[1],
13509                     operands[2], operands[3], 0);
13510   DONE;
13511 })
13512
13513 (define_insn "*call_pop_0"
13514   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13515          (match_operand:SI 1 "" ""))
13516    (set (reg:SI SP_REG)
13517         (plus:SI (reg:SI SP_REG)
13518                  (match_operand:SI 2 "immediate_operand" "")))]
13519   "!TARGET_64BIT"
13520 {
13521   if (SIBLING_CALL_P (insn))
13522     return "jmp\t%P0";
13523   else
13524     return "call\t%P0";
13525 }
13526   [(set_attr "type" "call")])
13527
13528 (define_insn "*call_pop_1"
13529   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13530          (match_operand:SI 1 "" ""))
13531    (set (reg:SI SP_REG)
13532         (plus:SI (reg:SI SP_REG)
13533                  (match_operand:SI 2 "immediate_operand" "i")))]
13534   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13535 {
13536   if (constant_call_address_operand (operands[0], Pmode))
13537     return "call\t%P0";
13538   return "call\t%A0";
13539 }
13540   [(set_attr "type" "call")])
13541
13542 (define_insn "*sibcall_pop_1"
13543   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13544          (match_operand:SI 1 "" ""))
13545    (set (reg:SI SP_REG)
13546         (plus:SI (reg:SI SP_REG)
13547                  (match_operand:SI 2 "immediate_operand" "i,i")))]
13548   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13549   "@
13550    jmp\t%P0
13551    jmp\t%A0"
13552   [(set_attr "type" "call")])
13553
13554 (define_expand "call"
13555   [(call (match_operand:QI 0 "" "")
13556          (match_operand 1 "" ""))
13557    (use (match_operand 2 "" ""))]
13558   ""
13559 {
13560   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13561   DONE;
13562 })
13563
13564 (define_expand "sibcall"
13565   [(call (match_operand:QI 0 "" "")
13566          (match_operand 1 "" ""))
13567    (use (match_operand 2 "" ""))]
13568   ""
13569 {
13570   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13571   DONE;
13572 })
13573
13574 (define_insn "*call_0"
13575   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13576          (match_operand 1 "" ""))]
13577   ""
13578 {
13579   if (SIBLING_CALL_P (insn))
13580     return "jmp\t%P0";
13581   else
13582     return "call\t%P0";
13583 }
13584   [(set_attr "type" "call")])
13585
13586 (define_insn "*call_1"
13587   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13588          (match_operand 1 "" ""))]
13589   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13590 {
13591   if (constant_call_address_operand (operands[0], Pmode))
13592     return "call\t%P0";
13593   return "call\t%A0";
13594 }
13595   [(set_attr "type" "call")])
13596
13597 (define_insn "*sibcall_1"
13598   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13599          (match_operand 1 "" ""))]
13600   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13601   "@
13602    jmp\t%P0
13603    jmp\t%A0"
13604   [(set_attr "type" "call")])
13605
13606 (define_insn "*call_1_rex64"
13607   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13608          (match_operand 1 "" ""))]
13609   "TARGET_64BIT && !SIBLING_CALL_P (insn)
13610    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13611 {
13612   if (constant_call_address_operand (operands[0], Pmode))
13613     return "call\t%P0";
13614   return "call\t%A0";
13615 }
13616   [(set_attr "type" "call")])
13617
13618 (define_insn "*call_1_rex64_ms_sysv"
13619   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13620          (match_operand 1 "" ""))
13621    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13622    (clobber (reg:TI XMM6_REG))
13623    (clobber (reg:TI XMM7_REG))
13624    (clobber (reg:TI XMM8_REG))
13625    (clobber (reg:TI XMM9_REG))
13626    (clobber (reg:TI XMM10_REG))
13627    (clobber (reg:TI XMM11_REG))
13628    (clobber (reg:TI XMM12_REG))
13629    (clobber (reg:TI XMM13_REG))
13630    (clobber (reg:TI XMM14_REG))
13631    (clobber (reg:TI XMM15_REG))
13632    (clobber (reg:DI SI_REG))
13633    (clobber (reg:DI DI_REG))]
13634   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13635 {
13636   if (constant_call_address_operand (operands[0], Pmode))
13637     return "call\t%P0";
13638   return "call\t%A0";
13639 }
13640   [(set_attr "type" "call")])
13641
13642 (define_insn "*call_1_rex64_large"
13643   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13644          (match_operand 1 "" ""))]
13645   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13646   "call\t%A0"
13647   [(set_attr "type" "call")])
13648
13649 (define_insn "*sibcall_1_rex64"
13650   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13651          (match_operand 1 "" ""))]
13652   "TARGET_64BIT && SIBLING_CALL_P (insn)"
13653   "@
13654    jmp\t%P0
13655    jmp\t%A0"
13656   [(set_attr "type" "call")])
13657
13658 ;; Call subroutine, returning value in operand 0
13659 (define_expand "call_value_pop"
13660   [(parallel [(set (match_operand 0 "" "")
13661                    (call (match_operand:QI 1 "" "")
13662                          (match_operand:SI 2 "" "")))
13663               (set (reg:SI SP_REG)
13664                    (plus:SI (reg:SI SP_REG)
13665                             (match_operand:SI 4 "" "")))])]
13666   "!TARGET_64BIT"
13667 {
13668   ix86_expand_call (operands[0], operands[1], operands[2],
13669                     operands[3], operands[4], 0);
13670   DONE;
13671 })
13672
13673 (define_expand "call_value"
13674   [(set (match_operand 0 "" "")
13675         (call (match_operand:QI 1 "" "")
13676               (match_operand:SI 2 "" "")))
13677    (use (match_operand:SI 3 "" ""))]
13678   ;; Operand 3 is not used on the i386.
13679   ""
13680 {
13681   ix86_expand_call (operands[0], operands[1], operands[2],
13682                     operands[3], NULL, 0);
13683   DONE;
13684 })
13685
13686 (define_expand "sibcall_value"
13687   [(set (match_operand 0 "" "")
13688         (call (match_operand:QI 1 "" "")
13689               (match_operand:SI 2 "" "")))
13690    (use (match_operand:SI 3 "" ""))]
13691   ;; Operand 3 is not used on the i386.
13692   ""
13693 {
13694   ix86_expand_call (operands[0], operands[1], operands[2],
13695                     operands[3], NULL, 1);
13696   DONE;
13697 })
13698
13699 ;; Call subroutine returning any type.
13700
13701 (define_expand "untyped_call"
13702   [(parallel [(call (match_operand 0 "" "")
13703                     (const_int 0))
13704               (match_operand 1 "" "")
13705               (match_operand 2 "" "")])]
13706   ""
13707 {
13708   int i;
13709
13710   /* In order to give reg-stack an easier job in validating two
13711      coprocessor registers as containing a possible return value,
13712      simply pretend the untyped call returns a complex long double
13713      value. 
13714
13715      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13716      and should have the default ABI.  */
13717
13718   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13719                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13720                     operands[0], const0_rtx,
13721                     GEN_INT ((TARGET_64BIT
13722                               ? (ix86_abi == SYSV_ABI
13723                                  ? X86_64_SSE_REGPARM_MAX
13724                                  : X86_64_MS_SSE_REGPARM_MAX)
13725                               : X86_32_SSE_REGPARM_MAX)
13726                              - 1),
13727                     NULL, 0);
13728
13729   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13730     {
13731       rtx set = XVECEXP (operands[2], 0, i);
13732       emit_move_insn (SET_DEST (set), SET_SRC (set));
13733     }
13734
13735   /* The optimizer does not know that the call sets the function value
13736      registers we stored in the result block.  We avoid problems by
13737      claiming that all hard registers are used and clobbered at this
13738      point.  */
13739   emit_insn (gen_blockage ());
13740
13741   DONE;
13742 })
13743 \f
13744 ;; Prologue and epilogue instructions
13745
13746 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13747 ;; all of memory.  This blocks insns from being moved across this point.
13748
13749 (define_insn "blockage"
13750   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13751   ""
13752   ""
13753   [(set_attr "length" "0")])
13754
13755 ;; Do not schedule instructions accessing memory across this point.
13756
13757 (define_expand "memory_blockage"
13758   [(set (match_dup 0)
13759         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13760   ""
13761 {
13762   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13763   MEM_VOLATILE_P (operands[0]) = 1;
13764 })
13765
13766 (define_insn "*memory_blockage"
13767   [(set (match_operand:BLK 0 "" "")
13768         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13769   ""
13770   ""
13771   [(set_attr "length" "0")])
13772
13773 ;; As USE insns aren't meaningful after reload, this is used instead
13774 ;; to prevent deleting instructions setting registers for PIC code
13775 (define_insn "prologue_use"
13776   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13777   ""
13778   ""
13779   [(set_attr "length" "0")])
13780
13781 ;; Insn emitted into the body of a function to return from a function.
13782 ;; This is only done if the function's epilogue is known to be simple.
13783 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13784
13785 (define_expand "return"
13786   [(return)]
13787   "ix86_can_use_return_insn_p ()"
13788 {
13789   if (crtl->args.pops_args)
13790     {
13791       rtx popc = GEN_INT (crtl->args.pops_args);
13792       emit_jump_insn (gen_return_pop_internal (popc));
13793       DONE;
13794     }
13795 })
13796
13797 (define_insn "return_internal"
13798   [(return)]
13799   "reload_completed"
13800   "ret"
13801   [(set_attr "length" "1")
13802    (set_attr "atom_unit" "jeu")
13803    (set_attr "length_immediate" "0")
13804    (set_attr "modrm" "0")])
13805
13806 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13807 ;; instruction Athlon and K8 have.
13808
13809 (define_insn "return_internal_long"
13810   [(return)
13811    (unspec [(const_int 0)] UNSPEC_REP)]
13812   "reload_completed"
13813   "rep\;ret"
13814   [(set_attr "length" "2")
13815    (set_attr "atom_unit" "jeu")
13816    (set_attr "length_immediate" "0")
13817    (set_attr "prefix_rep" "1")
13818    (set_attr "modrm" "0")])
13819
13820 (define_insn "return_pop_internal"
13821   [(return)
13822    (use (match_operand:SI 0 "const_int_operand" ""))]
13823   "reload_completed"
13824   "ret\t%0"
13825   [(set_attr "length" "3")
13826    (set_attr "atom_unit" "jeu")
13827    (set_attr "length_immediate" "2")
13828    (set_attr "modrm" "0")])
13829
13830 (define_insn "return_indirect_internal"
13831   [(return)
13832    (use (match_operand:SI 0 "register_operand" "r"))]
13833   "reload_completed"
13834   "jmp\t%A0"
13835   [(set_attr "type" "ibr")
13836    (set_attr "length_immediate" "0")])
13837
13838 (define_insn "nop"
13839   [(const_int 0)]
13840   ""
13841   "nop"
13842   [(set_attr "length" "1")
13843    (set_attr "length_immediate" "0")
13844    (set_attr "modrm" "0")])
13845
13846 (define_insn "vswapmov"
13847   [(set (match_operand:SI 0 "register_operand" "=r")
13848         (match_operand:SI 1 "register_operand" "r"))
13849    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13850   ""
13851   "movl.s\t{%1, %0|%0, %1}"
13852   [(set_attr "length" "2")
13853    (set_attr "length_immediate" "0")
13854    (set_attr "modrm" "0")])
13855
13856 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13857 ;; branch prediction penalty for the third jump in a 16-byte
13858 ;; block on K8.
13859
13860 (define_insn "pad"
13861   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13862   ""
13863 {
13864 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13865   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13866 #else
13867   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13868      The align insn is used to avoid 3 jump instructions in the row to improve
13869      branch prediction and the benefits hardly outweigh the cost of extra 8
13870      nops on the average inserted by full alignment pseudo operation.  */
13871 #endif
13872   return "";
13873 }
13874   [(set_attr "length" "16")])
13875
13876 (define_expand "prologue"
13877   [(const_int 0)]
13878   ""
13879   "ix86_expand_prologue (); DONE;")
13880
13881 (define_insn "set_got"
13882   [(set (match_operand:SI 0 "register_operand" "=r")
13883         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13884    (clobber (reg:CC FLAGS_REG))]
13885   "!TARGET_64BIT"
13886   { return output_set_got (operands[0], NULL_RTX); }
13887   [(set_attr "type" "multi")
13888    (set_attr "length" "12")])
13889
13890 (define_insn "set_got_labelled"
13891   [(set (match_operand:SI 0 "register_operand" "=r")
13892         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13893          UNSPEC_SET_GOT))
13894    (clobber (reg:CC FLAGS_REG))]
13895   "!TARGET_64BIT"
13896   { return output_set_got (operands[0], operands[1]); }
13897   [(set_attr "type" "multi")
13898    (set_attr "length" "12")])
13899
13900 (define_insn "set_got_rex64"
13901   [(set (match_operand:DI 0 "register_operand" "=r")
13902         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13903   "TARGET_64BIT"
13904   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13905   [(set_attr "type" "lea")
13906    (set_attr "length_address" "4")
13907    (set_attr "mode" "DI")])
13908
13909 (define_insn "set_rip_rex64"
13910   [(set (match_operand:DI 0 "register_operand" "=r")
13911         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13912   "TARGET_64BIT"
13913   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13914   [(set_attr "type" "lea")
13915    (set_attr "length_address" "4")
13916    (set_attr "mode" "DI")])
13917
13918 (define_insn "set_got_offset_rex64"
13919   [(set (match_operand:DI 0 "register_operand" "=r")
13920         (unspec:DI
13921           [(label_ref (match_operand 1 "" ""))]
13922           UNSPEC_SET_GOT_OFFSET))]
13923   "TARGET_64BIT"
13924   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13925   [(set_attr "type" "imov")
13926    (set_attr "length_immediate" "0")
13927    (set_attr "length_address" "8")
13928    (set_attr "mode" "DI")])
13929
13930 (define_expand "epilogue"
13931   [(const_int 0)]
13932   ""
13933   "ix86_expand_epilogue (1); DONE;")
13934
13935 (define_expand "sibcall_epilogue"
13936   [(const_int 0)]
13937   ""
13938   "ix86_expand_epilogue (0); DONE;")
13939
13940 (define_expand "eh_return"
13941   [(use (match_operand 0 "register_operand" ""))]
13942   ""
13943 {
13944   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13945
13946   /* Tricky bit: we write the address of the handler to which we will
13947      be returning into someone else's stack frame, one word below the
13948      stack address we wish to restore.  */
13949   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13950   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13951   tmp = gen_rtx_MEM (Pmode, tmp);
13952   emit_move_insn (tmp, ra);
13953
13954   emit_jump_insn (gen_eh_return_internal ());
13955   emit_barrier ();
13956   DONE;
13957 })
13958
13959 (define_insn_and_split "eh_return_internal"
13960   [(eh_return)]
13961   ""
13962   "#"
13963   "epilogue_completed"
13964   [(const_int 0)]
13965   "ix86_expand_epilogue (2); DONE;")
13966
13967 (define_insn "leave"
13968   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13969    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13970    (clobber (mem:BLK (scratch)))]
13971   "!TARGET_64BIT"
13972   "leave"
13973   [(set_attr "type" "leave")])
13974
13975 (define_insn "leave_rex64"
13976   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13977    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13978    (clobber (mem:BLK (scratch)))]
13979   "TARGET_64BIT"
13980   "leave"
13981   [(set_attr "type" "leave")])
13982 \f
13983 (define_expand "ffssi2"
13984   [(parallel
13985      [(set (match_operand:SI 0 "register_operand" "")
13986            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13987       (clobber (match_scratch:SI 2 ""))
13988       (clobber (reg:CC FLAGS_REG))])]
13989   ""
13990 {
13991   if (TARGET_CMOVE)
13992     {
13993       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13994       DONE;
13995     }
13996 })
13997
13998 (define_expand "ffs_cmove"
13999   [(set (match_dup 2) (const_int -1))
14000    (parallel [(set (reg:CCZ FLAGS_REG)
14001                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14002                                 (const_int 0)))
14003               (set (match_operand:SI 0 "register_operand" "")
14004                    (ctz:SI (match_dup 1)))])
14005    (set (match_dup 0) (if_then_else:SI
14006                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14007                         (match_dup 2)
14008                         (match_dup 0)))
14009    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14010               (clobber (reg:CC FLAGS_REG))])]
14011   "TARGET_CMOVE"
14012   "operands[2] = gen_reg_rtx (SImode);")
14013
14014 (define_insn_and_split "*ffs_no_cmove"
14015   [(set (match_operand:SI 0 "register_operand" "=r")
14016         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14017    (clobber (match_scratch:SI 2 "=&q"))
14018    (clobber (reg:CC FLAGS_REG))]
14019   "!TARGET_CMOVE"
14020   "#"
14021   "&& reload_completed"
14022   [(parallel [(set (reg:CCZ FLAGS_REG)
14023                    (compare:CCZ (match_dup 1) (const_int 0)))
14024               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025    (set (strict_low_part (match_dup 3))
14026         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028               (clobber (reg:CC FLAGS_REG))])
14029    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030               (clobber (reg:CC FLAGS_REG))])
14031    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14033 {
14034   operands[3] = gen_lowpart (QImode, operands[2]);
14035   ix86_expand_clear (operands[2]);
14036 })
14037
14038 (define_insn "*ffssi_1"
14039   [(set (reg:CCZ FLAGS_REG)
14040         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14041                      (const_int 0)))
14042    (set (match_operand:SI 0 "register_operand" "=r")
14043         (ctz:SI (match_dup 1)))]
14044   ""
14045   "bsf{l}\t{%1, %0|%0, %1}"
14046   [(set_attr "type" "alu1")
14047    (set_attr "prefix_0f" "1")
14048    (set_attr "mode" "SI")])
14049
14050 (define_expand "ffsdi2"
14051   [(set (match_dup 2) (const_int -1))
14052    (parallel [(set (reg:CCZ FLAGS_REG)
14053                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14054                                 (const_int 0)))
14055               (set (match_operand:DI 0 "register_operand" "")
14056                    (ctz:DI (match_dup 1)))])
14057    (set (match_dup 0) (if_then_else:DI
14058                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14059                         (match_dup 2)
14060                         (match_dup 0)))
14061    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14062               (clobber (reg:CC FLAGS_REG))])]
14063   "TARGET_64BIT"
14064   "operands[2] = gen_reg_rtx (DImode);")
14065
14066 (define_insn "*ffsdi_1"
14067   [(set (reg:CCZ FLAGS_REG)
14068         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14069                      (const_int 0)))
14070    (set (match_operand:DI 0 "register_operand" "=r")
14071         (ctz:DI (match_dup 1)))]
14072   "TARGET_64BIT"
14073   "bsf{q}\t{%1, %0|%0, %1}"
14074   [(set_attr "type" "alu1")
14075    (set_attr "prefix_0f" "1")
14076    (set_attr "mode" "DI")])
14077
14078 (define_insn "ctzsi2"
14079   [(set (match_operand:SI 0 "register_operand" "=r")
14080         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14081    (clobber (reg:CC FLAGS_REG))]
14082   ""
14083   "bsf{l}\t{%1, %0|%0, %1}"
14084   [(set_attr "type" "alu1")
14085    (set_attr "prefix_0f" "1")
14086    (set_attr "mode" "SI")])
14087
14088 (define_insn "ctzdi2"
14089   [(set (match_operand:DI 0 "register_operand" "=r")
14090         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14091    (clobber (reg:CC FLAGS_REG))]
14092   "TARGET_64BIT"
14093   "bsf{q}\t{%1, %0|%0, %1}"
14094   [(set_attr "type" "alu1")
14095    (set_attr "prefix_0f" "1")
14096    (set_attr "mode" "DI")])
14097
14098 (define_expand "clzsi2"
14099   [(parallel
14100      [(set (match_operand:SI 0 "register_operand" "")
14101            (minus:SI (const_int 31)
14102                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14103       (clobber (reg:CC FLAGS_REG))])
14104    (parallel
14105      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14106       (clobber (reg:CC FLAGS_REG))])]
14107   ""
14108 {
14109   if (TARGET_ABM)
14110     {
14111       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14112       DONE;
14113     }
14114 })
14115
14116 (define_insn "clzsi2_abm"
14117   [(set (match_operand:SI 0 "register_operand" "=r")
14118         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14119    (clobber (reg:CC FLAGS_REG))]
14120   "TARGET_ABM"
14121   "lzcnt{l}\t{%1, %0|%0, %1}"
14122   [(set_attr "prefix_rep" "1")
14123    (set_attr "type" "bitmanip")
14124    (set_attr "mode" "SI")])
14125
14126 (define_insn "bsr"
14127   [(set (match_operand:SI 0 "register_operand" "=r")
14128         (minus:SI (const_int 31)
14129                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14130    (clobber (reg:CC FLAGS_REG))]
14131   ""
14132   "bsr{l}\t{%1, %0|%0, %1}"
14133   [(set_attr "type" "alu1")
14134    (set_attr "prefix_0f" "1")
14135    (set_attr "mode" "SI")])
14136
14137 (define_insn "popcount<mode>2"
14138   [(set (match_operand:SWI248 0 "register_operand" "=r")
14139         (popcount:SWI248
14140           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14141    (clobber (reg:CC FLAGS_REG))]
14142   "TARGET_POPCNT"
14143 {
14144 #if TARGET_MACHO
14145   return "popcnt\t{%1, %0|%0, %1}";
14146 #else
14147   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14148 #endif
14149 }
14150   [(set_attr "prefix_rep" "1")
14151    (set_attr "type" "bitmanip")
14152    (set_attr "mode" "<MODE>")])
14153
14154 (define_insn "*popcount<mode>2_cmp"
14155   [(set (reg FLAGS_REG)
14156         (compare
14157           (popcount:SWI248
14158             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14159           (const_int 0)))
14160    (set (match_operand:SWI248 0 "register_operand" "=r")
14161         (popcount:SWI248 (match_dup 1)))]
14162   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14163 {
14164 #if TARGET_MACHO
14165   return "popcnt\t{%1, %0|%0, %1}";
14166 #else
14167   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14168 #endif
14169 }
14170   [(set_attr "prefix_rep" "1")
14171    (set_attr "type" "bitmanip")
14172    (set_attr "mode" "<MODE>")])
14173
14174 (define_insn "*popcountsi2_cmp_zext"
14175   [(set (reg FLAGS_REG)
14176         (compare
14177           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14178           (const_int 0)))
14179    (set (match_operand:DI 0 "register_operand" "=r")
14180         (zero_extend:DI(popcount:SI (match_dup 1))))]
14181   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14182 {
14183 #if TARGET_MACHO
14184   return "popcnt\t{%1, %0|%0, %1}";
14185 #else
14186   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14187 #endif
14188 }
14189   [(set_attr "prefix_rep" "1")
14190    (set_attr "type" "bitmanip")
14191    (set_attr "mode" "SI")])
14192
14193 (define_expand "bswapsi2"
14194   [(set (match_operand:SI 0 "register_operand" "")
14195         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14196   ""
14197 {
14198   if (!(TARGET_BSWAP || TARGET_MOVBE))
14199     {
14200       rtx x = operands[0];
14201
14202       emit_move_insn (x, operands[1]);
14203       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14204       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14205       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14206       DONE;
14207     }
14208 })
14209
14210 (define_insn "*bswapsi_movbe"
14211   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14212         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14213   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14214   "@
14215     bswap\t%0
14216     movbe\t{%1, %0|%0, %1}
14217     movbe\t{%1, %0|%0, %1}"
14218   [(set_attr "type" "*,imov,imov")
14219    (set_attr "modrm" "*,1,1")
14220    (set_attr "prefix_0f" "1")
14221    (set_attr "prefix_extra" "*,1,1")
14222    (set_attr "length" "2,*,*")
14223    (set_attr "mode" "SI")])
14224
14225 (define_insn "*bswapsi_1"
14226   [(set (match_operand:SI 0 "register_operand" "=r")
14227         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14228   "TARGET_BSWAP"
14229   "bswap\t%0"
14230   [(set_attr "prefix_0f" "1")
14231    (set_attr "length" "2")])
14232
14233 (define_insn "*bswaphi_lowpart_1"
14234   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14235         (bswap:HI (match_dup 0)))
14236    (clobber (reg:CC FLAGS_REG))]
14237   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14238   "@
14239     xchg{b}\t{%h0, %b0|%b0, %h0}
14240     rol{w}\t{$8, %0|%0, 8}"
14241   [(set_attr "length" "2,4")
14242    (set_attr "mode" "QI,HI")])
14243
14244 (define_insn "bswaphi_lowpart"
14245   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14246         (bswap:HI (match_dup 0)))
14247    (clobber (reg:CC FLAGS_REG))]
14248   ""
14249   "rol{w}\t{$8, %0|%0, 8}"
14250   [(set_attr "length" "4")
14251    (set_attr "mode" "HI")])
14252
14253 (define_expand "bswapdi2"
14254   [(set (match_operand:DI 0 "register_operand" "")
14255         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14256   "TARGET_64BIT"
14257   "")
14258
14259 (define_insn "*bswapdi_movbe"
14260   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14261         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14262   "TARGET_64BIT && TARGET_MOVBE
14263    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14264   "@
14265     bswap\t%0
14266     movbe\t{%1, %0|%0, %1}
14267     movbe\t{%1, %0|%0, %1}"
14268   [(set_attr "type" "*,imov,imov")
14269    (set_attr "modrm" "*,1,1")
14270    (set_attr "prefix_0f" "1")
14271    (set_attr "prefix_extra" "*,1,1")
14272    (set_attr "length" "3,*,*")
14273    (set_attr "mode" "DI")])
14274
14275 (define_insn "*bswapdi_1"
14276   [(set (match_operand:DI 0 "register_operand" "=r")
14277         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14278   "TARGET_64BIT"
14279   "bswap\t%0"
14280   [(set_attr "prefix_0f" "1")
14281    (set_attr "length" "3")])
14282
14283 (define_expand "clzdi2"
14284   [(parallel
14285      [(set (match_operand:DI 0 "register_operand" "")
14286            (minus:DI (const_int 63)
14287                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14288       (clobber (reg:CC FLAGS_REG))])
14289    (parallel
14290      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14291       (clobber (reg:CC FLAGS_REG))])]
14292   "TARGET_64BIT"
14293 {
14294   if (TARGET_ABM)
14295     {
14296       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14297       DONE;
14298     }
14299 })
14300
14301 (define_insn "clzdi2_abm"
14302   [(set (match_operand:DI 0 "register_operand" "=r")
14303         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14304    (clobber (reg:CC FLAGS_REG))]
14305   "TARGET_64BIT && TARGET_ABM"
14306   "lzcnt{q}\t{%1, %0|%0, %1}"
14307   [(set_attr "prefix_rep" "1")
14308    (set_attr "type" "bitmanip")
14309    (set_attr "mode" "DI")])
14310
14311 (define_insn "bsr_rex64"
14312   [(set (match_operand:DI 0 "register_operand" "=r")
14313         (minus:DI (const_int 63)
14314                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14315    (clobber (reg:CC FLAGS_REG))]
14316   "TARGET_64BIT"
14317   "bsr{q}\t{%1, %0|%0, %1}"
14318   [(set_attr "type" "alu1")
14319    (set_attr "prefix_0f" "1")
14320    (set_attr "mode" "DI")])
14321
14322 (define_expand "clzhi2"
14323   [(parallel
14324      [(set (match_operand:HI 0 "register_operand" "")
14325            (minus:HI (const_int 15)
14326                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14327       (clobber (reg:CC FLAGS_REG))])
14328    (parallel
14329      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14330       (clobber (reg:CC FLAGS_REG))])]
14331   ""
14332 {
14333   if (TARGET_ABM)
14334     {
14335       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14336       DONE;
14337     }
14338 })
14339
14340 (define_insn "clzhi2_abm"
14341   [(set (match_operand:HI 0 "register_operand" "=r")
14342         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14343    (clobber (reg:CC FLAGS_REG))]
14344   "TARGET_ABM"
14345   "lzcnt{w}\t{%1, %0|%0, %1}"
14346   [(set_attr "prefix_rep" "1")
14347    (set_attr "type" "bitmanip")
14348    (set_attr "mode" "HI")])
14349
14350 (define_insn "*bsrhi"
14351   [(set (match_operand:HI 0 "register_operand" "=r")
14352         (minus:HI (const_int 15)
14353                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14354    (clobber (reg:CC FLAGS_REG))]
14355   ""
14356   "bsr{w}\t{%1, %0|%0, %1}"
14357   [(set_attr "type" "alu1")
14358    (set_attr "prefix_0f" "1")
14359    (set_attr "mode" "HI")])
14360
14361 (define_expand "paritydi2"
14362   [(set (match_operand:DI 0 "register_operand" "")
14363         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14364   "! TARGET_POPCNT"
14365 {
14366   rtx scratch = gen_reg_rtx (QImode);
14367   rtx cond;
14368
14369   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14370                                 NULL_RTX, operands[1]));
14371
14372   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14373                          gen_rtx_REG (CCmode, FLAGS_REG),
14374                          const0_rtx);
14375   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14376
14377   if (TARGET_64BIT)
14378     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14379   else
14380     {
14381       rtx tmp = gen_reg_rtx (SImode);
14382
14383       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14384       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14385     }
14386   DONE;
14387 })
14388
14389 (define_insn_and_split "paritydi2_cmp"
14390   [(set (reg:CC FLAGS_REG)
14391         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14392    (clobber (match_scratch:DI 0 "=r"))
14393    (clobber (match_scratch:SI 1 "=&r"))
14394    (clobber (match_scratch:HI 2 "=Q"))]
14395   "! TARGET_POPCNT"
14396   "#"
14397   "&& reload_completed"
14398   [(parallel
14399      [(set (match_dup 1)
14400            (xor:SI (match_dup 1) (match_dup 4)))
14401       (clobber (reg:CC FLAGS_REG))])
14402    (parallel
14403      [(set (reg:CC FLAGS_REG)
14404            (parity:CC (match_dup 1)))
14405       (clobber (match_dup 1))
14406       (clobber (match_dup 2))])]
14407 {
14408   operands[4] = gen_lowpart (SImode, operands[3]);
14409
14410   if (TARGET_64BIT)
14411     {
14412       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14413       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14414     }
14415   else
14416     operands[1] = gen_highpart (SImode, operands[3]);
14417 })
14418
14419 (define_expand "paritysi2"
14420   [(set (match_operand:SI 0 "register_operand" "")
14421         (parity:SI (match_operand:SI 1 "register_operand" "")))]
14422   "! TARGET_POPCNT"
14423 {
14424   rtx scratch = gen_reg_rtx (QImode);
14425   rtx cond;
14426
14427   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14428
14429   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14430                          gen_rtx_REG (CCmode, FLAGS_REG),
14431                          const0_rtx);
14432   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14433
14434   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14435   DONE;
14436 })
14437
14438 (define_insn_and_split "paritysi2_cmp"
14439   [(set (reg:CC FLAGS_REG)
14440         (parity:CC (match_operand:SI 2 "register_operand" "0")))
14441    (clobber (match_scratch:SI 0 "=r"))
14442    (clobber (match_scratch:HI 1 "=&Q"))]
14443   "! TARGET_POPCNT"
14444   "#"
14445   "&& reload_completed"
14446   [(parallel
14447      [(set (match_dup 1)
14448            (xor:HI (match_dup 1) (match_dup 3)))
14449       (clobber (reg:CC FLAGS_REG))])
14450    (parallel
14451      [(set (reg:CC FLAGS_REG)
14452            (parity:CC (match_dup 1)))
14453       (clobber (match_dup 1))])]
14454 {
14455   operands[3] = gen_lowpart (HImode, operands[2]);
14456
14457   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14458   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14459 })
14460
14461 (define_insn "*parityhi2_cmp"
14462   [(set (reg:CC FLAGS_REG)
14463         (parity:CC (match_operand:HI 1 "register_operand" "0")))
14464    (clobber (match_scratch:HI 0 "=Q"))]
14465   "! TARGET_POPCNT"
14466   "xor{b}\t{%h0, %b0|%b0, %h0}"
14467   [(set_attr "length" "2")
14468    (set_attr "mode" "HI")])
14469
14470 (define_insn "*parityqi2_cmp"
14471   [(set (reg:CC FLAGS_REG)
14472         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14473   "! TARGET_POPCNT"
14474   "test{b}\t%0, %0"
14475   [(set_attr "length" "2")
14476    (set_attr "mode" "QI")])
14477 \f
14478 ;; Thread-local storage patterns for ELF.
14479 ;;
14480 ;; Note that these code sequences must appear exactly as shown
14481 ;; in order to allow linker relaxation.
14482
14483 (define_insn "*tls_global_dynamic_32_gnu"
14484   [(set (match_operand:SI 0 "register_operand" "=a")
14485         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14486                     (match_operand:SI 2 "tls_symbolic_operand" "")
14487                     (match_operand:SI 3 "call_insn_operand" "")]
14488                     UNSPEC_TLS_GD))
14489    (clobber (match_scratch:SI 4 "=d"))
14490    (clobber (match_scratch:SI 5 "=c"))
14491    (clobber (reg:CC FLAGS_REG))]
14492   "!TARGET_64BIT && TARGET_GNU_TLS"
14493   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14494   [(set_attr "type" "multi")
14495    (set_attr "length" "12")])
14496
14497 (define_insn "*tls_global_dynamic_32_sun"
14498   [(set (match_operand:SI 0 "register_operand" "=a")
14499         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14500                     (match_operand:SI 2 "tls_symbolic_operand" "")
14501                     (match_operand:SI 3 "call_insn_operand" "")]
14502                     UNSPEC_TLS_GD))
14503    (clobber (match_scratch:SI 4 "=d"))
14504    (clobber (match_scratch:SI 5 "=c"))
14505    (clobber (reg:CC FLAGS_REG))]
14506   "!TARGET_64BIT && TARGET_SUN_TLS"
14507   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14508         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14509   [(set_attr "type" "multi")
14510    (set_attr "length" "14")])
14511
14512 (define_expand "tls_global_dynamic_32"
14513   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14514                    (unspec:SI
14515                     [(match_dup 2)
14516                      (match_operand:SI 1 "tls_symbolic_operand" "")
14517                      (match_dup 3)]
14518                     UNSPEC_TLS_GD))
14519               (clobber (match_scratch:SI 4 ""))
14520               (clobber (match_scratch:SI 5 ""))
14521               (clobber (reg:CC FLAGS_REG))])]
14522   ""
14523 {
14524   if (flag_pic)
14525     operands[2] = pic_offset_table_rtx;
14526   else
14527     {
14528       operands[2] = gen_reg_rtx (Pmode);
14529       emit_insn (gen_set_got (operands[2]));
14530     }
14531   if (TARGET_GNU2_TLS)
14532     {
14533        emit_insn (gen_tls_dynamic_gnu2_32
14534                   (operands[0], operands[1], operands[2]));
14535        DONE;
14536     }
14537   operands[3] = ix86_tls_get_addr ();
14538 })
14539
14540 (define_insn "*tls_global_dynamic_64"
14541   [(set (match_operand:DI 0 "register_operand" "=a")
14542         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14543                  (match_operand:DI 3 "" "")))
14544    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14545               UNSPEC_TLS_GD)]
14546   "TARGET_64BIT"
14547   { 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"; }
14548   [(set_attr "type" "multi")
14549    (set_attr "length" "16")])
14550
14551 (define_expand "tls_global_dynamic_64"
14552   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14553                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14554               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14555                          UNSPEC_TLS_GD)])]
14556   ""
14557 {
14558   if (TARGET_GNU2_TLS)
14559     {
14560        emit_insn (gen_tls_dynamic_gnu2_64
14561                   (operands[0], operands[1]));
14562        DONE;
14563     }
14564   operands[2] = ix86_tls_get_addr ();
14565 })
14566
14567 (define_insn "*tls_local_dynamic_base_32_gnu"
14568   [(set (match_operand:SI 0 "register_operand" "=a")
14569         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14570                     (match_operand:SI 2 "call_insn_operand" "")]
14571                    UNSPEC_TLS_LD_BASE))
14572    (clobber (match_scratch:SI 3 "=d"))
14573    (clobber (match_scratch:SI 4 "=c"))
14574    (clobber (reg:CC FLAGS_REG))]
14575   "!TARGET_64BIT && TARGET_GNU_TLS"
14576   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14577   [(set_attr "type" "multi")
14578    (set_attr "length" "11")])
14579
14580 (define_insn "*tls_local_dynamic_base_32_sun"
14581   [(set (match_operand:SI 0 "register_operand" "=a")
14582         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14583                     (match_operand:SI 2 "call_insn_operand" "")]
14584                    UNSPEC_TLS_LD_BASE))
14585    (clobber (match_scratch:SI 3 "=d"))
14586    (clobber (match_scratch:SI 4 "=c"))
14587    (clobber (reg:CC FLAGS_REG))]
14588   "!TARGET_64BIT && TARGET_SUN_TLS"
14589   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14590         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14591   [(set_attr "type" "multi")
14592    (set_attr "length" "13")])
14593
14594 (define_expand "tls_local_dynamic_base_32"
14595   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14596                    (unspec:SI [(match_dup 1) (match_dup 2)]
14597                               UNSPEC_TLS_LD_BASE))
14598               (clobber (match_scratch:SI 3 ""))
14599               (clobber (match_scratch:SI 4 ""))
14600               (clobber (reg:CC FLAGS_REG))])]
14601   ""
14602 {
14603   if (flag_pic)
14604     operands[1] = pic_offset_table_rtx;
14605   else
14606     {
14607       operands[1] = gen_reg_rtx (Pmode);
14608       emit_insn (gen_set_got (operands[1]));
14609     }
14610   if (TARGET_GNU2_TLS)
14611     {
14612        emit_insn (gen_tls_dynamic_gnu2_32
14613                   (operands[0], ix86_tls_module_base (), operands[1]));
14614        DONE;
14615     }
14616   operands[2] = ix86_tls_get_addr ();
14617 })
14618
14619 (define_insn "*tls_local_dynamic_base_64"
14620   [(set (match_operand:DI 0 "register_operand" "=a")
14621         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14622                  (match_operand:DI 2 "" "")))
14623    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14624   "TARGET_64BIT"
14625   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
14626   [(set_attr "type" "multi")
14627    (set_attr "length" "12")])
14628
14629 (define_expand "tls_local_dynamic_base_64"
14630   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14631                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14632               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14633   ""
14634 {
14635   if (TARGET_GNU2_TLS)
14636     {
14637        emit_insn (gen_tls_dynamic_gnu2_64
14638                   (operands[0], ix86_tls_module_base ()));
14639        DONE;
14640     }
14641   operands[1] = ix86_tls_get_addr ();
14642 })
14643
14644 ;; Local dynamic of a single variable is a lose.  Show combine how
14645 ;; to convert that back to global dynamic.
14646
14647 (define_insn_and_split "*tls_local_dynamic_32_once"
14648   [(set (match_operand:SI 0 "register_operand" "=a")
14649         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14650                              (match_operand:SI 2 "call_insn_operand" "")]
14651                             UNSPEC_TLS_LD_BASE)
14652                  (const:SI (unspec:SI
14653                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14654                             UNSPEC_DTPOFF))))
14655    (clobber (match_scratch:SI 4 "=d"))
14656    (clobber (match_scratch:SI 5 "=c"))
14657    (clobber (reg:CC FLAGS_REG))]
14658   ""
14659   "#"
14660   ""
14661   [(parallel [(set (match_dup 0)
14662                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14663                               UNSPEC_TLS_GD))
14664               (clobber (match_dup 4))
14665               (clobber (match_dup 5))
14666               (clobber (reg:CC FLAGS_REG))])]
14667   "")
14668
14669 ;; Load and add the thread base pointer from %gs:0.
14670
14671 (define_insn "*load_tp_si"
14672   [(set (match_operand:SI 0 "register_operand" "=r")
14673         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14674   "!TARGET_64BIT"
14675   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14676   [(set_attr "type" "imov")
14677    (set_attr "modrm" "0")
14678    (set_attr "length" "7")
14679    (set_attr "memory" "load")
14680    (set_attr "imm_disp" "false")])
14681
14682 (define_insn "*add_tp_si"
14683   [(set (match_operand:SI 0 "register_operand" "=r")
14684         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14685                  (match_operand:SI 1 "register_operand" "0")))
14686    (clobber (reg:CC FLAGS_REG))]
14687   "!TARGET_64BIT"
14688   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14689   [(set_attr "type" "alu")
14690    (set_attr "modrm" "0")
14691    (set_attr "length" "7")
14692    (set_attr "memory" "load")
14693    (set_attr "imm_disp" "false")])
14694
14695 (define_insn "*load_tp_di"
14696   [(set (match_operand:DI 0 "register_operand" "=r")
14697         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14698   "TARGET_64BIT"
14699   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14700   [(set_attr "type" "imov")
14701    (set_attr "modrm" "0")
14702    (set_attr "length" "7")
14703    (set_attr "memory" "load")
14704    (set_attr "imm_disp" "false")])
14705
14706 (define_insn "*add_tp_di"
14707   [(set (match_operand:DI 0 "register_operand" "=r")
14708         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14709                  (match_operand:DI 1 "register_operand" "0")))
14710    (clobber (reg:CC FLAGS_REG))]
14711   "TARGET_64BIT"
14712   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14713   [(set_attr "type" "alu")
14714    (set_attr "modrm" "0")
14715    (set_attr "length" "7")
14716    (set_attr "memory" "load")
14717    (set_attr "imm_disp" "false")])
14718
14719 ;; GNU2 TLS patterns can be split.
14720
14721 (define_expand "tls_dynamic_gnu2_32"
14722   [(set (match_dup 3)
14723         (plus:SI (match_operand:SI 2 "register_operand" "")
14724                  (const:SI
14725                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14726                              UNSPEC_TLSDESC))))
14727    (parallel
14728     [(set (match_operand:SI 0 "register_operand" "")
14729           (unspec:SI [(match_dup 1) (match_dup 3)
14730                       (match_dup 2) (reg:SI SP_REG)]
14731                       UNSPEC_TLSDESC))
14732      (clobber (reg:CC FLAGS_REG))])]
14733   "!TARGET_64BIT && TARGET_GNU2_TLS"
14734 {
14735   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14736   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14737 })
14738
14739 (define_insn "*tls_dynamic_lea_32"
14740   [(set (match_operand:SI 0 "register_operand" "=r")
14741         (plus:SI (match_operand:SI 1 "register_operand" "b")
14742                  (const:SI
14743                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14744                               UNSPEC_TLSDESC))))]
14745   "!TARGET_64BIT && TARGET_GNU2_TLS"
14746   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14747   [(set_attr "type" "lea")
14748    (set_attr "mode" "SI")
14749    (set_attr "length" "6")
14750    (set_attr "length_address" "4")])
14751
14752 (define_insn "*tls_dynamic_call_32"
14753   [(set (match_operand:SI 0 "register_operand" "=a")
14754         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14755                     (match_operand:SI 2 "register_operand" "0")
14756                     ;; we have to make sure %ebx still points to the GOT
14757                     (match_operand:SI 3 "register_operand" "b")
14758                     (reg:SI SP_REG)]
14759                    UNSPEC_TLSDESC))
14760    (clobber (reg:CC FLAGS_REG))]
14761   "!TARGET_64BIT && TARGET_GNU2_TLS"
14762   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14763   [(set_attr "type" "call")
14764    (set_attr "length" "2")
14765    (set_attr "length_address" "0")])
14766
14767 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14768   [(set (match_operand:SI 0 "register_operand" "=&a")
14769         (plus:SI
14770          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14771                      (match_operand:SI 4 "" "")
14772                      (match_operand:SI 2 "register_operand" "b")
14773                      (reg:SI SP_REG)]
14774                     UNSPEC_TLSDESC)
14775          (const:SI (unspec:SI
14776                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14777                     UNSPEC_DTPOFF))))
14778    (clobber (reg:CC FLAGS_REG))]
14779   "!TARGET_64BIT && TARGET_GNU2_TLS"
14780   "#"
14781   ""
14782   [(set (match_dup 0) (match_dup 5))]
14783 {
14784   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14785   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14786 })
14787
14788 (define_expand "tls_dynamic_gnu2_64"
14789   [(set (match_dup 2)
14790         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14791                    UNSPEC_TLSDESC))
14792    (parallel
14793     [(set (match_operand:DI 0 "register_operand" "")
14794           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14795                      UNSPEC_TLSDESC))
14796      (clobber (reg:CC FLAGS_REG))])]
14797   "TARGET_64BIT && TARGET_GNU2_TLS"
14798 {
14799   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14800   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14801 })
14802
14803 (define_insn "*tls_dynamic_lea_64"
14804   [(set (match_operand:DI 0 "register_operand" "=r")
14805         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14806                    UNSPEC_TLSDESC))]
14807   "TARGET_64BIT && TARGET_GNU2_TLS"
14808   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14809   [(set_attr "type" "lea")
14810    (set_attr "mode" "DI")
14811    (set_attr "length" "7")
14812    (set_attr "length_address" "4")])
14813
14814 (define_insn "*tls_dynamic_call_64"
14815   [(set (match_operand:DI 0 "register_operand" "=a")
14816         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14817                     (match_operand:DI 2 "register_operand" "0")
14818                     (reg:DI SP_REG)]
14819                    UNSPEC_TLSDESC))
14820    (clobber (reg:CC FLAGS_REG))]
14821   "TARGET_64BIT && TARGET_GNU2_TLS"
14822   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14823   [(set_attr "type" "call")
14824    (set_attr "length" "2")
14825    (set_attr "length_address" "0")])
14826
14827 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14828   [(set (match_operand:DI 0 "register_operand" "=&a")
14829         (plus:DI
14830          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14831                      (match_operand:DI 3 "" "")
14832                      (reg:DI SP_REG)]
14833                     UNSPEC_TLSDESC)
14834          (const:DI (unspec:DI
14835                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14836                     UNSPEC_DTPOFF))))
14837    (clobber (reg:CC FLAGS_REG))]
14838   "TARGET_64BIT && TARGET_GNU2_TLS"
14839   "#"
14840   ""
14841   [(set (match_dup 0) (match_dup 4))]
14842 {
14843   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14844   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14845 })
14846
14847 ;;
14848 \f
14849 ;; These patterns match the binary 387 instructions for addM3, subM3,
14850 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14851 ;; SFmode.  The first is the normal insn, the second the same insn but
14852 ;; with one operand a conversion, and the third the same insn but with
14853 ;; the other operand a conversion.  The conversion may be SFmode or
14854 ;; SImode if the target mode DFmode, but only SImode if the target mode
14855 ;; is SFmode.
14856
14857 ;; Gcc is slightly more smart about handling normal two address instructions
14858 ;; so use special patterns for add and mull.
14859
14860 (define_insn "*fop_<mode>_comm_mixed_avx"
14861   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14862         (match_operator:MODEF 3 "binary_fp_operator"
14863           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14864            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14865   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14866    && COMMUTATIVE_ARITH_P (operands[3])
14867    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14868   "* return output_387_binary_op (insn, operands);"
14869   [(set (attr "type")
14870         (if_then_else (eq_attr "alternative" "1")
14871            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14872               (const_string "ssemul")
14873               (const_string "sseadd"))
14874            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14875               (const_string "fmul")
14876               (const_string "fop"))))
14877    (set_attr "prefix" "orig,maybe_vex")
14878    (set_attr "mode" "<MODE>")])
14879
14880 (define_insn "*fop_<mode>_comm_mixed"
14881   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14882         (match_operator:MODEF 3 "binary_fp_operator"
14883           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14884            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14885   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14886    && COMMUTATIVE_ARITH_P (operands[3])
14887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14888   "* return output_387_binary_op (insn, operands);"
14889   [(set (attr "type")
14890         (if_then_else (eq_attr "alternative" "1")
14891            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14892               (const_string "ssemul")
14893               (const_string "sseadd"))
14894            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14895               (const_string "fmul")
14896               (const_string "fop"))))
14897    (set_attr "mode" "<MODE>")])
14898
14899 (define_insn "*fop_<mode>_comm_avx"
14900   [(set (match_operand:MODEF 0 "register_operand" "=x")
14901         (match_operator:MODEF 3 "binary_fp_operator"
14902           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14903            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14904   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14905    && COMMUTATIVE_ARITH_P (operands[3])
14906    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14907   "* return output_387_binary_op (insn, operands);"
14908   [(set (attr "type")
14909         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14910            (const_string "ssemul")
14911            (const_string "sseadd")))
14912    (set_attr "prefix" "vex")
14913    (set_attr "mode" "<MODE>")])
14914
14915 (define_insn "*fop_<mode>_comm_sse"
14916   [(set (match_operand:MODEF 0 "register_operand" "=x")
14917         (match_operator:MODEF 3 "binary_fp_operator"
14918           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14919            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14920   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14921    && COMMUTATIVE_ARITH_P (operands[3])
14922    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14923   "* return output_387_binary_op (insn, operands);"
14924   [(set (attr "type")
14925         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14926            (const_string "ssemul")
14927            (const_string "sseadd")))
14928    (set_attr "mode" "<MODE>")])
14929
14930 (define_insn "*fop_<mode>_comm_i387"
14931   [(set (match_operand:MODEF 0 "register_operand" "=f")
14932         (match_operator:MODEF 3 "binary_fp_operator"
14933           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14934            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14935   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14936    && COMMUTATIVE_ARITH_P (operands[3])
14937    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14938   "* return output_387_binary_op (insn, operands);"
14939   [(set (attr "type")
14940         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14941            (const_string "fmul")
14942            (const_string "fop")))
14943    (set_attr "mode" "<MODE>")])
14944
14945 (define_insn "*fop_<mode>_1_mixed_avx"
14946   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14947         (match_operator:MODEF 3 "binary_fp_operator"
14948           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14949            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14950   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14951    && !COMMUTATIVE_ARITH_P (operands[3])
14952    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14953   "* return output_387_binary_op (insn, operands);"
14954   [(set (attr "type")
14955         (cond [(and (eq_attr "alternative" "2")
14956                     (match_operand:MODEF 3 "mult_operator" ""))
14957                  (const_string "ssemul")
14958                (and (eq_attr "alternative" "2")
14959                     (match_operand:MODEF 3 "div_operator" ""))
14960                  (const_string "ssediv")
14961                (eq_attr "alternative" "2")
14962                  (const_string "sseadd")
14963                (match_operand:MODEF 3 "mult_operator" "")
14964                  (const_string "fmul")
14965                (match_operand:MODEF 3 "div_operator" "")
14966                  (const_string "fdiv")
14967               ]
14968               (const_string "fop")))
14969    (set_attr "prefix" "orig,orig,maybe_vex")
14970    (set_attr "mode" "<MODE>")])
14971
14972 (define_insn "*fop_<mode>_1_mixed"
14973   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14974         (match_operator:MODEF 3 "binary_fp_operator"
14975           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14976            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14977   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14978    && !COMMUTATIVE_ARITH_P (operands[3])
14979    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14980   "* return output_387_binary_op (insn, operands);"
14981   [(set (attr "type")
14982         (cond [(and (eq_attr "alternative" "2")
14983                     (match_operand:MODEF 3 "mult_operator" ""))
14984                  (const_string "ssemul")
14985                (and (eq_attr "alternative" "2")
14986                     (match_operand:MODEF 3 "div_operator" ""))
14987                  (const_string "ssediv")
14988                (eq_attr "alternative" "2")
14989                  (const_string "sseadd")
14990                (match_operand:MODEF 3 "mult_operator" "")
14991                  (const_string "fmul")
14992                (match_operand:MODEF 3 "div_operator" "")
14993                  (const_string "fdiv")
14994               ]
14995               (const_string "fop")))
14996    (set_attr "mode" "<MODE>")])
14997
14998 (define_insn "*rcpsf2_sse"
14999   [(set (match_operand:SF 0 "register_operand" "=x")
15000         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15001                    UNSPEC_RCP))]
15002   "TARGET_SSE_MATH"
15003   "%vrcpss\t{%1, %d0|%d0, %1}"
15004   [(set_attr "type" "sse")
15005    (set_attr "atom_sse_attr" "rcp")
15006    (set_attr "prefix" "maybe_vex")
15007    (set_attr "mode" "SF")])
15008
15009 (define_insn "*fop_<mode>_1_avx"
15010   [(set (match_operand:MODEF 0 "register_operand" "=x")
15011         (match_operator:MODEF 3 "binary_fp_operator"
15012           [(match_operand:MODEF 1 "register_operand" "x")
15013            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15014   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15015    && !COMMUTATIVE_ARITH_P (operands[3])"
15016   "* return output_387_binary_op (insn, operands);"
15017   [(set (attr "type")
15018         (cond [(match_operand:MODEF 3 "mult_operator" "")
15019                  (const_string "ssemul")
15020                (match_operand:MODEF 3 "div_operator" "")
15021                  (const_string "ssediv")
15022               ]
15023               (const_string "sseadd")))
15024    (set_attr "prefix" "vex")
15025    (set_attr "mode" "<MODE>")])
15026
15027 (define_insn "*fop_<mode>_1_sse"
15028   [(set (match_operand:MODEF 0 "register_operand" "=x")
15029         (match_operator:MODEF 3 "binary_fp_operator"
15030           [(match_operand:MODEF 1 "register_operand" "0")
15031            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15032   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15033    && !COMMUTATIVE_ARITH_P (operands[3])"
15034   "* return output_387_binary_op (insn, operands);"
15035   [(set (attr "type")
15036         (cond [(match_operand:MODEF 3 "mult_operator" "")
15037                  (const_string "ssemul")
15038                (match_operand:MODEF 3 "div_operator" "")
15039                  (const_string "ssediv")
15040               ]
15041               (const_string "sseadd")))
15042    (set_attr "mode" "<MODE>")])
15043
15044 ;; This pattern is not fully shadowed by the pattern above.
15045 (define_insn "*fop_<mode>_1_i387"
15046   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15047         (match_operator:MODEF 3 "binary_fp_operator"
15048           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15049            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15050   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15051    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15052    && !COMMUTATIVE_ARITH_P (operands[3])
15053    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15054   "* return output_387_binary_op (insn, operands);"
15055   [(set (attr "type")
15056         (cond [(match_operand:MODEF 3 "mult_operator" "")
15057                  (const_string "fmul")
15058                (match_operand:MODEF 3 "div_operator" "")
15059                  (const_string "fdiv")
15060               ]
15061               (const_string "fop")))
15062    (set_attr "mode" "<MODE>")])
15063
15064 ;; ??? Add SSE splitters for these!
15065 (define_insn "*fop_<MODEF:mode>_2_i387"
15066   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15067         (match_operator:MODEF 3 "binary_fp_operator"
15068           [(float:MODEF
15069              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15070            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15071   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15072    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15073    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15074   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15075   [(set (attr "type")
15076         (cond [(match_operand:MODEF 3 "mult_operator" "")
15077                  (const_string "fmul")
15078                (match_operand:MODEF 3 "div_operator" "")
15079                  (const_string "fdiv")
15080               ]
15081               (const_string "fop")))
15082    (set_attr "fp_int_src" "true")
15083    (set_attr "mode" "<X87MODEI12:MODE>")])
15084
15085 (define_insn "*fop_<MODEF:mode>_3_i387"
15086   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15087         (match_operator:MODEF 3 "binary_fp_operator"
15088           [(match_operand:MODEF 1 "register_operand" "0,0")
15089            (float:MODEF
15090              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15091   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15092    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15093    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15094   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15095   [(set (attr "type")
15096         (cond [(match_operand:MODEF 3 "mult_operator" "")
15097                  (const_string "fmul")
15098                (match_operand:MODEF 3 "div_operator" "")
15099                  (const_string "fdiv")
15100               ]
15101               (const_string "fop")))
15102    (set_attr "fp_int_src" "true")
15103    (set_attr "mode" "<MODE>")])
15104
15105 (define_insn "*fop_df_4_i387"
15106   [(set (match_operand:DF 0 "register_operand" "=f,f")
15107         (match_operator:DF 3 "binary_fp_operator"
15108            [(float_extend:DF
15109              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15110             (match_operand:DF 2 "register_operand" "0,f")]))]
15111   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15112    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15113    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15114   "* return output_387_binary_op (insn, operands);"
15115   [(set (attr "type")
15116         (cond [(match_operand:DF 3 "mult_operator" "")
15117                  (const_string "fmul")
15118                (match_operand:DF 3 "div_operator" "")
15119                  (const_string "fdiv")
15120               ]
15121               (const_string "fop")))
15122    (set_attr "mode" "SF")])
15123
15124 (define_insn "*fop_df_5_i387"
15125   [(set (match_operand:DF 0 "register_operand" "=f,f")
15126         (match_operator:DF 3 "binary_fp_operator"
15127           [(match_operand:DF 1 "register_operand" "0,f")
15128            (float_extend:DF
15129             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15130   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15131    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15132   "* return output_387_binary_op (insn, operands);"
15133   [(set (attr "type")
15134         (cond [(match_operand:DF 3 "mult_operator" "")
15135                  (const_string "fmul")
15136                (match_operand:DF 3 "div_operator" "")
15137                  (const_string "fdiv")
15138               ]
15139               (const_string "fop")))
15140    (set_attr "mode" "SF")])
15141
15142 (define_insn "*fop_df_6_i387"
15143   [(set (match_operand:DF 0 "register_operand" "=f,f")
15144         (match_operator:DF 3 "binary_fp_operator"
15145           [(float_extend:DF
15146             (match_operand:SF 1 "register_operand" "0,f"))
15147            (float_extend:DF
15148             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15149   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15150    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15151   "* return output_387_binary_op (insn, operands);"
15152   [(set (attr "type")
15153         (cond [(match_operand:DF 3 "mult_operator" "")
15154                  (const_string "fmul")
15155                (match_operand:DF 3 "div_operator" "")
15156                  (const_string "fdiv")
15157               ]
15158               (const_string "fop")))
15159    (set_attr "mode" "SF")])
15160
15161 (define_insn "*fop_xf_comm_i387"
15162   [(set (match_operand:XF 0 "register_operand" "=f")
15163         (match_operator:XF 3 "binary_fp_operator"
15164                         [(match_operand:XF 1 "register_operand" "%0")
15165                          (match_operand:XF 2 "register_operand" "f")]))]
15166   "TARGET_80387
15167    && COMMUTATIVE_ARITH_P (operands[3])"
15168   "* return output_387_binary_op (insn, operands);"
15169   [(set (attr "type")
15170         (if_then_else (match_operand:XF 3 "mult_operator" "")
15171            (const_string "fmul")
15172            (const_string "fop")))
15173    (set_attr "mode" "XF")])
15174
15175 (define_insn "*fop_xf_1_i387"
15176   [(set (match_operand:XF 0 "register_operand" "=f,f")
15177         (match_operator:XF 3 "binary_fp_operator"
15178                         [(match_operand:XF 1 "register_operand" "0,f")
15179                          (match_operand:XF 2 "register_operand" "f,0")]))]
15180   "TARGET_80387
15181    && !COMMUTATIVE_ARITH_P (operands[3])"
15182   "* return output_387_binary_op (insn, operands);"
15183   [(set (attr "type")
15184         (cond [(match_operand:XF 3 "mult_operator" "")
15185                  (const_string "fmul")
15186                (match_operand:XF 3 "div_operator" "")
15187                  (const_string "fdiv")
15188               ]
15189               (const_string "fop")))
15190    (set_attr "mode" "XF")])
15191
15192 (define_insn "*fop_xf_2_i387"
15193   [(set (match_operand:XF 0 "register_operand" "=f,f")
15194         (match_operator:XF 3 "binary_fp_operator"
15195           [(float:XF
15196              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15197            (match_operand:XF 2 "register_operand" "0,0")]))]
15198   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15199   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15200   [(set (attr "type")
15201         (cond [(match_operand:XF 3 "mult_operator" "")
15202                  (const_string "fmul")
15203                (match_operand:XF 3 "div_operator" "")
15204                  (const_string "fdiv")
15205               ]
15206               (const_string "fop")))
15207    (set_attr "fp_int_src" "true")
15208    (set_attr "mode" "<MODE>")])
15209
15210 (define_insn "*fop_xf_3_i387"
15211   [(set (match_operand:XF 0 "register_operand" "=f,f")
15212         (match_operator:XF 3 "binary_fp_operator"
15213           [(match_operand:XF 1 "register_operand" "0,0")
15214            (float:XF
15215              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15216   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15217   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15218   [(set (attr "type")
15219         (cond [(match_operand:XF 3 "mult_operator" "")
15220                  (const_string "fmul")
15221                (match_operand:XF 3 "div_operator" "")
15222                  (const_string "fdiv")
15223               ]
15224               (const_string "fop")))
15225    (set_attr "fp_int_src" "true")
15226    (set_attr "mode" "<MODE>")])
15227
15228 (define_insn "*fop_xf_4_i387"
15229   [(set (match_operand:XF 0 "register_operand" "=f,f")
15230         (match_operator:XF 3 "binary_fp_operator"
15231            [(float_extend:XF
15232               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15233             (match_operand:XF 2 "register_operand" "0,f")]))]
15234   "TARGET_80387"
15235   "* return output_387_binary_op (insn, operands);"
15236   [(set (attr "type")
15237         (cond [(match_operand:XF 3 "mult_operator" "")
15238                  (const_string "fmul")
15239                (match_operand:XF 3 "div_operator" "")
15240                  (const_string "fdiv")
15241               ]
15242               (const_string "fop")))
15243    (set_attr "mode" "<MODE>")])
15244
15245 (define_insn "*fop_xf_5_i387"
15246   [(set (match_operand:XF 0 "register_operand" "=f,f")
15247         (match_operator:XF 3 "binary_fp_operator"
15248           [(match_operand:XF 1 "register_operand" "0,f")
15249            (float_extend:XF
15250              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15251   "TARGET_80387"
15252   "* return output_387_binary_op (insn, operands);"
15253   [(set (attr "type")
15254         (cond [(match_operand:XF 3 "mult_operator" "")
15255                  (const_string "fmul")
15256                (match_operand:XF 3 "div_operator" "")
15257                  (const_string "fdiv")
15258               ]
15259               (const_string "fop")))
15260    (set_attr "mode" "<MODE>")])
15261
15262 (define_insn "*fop_xf_6_i387"
15263   [(set (match_operand:XF 0 "register_operand" "=f,f")
15264         (match_operator:XF 3 "binary_fp_operator"
15265           [(float_extend:XF
15266              (match_operand:MODEF 1 "register_operand" "0,f"))
15267            (float_extend:XF
15268              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15269   "TARGET_80387"
15270   "* return output_387_binary_op (insn, operands);"
15271   [(set (attr "type")
15272         (cond [(match_operand:XF 3 "mult_operator" "")
15273                  (const_string "fmul")
15274                (match_operand:XF 3 "div_operator" "")
15275                  (const_string "fdiv")
15276               ]
15277               (const_string "fop")))
15278    (set_attr "mode" "<MODE>")])
15279
15280 (define_split
15281   [(set (match_operand 0 "register_operand" "")
15282         (match_operator 3 "binary_fp_operator"
15283            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15284             (match_operand 2 "register_operand" "")]))]
15285   "reload_completed
15286    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15287    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15288   [(const_int 0)]
15289 {
15290   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15291   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15292   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15293                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15294                                           GET_MODE (operands[3]),
15295                                           operands[4],
15296                                           operands[2])));
15297   ix86_free_from_memory (GET_MODE (operands[1]));
15298   DONE;
15299 })
15300
15301 (define_split
15302   [(set (match_operand 0 "register_operand" "")
15303         (match_operator 3 "binary_fp_operator"
15304            [(match_operand 1 "register_operand" "")
15305             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15306   "reload_completed
15307    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15308    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15309   [(const_int 0)]
15310 {
15311   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15312   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15313   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15314                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15315                                           GET_MODE (operands[3]),
15316                                           operands[1],
15317                                           operands[4])));
15318   ix86_free_from_memory (GET_MODE (operands[2]));
15319   DONE;
15320 })
15321 \f
15322 ;; FPU special functions.
15323
15324 ;; This pattern implements a no-op XFmode truncation for
15325 ;; all fancy i386 XFmode math functions.
15326
15327 (define_insn "truncxf<mode>2_i387_noop_unspec"
15328   [(set (match_operand:MODEF 0 "register_operand" "=f")
15329         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15330         UNSPEC_TRUNC_NOOP))]
15331   "TARGET_USE_FANCY_MATH_387"
15332   "* return output_387_reg_move (insn, operands);"
15333   [(set_attr "type" "fmov")
15334    (set_attr "mode" "<MODE>")])
15335
15336 (define_insn "sqrtxf2"
15337   [(set (match_operand:XF 0 "register_operand" "=f")
15338         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15339   "TARGET_USE_FANCY_MATH_387"
15340   "fsqrt"
15341   [(set_attr "type" "fpspc")
15342    (set_attr "mode" "XF")
15343    (set_attr "athlon_decode" "direct")
15344    (set_attr "amdfam10_decode" "direct")])
15345
15346 (define_insn "sqrt_extend<mode>xf2_i387"
15347   [(set (match_operand:XF 0 "register_operand" "=f")
15348         (sqrt:XF
15349           (float_extend:XF
15350             (match_operand:MODEF 1 "register_operand" "0"))))]
15351   "TARGET_USE_FANCY_MATH_387"
15352   "fsqrt"
15353   [(set_attr "type" "fpspc")
15354    (set_attr "mode" "XF")
15355    (set_attr "athlon_decode" "direct")
15356    (set_attr "amdfam10_decode" "direct")])
15357
15358 (define_insn "*rsqrtsf2_sse"
15359   [(set (match_operand:SF 0 "register_operand" "=x")
15360         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15361                    UNSPEC_RSQRT))]
15362   "TARGET_SSE_MATH"
15363   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15364   [(set_attr "type" "sse")
15365    (set_attr "atom_sse_attr" "rcp")
15366    (set_attr "prefix" "maybe_vex")
15367    (set_attr "mode" "SF")])
15368
15369 (define_expand "rsqrtsf2"
15370   [(set (match_operand:SF 0 "register_operand" "")
15371         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15372                    UNSPEC_RSQRT))]
15373   "TARGET_SSE_MATH"
15374 {
15375   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15376   DONE;
15377 })
15378
15379 (define_insn "*sqrt<mode>2_sse"
15380   [(set (match_operand:MODEF 0 "register_operand" "=x")
15381         (sqrt:MODEF
15382           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15383   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15384   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15385   [(set_attr "type" "sse")
15386    (set_attr "atom_sse_attr" "sqrt")
15387    (set_attr "prefix" "maybe_vex")
15388    (set_attr "mode" "<MODE>")
15389    (set_attr "athlon_decode" "*")
15390    (set_attr "amdfam10_decode" "*")])
15391
15392 (define_expand "sqrt<mode>2"
15393   [(set (match_operand:MODEF 0 "register_operand" "")
15394         (sqrt:MODEF
15395           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15396   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15397    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15398 {
15399   if (<MODE>mode == SFmode
15400       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15401       && flag_finite_math_only && !flag_trapping_math
15402       && flag_unsafe_math_optimizations)
15403     {
15404       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15405       DONE;
15406     }
15407
15408   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15409     {
15410       rtx op0 = gen_reg_rtx (XFmode);
15411       rtx op1 = force_reg (<MODE>mode, operands[1]);
15412
15413       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15414       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15415       DONE;
15416    }
15417 })
15418
15419 (define_insn "fpremxf4_i387"
15420   [(set (match_operand:XF 0 "register_operand" "=f")
15421         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15422                     (match_operand:XF 3 "register_operand" "1")]
15423                    UNSPEC_FPREM_F))
15424    (set (match_operand:XF 1 "register_operand" "=u")
15425         (unspec:XF [(match_dup 2) (match_dup 3)]
15426                    UNSPEC_FPREM_U))
15427    (set (reg:CCFP FPSR_REG)
15428         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15429                      UNSPEC_C2_FLAG))]
15430   "TARGET_USE_FANCY_MATH_387"
15431   "fprem"
15432   [(set_attr "type" "fpspc")
15433    (set_attr "mode" "XF")])
15434
15435 (define_expand "fmodxf3"
15436   [(use (match_operand:XF 0 "register_operand" ""))
15437    (use (match_operand:XF 1 "general_operand" ""))
15438    (use (match_operand:XF 2 "general_operand" ""))]
15439   "TARGET_USE_FANCY_MATH_387"
15440 {
15441   rtx label = gen_label_rtx ();
15442
15443   rtx op1 = gen_reg_rtx (XFmode);
15444   rtx op2 = gen_reg_rtx (XFmode);
15445
15446   emit_move_insn (op2, operands[2]);
15447   emit_move_insn (op1, operands[1]);
15448
15449   emit_label (label);
15450   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15451   ix86_emit_fp_unordered_jump (label);
15452   LABEL_NUSES (label) = 1;
15453
15454   emit_move_insn (operands[0], op1);
15455   DONE;
15456 })
15457
15458 (define_expand "fmod<mode>3"
15459   [(use (match_operand:MODEF 0 "register_operand" ""))
15460    (use (match_operand:MODEF 1 "general_operand" ""))
15461    (use (match_operand:MODEF 2 "general_operand" ""))]
15462   "TARGET_USE_FANCY_MATH_387"
15463 {
15464   rtx label = gen_label_rtx ();
15465
15466   rtx op1 = gen_reg_rtx (XFmode);
15467   rtx op2 = gen_reg_rtx (XFmode);
15468
15469   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15470   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15471
15472   emit_label (label);
15473   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15474   ix86_emit_fp_unordered_jump (label);
15475   LABEL_NUSES (label) = 1;
15476
15477   /* Truncate the result properly for strict SSE math.  */
15478   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15479       && !TARGET_MIX_SSE_I387)
15480     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15481   else
15482     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15483
15484   DONE;
15485 })
15486
15487 (define_insn "fprem1xf4_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490                     (match_operand:XF 3 "register_operand" "1")]
15491                    UNSPEC_FPREM1_F))
15492    (set (match_operand:XF 1 "register_operand" "=u")
15493         (unspec:XF [(match_dup 2) (match_dup 3)]
15494                    UNSPEC_FPREM1_U))
15495    (set (reg:CCFP FPSR_REG)
15496         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15497                      UNSPEC_C2_FLAG))]
15498   "TARGET_USE_FANCY_MATH_387"
15499   "fprem1"
15500   [(set_attr "type" "fpspc")
15501    (set_attr "mode" "XF")])
15502
15503 (define_expand "remainderxf3"
15504   [(use (match_operand:XF 0 "register_operand" ""))
15505    (use (match_operand:XF 1 "general_operand" ""))
15506    (use (match_operand:XF 2 "general_operand" ""))]
15507   "TARGET_USE_FANCY_MATH_387"
15508 {
15509   rtx label = gen_label_rtx ();
15510
15511   rtx op1 = gen_reg_rtx (XFmode);
15512   rtx op2 = gen_reg_rtx (XFmode);
15513
15514   emit_move_insn (op2, operands[2]);
15515   emit_move_insn (op1, operands[1]);
15516
15517   emit_label (label);
15518   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15519   ix86_emit_fp_unordered_jump (label);
15520   LABEL_NUSES (label) = 1;
15521
15522   emit_move_insn (operands[0], op1);
15523   DONE;
15524 })
15525
15526 (define_expand "remainder<mode>3"
15527   [(use (match_operand:MODEF 0 "register_operand" ""))
15528    (use (match_operand:MODEF 1 "general_operand" ""))
15529    (use (match_operand:MODEF 2 "general_operand" ""))]
15530   "TARGET_USE_FANCY_MATH_387"
15531 {
15532   rtx label = gen_label_rtx ();
15533
15534   rtx op1 = gen_reg_rtx (XFmode);
15535   rtx op2 = gen_reg_rtx (XFmode);
15536
15537   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15538   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15539
15540   emit_label (label);
15541
15542   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15543   ix86_emit_fp_unordered_jump (label);
15544   LABEL_NUSES (label) = 1;
15545
15546   /* Truncate the result properly for strict SSE math.  */
15547   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15548       && !TARGET_MIX_SSE_I387)
15549     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15550   else
15551     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15552
15553   DONE;
15554 })
15555
15556 (define_insn "*sinxf2_i387"
15557   [(set (match_operand:XF 0 "register_operand" "=f")
15558         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15559   "TARGET_USE_FANCY_MATH_387
15560    && flag_unsafe_math_optimizations"
15561   "fsin"
15562   [(set_attr "type" "fpspc")
15563    (set_attr "mode" "XF")])
15564
15565 (define_insn "*sin_extend<mode>xf2_i387"
15566   [(set (match_operand:XF 0 "register_operand" "=f")
15567         (unspec:XF [(float_extend:XF
15568                       (match_operand:MODEF 1 "register_operand" "0"))]
15569                    UNSPEC_SIN))]
15570   "TARGET_USE_FANCY_MATH_387
15571    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15572        || TARGET_MIX_SSE_I387)
15573    && flag_unsafe_math_optimizations"
15574   "fsin"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")])
15577
15578 (define_insn "*cosxf2_i387"
15579   [(set (match_operand:XF 0 "register_operand" "=f")
15580         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15581   "TARGET_USE_FANCY_MATH_387
15582    && flag_unsafe_math_optimizations"
15583   "fcos"
15584   [(set_attr "type" "fpspc")
15585    (set_attr "mode" "XF")])
15586
15587 (define_insn "*cos_extend<mode>xf2_i387"
15588   [(set (match_operand:XF 0 "register_operand" "=f")
15589         (unspec:XF [(float_extend:XF
15590                       (match_operand:MODEF 1 "register_operand" "0"))]
15591                    UNSPEC_COS))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15594        || TARGET_MIX_SSE_I387)
15595    && flag_unsafe_math_optimizations"
15596   "fcos"
15597   [(set_attr "type" "fpspc")
15598    (set_attr "mode" "XF")])
15599
15600 ;; When sincos pattern is defined, sin and cos builtin functions will be
15601 ;; expanded to sincos pattern with one of its outputs left unused.
15602 ;; CSE pass will figure out if two sincos patterns can be combined,
15603 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15604 ;; depending on the unused output.
15605
15606 (define_insn "sincosxf3"
15607   [(set (match_operand:XF 0 "register_operand" "=f")
15608         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15609                    UNSPEC_SINCOS_COS))
15610    (set (match_operand:XF 1 "register_operand" "=u")
15611         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && flag_unsafe_math_optimizations"
15614   "fsincos"
15615   [(set_attr "type" "fpspc")
15616    (set_attr "mode" "XF")])
15617
15618 (define_split
15619   [(set (match_operand:XF 0 "register_operand" "")
15620         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15621                    UNSPEC_SINCOS_COS))
15622    (set (match_operand:XF 1 "register_operand" "")
15623         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15624   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15625    && !(reload_completed || reload_in_progress)"
15626   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15627   "")
15628
15629 (define_split
15630   [(set (match_operand:XF 0 "register_operand" "")
15631         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15632                    UNSPEC_SINCOS_COS))
15633    (set (match_operand:XF 1 "register_operand" "")
15634         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15635   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15636    && !(reload_completed || reload_in_progress)"
15637   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15638   "")
15639
15640 (define_insn "sincos_extend<mode>xf3_i387"
15641   [(set (match_operand:XF 0 "register_operand" "=f")
15642         (unspec:XF [(float_extend:XF
15643                       (match_operand:MODEF 2 "register_operand" "0"))]
15644                    UNSPEC_SINCOS_COS))
15645    (set (match_operand:XF 1 "register_operand" "=u")
15646         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15647   "TARGET_USE_FANCY_MATH_387
15648    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15649        || TARGET_MIX_SSE_I387)
15650    && flag_unsafe_math_optimizations"
15651   "fsincos"
15652   [(set_attr "type" "fpspc")
15653    (set_attr "mode" "XF")])
15654
15655 (define_split
15656   [(set (match_operand:XF 0 "register_operand" "")
15657         (unspec:XF [(float_extend:XF
15658                       (match_operand:MODEF 2 "register_operand" ""))]
15659                    UNSPEC_SINCOS_COS))
15660    (set (match_operand:XF 1 "register_operand" "")
15661         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15662   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15663    && !(reload_completed || reload_in_progress)"
15664   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15665   "")
15666
15667 (define_split
15668   [(set (match_operand:XF 0 "register_operand" "")
15669         (unspec:XF [(float_extend:XF
15670                       (match_operand:MODEF 2 "register_operand" ""))]
15671                    UNSPEC_SINCOS_COS))
15672    (set (match_operand:XF 1 "register_operand" "")
15673         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15674   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15675    && !(reload_completed || reload_in_progress)"
15676   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15677   "")
15678
15679 (define_expand "sincos<mode>3"
15680   [(use (match_operand:MODEF 0 "register_operand" ""))
15681    (use (match_operand:MODEF 1 "register_operand" ""))
15682    (use (match_operand:MODEF 2 "register_operand" ""))]
15683   "TARGET_USE_FANCY_MATH_387
15684    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15685        || TARGET_MIX_SSE_I387)
15686    && flag_unsafe_math_optimizations"
15687 {
15688   rtx op0 = gen_reg_rtx (XFmode);
15689   rtx op1 = gen_reg_rtx (XFmode);
15690
15691   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15692   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15693   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15694   DONE;
15695 })
15696
15697 (define_insn "fptanxf4_i387"
15698   [(set (match_operand:XF 0 "register_operand" "=f")
15699         (match_operand:XF 3 "const_double_operand" "F"))
15700    (set (match_operand:XF 1 "register_operand" "=u")
15701         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15702                    UNSPEC_TAN))]
15703   "TARGET_USE_FANCY_MATH_387
15704    && flag_unsafe_math_optimizations
15705    && standard_80387_constant_p (operands[3]) == 2"
15706   "fptan"
15707   [(set_attr "type" "fpspc")
15708    (set_attr "mode" "XF")])
15709
15710 (define_insn "fptan_extend<mode>xf4_i387"
15711   [(set (match_operand:MODEF 0 "register_operand" "=f")
15712         (match_operand:MODEF 3 "const_double_operand" "F"))
15713    (set (match_operand:XF 1 "register_operand" "=u")
15714         (unspec:XF [(float_extend:XF
15715                       (match_operand:MODEF 2 "register_operand" "0"))]
15716                    UNSPEC_TAN))]
15717   "TARGET_USE_FANCY_MATH_387
15718    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15719        || TARGET_MIX_SSE_I387)
15720    && flag_unsafe_math_optimizations
15721    && standard_80387_constant_p (operands[3]) == 2"
15722   "fptan"
15723   [(set_attr "type" "fpspc")
15724    (set_attr "mode" "XF")])
15725
15726 (define_expand "tanxf2"
15727   [(use (match_operand:XF 0 "register_operand" ""))
15728    (use (match_operand:XF 1 "register_operand" ""))]
15729   "TARGET_USE_FANCY_MATH_387
15730    && flag_unsafe_math_optimizations"
15731 {
15732   rtx one = gen_reg_rtx (XFmode);
15733   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15734
15735   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15736   DONE;
15737 })
15738
15739 (define_expand "tan<mode>2"
15740   [(use (match_operand:MODEF 0 "register_operand" ""))
15741    (use (match_operand:MODEF 1 "register_operand" ""))]
15742   "TARGET_USE_FANCY_MATH_387
15743    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744        || TARGET_MIX_SSE_I387)
15745    && flag_unsafe_math_optimizations"
15746 {
15747   rtx op0 = gen_reg_rtx (XFmode);
15748
15749   rtx one = gen_reg_rtx (<MODE>mode);
15750   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15751
15752   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15753                                              operands[1], op2));
15754   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15755   DONE;
15756 })
15757
15758 (define_insn "*fpatanxf3_i387"
15759   [(set (match_operand:XF 0 "register_operand" "=f")
15760         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15761                     (match_operand:XF 2 "register_operand" "u")]
15762                    UNSPEC_FPATAN))
15763    (clobber (match_scratch:XF 3 "=2"))]
15764   "TARGET_USE_FANCY_MATH_387
15765    && flag_unsafe_math_optimizations"
15766   "fpatan"
15767   [(set_attr "type" "fpspc")
15768    (set_attr "mode" "XF")])
15769
15770 (define_insn "fpatan_extend<mode>xf3_i387"
15771   [(set (match_operand:XF 0 "register_operand" "=f")
15772         (unspec:XF [(float_extend:XF
15773                       (match_operand:MODEF 1 "register_operand" "0"))
15774                     (float_extend:XF
15775                       (match_operand:MODEF 2 "register_operand" "u"))]
15776                    UNSPEC_FPATAN))
15777    (clobber (match_scratch:XF 3 "=2"))]
15778   "TARGET_USE_FANCY_MATH_387
15779    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15780        || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations"
15782   "fpatan"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "XF")])
15785
15786 (define_expand "atan2xf3"
15787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15788                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15789                                (match_operand:XF 1 "register_operand" "")]
15790                               UNSPEC_FPATAN))
15791               (clobber (match_scratch:XF 3 ""))])]
15792   "TARGET_USE_FANCY_MATH_387
15793    && flag_unsafe_math_optimizations"
15794   "")
15795
15796 (define_expand "atan2<mode>3"
15797   [(use (match_operand:MODEF 0 "register_operand" ""))
15798    (use (match_operand:MODEF 1 "register_operand" ""))
15799    (use (match_operand:MODEF 2 "register_operand" ""))]
15800   "TARGET_USE_FANCY_MATH_387
15801    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15802        || TARGET_MIX_SSE_I387)
15803    && flag_unsafe_math_optimizations"
15804 {
15805   rtx op0 = gen_reg_rtx (XFmode);
15806
15807   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15808   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15809   DONE;
15810 })
15811
15812 (define_expand "atanxf2"
15813   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15814                    (unspec:XF [(match_dup 2)
15815                                (match_operand:XF 1 "register_operand" "")]
15816                               UNSPEC_FPATAN))
15817               (clobber (match_scratch:XF 3 ""))])]
15818   "TARGET_USE_FANCY_MATH_387
15819    && flag_unsafe_math_optimizations"
15820 {
15821   operands[2] = gen_reg_rtx (XFmode);
15822   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15823 })
15824
15825 (define_expand "atan<mode>2"
15826   [(use (match_operand:MODEF 0 "register_operand" ""))
15827    (use (match_operand:MODEF 1 "register_operand" ""))]
15828   "TARGET_USE_FANCY_MATH_387
15829    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15830        || TARGET_MIX_SSE_I387)
15831    && flag_unsafe_math_optimizations"
15832 {
15833   rtx op0 = gen_reg_rtx (XFmode);
15834
15835   rtx op2 = gen_reg_rtx (<MODE>mode);
15836   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15837
15838   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15839   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15840   DONE;
15841 })
15842
15843 (define_expand "asinxf2"
15844   [(set (match_dup 2)
15845         (mult:XF (match_operand:XF 1 "register_operand" "")
15846                  (match_dup 1)))
15847    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15848    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15849    (parallel [(set (match_operand:XF 0 "register_operand" "")
15850                    (unspec:XF [(match_dup 5) (match_dup 1)]
15851                               UNSPEC_FPATAN))
15852               (clobber (match_scratch:XF 6 ""))])]
15853   "TARGET_USE_FANCY_MATH_387
15854    && flag_unsafe_math_optimizations"
15855 {
15856   int i;
15857
15858   if (optimize_insn_for_size_p ())
15859     FAIL;
15860
15861   for (i = 2; i < 6; i++)
15862     operands[i] = gen_reg_rtx (XFmode);
15863
15864   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15865 })
15866
15867 (define_expand "asin<mode>2"
15868   [(use (match_operand:MODEF 0 "register_operand" ""))
15869    (use (match_operand:MODEF 1 "general_operand" ""))]
15870  "TARGET_USE_FANCY_MATH_387
15871    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15872        || TARGET_MIX_SSE_I387)
15873    && flag_unsafe_math_optimizations"
15874 {
15875   rtx op0 = gen_reg_rtx (XFmode);
15876   rtx op1 = gen_reg_rtx (XFmode);
15877
15878   if (optimize_insn_for_size_p ())
15879     FAIL;
15880
15881   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15882   emit_insn (gen_asinxf2 (op0, op1));
15883   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15884   DONE;
15885 })
15886
15887 (define_expand "acosxf2"
15888   [(set (match_dup 2)
15889         (mult:XF (match_operand:XF 1 "register_operand" "")
15890                  (match_dup 1)))
15891    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15892    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15893    (parallel [(set (match_operand:XF 0 "register_operand" "")
15894                    (unspec:XF [(match_dup 1) (match_dup 5)]
15895                               UNSPEC_FPATAN))
15896               (clobber (match_scratch:XF 6 ""))])]
15897   "TARGET_USE_FANCY_MATH_387
15898    && flag_unsafe_math_optimizations"
15899 {
15900   int i;
15901
15902   if (optimize_insn_for_size_p ())
15903     FAIL;
15904
15905   for (i = 2; i < 6; i++)
15906     operands[i] = gen_reg_rtx (XFmode);
15907
15908   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15909 })
15910
15911 (define_expand "acos<mode>2"
15912   [(use (match_operand:MODEF 0 "register_operand" ""))
15913    (use (match_operand:MODEF 1 "general_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 = gen_reg_rtx (XFmode);
15920   rtx op1 = gen_reg_rtx (XFmode);
15921
15922   if (optimize_insn_for_size_p ())
15923     FAIL;
15924
15925   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15926   emit_insn (gen_acosxf2 (op0, op1));
15927   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15928   DONE;
15929 })
15930
15931 (define_insn "fyl2xxf3_i387"
15932   [(set (match_operand:XF 0 "register_operand" "=f")
15933         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15934                     (match_operand:XF 2 "register_operand" "u")]
15935                    UNSPEC_FYL2X))
15936    (clobber (match_scratch:XF 3 "=2"))]
15937   "TARGET_USE_FANCY_MATH_387
15938    && flag_unsafe_math_optimizations"
15939   "fyl2x"
15940   [(set_attr "type" "fpspc")
15941    (set_attr "mode" "XF")])
15942
15943 (define_insn "fyl2x_extend<mode>xf3_i387"
15944   [(set (match_operand:XF 0 "register_operand" "=f")
15945         (unspec:XF [(float_extend:XF
15946                       (match_operand:MODEF 1 "register_operand" "0"))
15947                     (match_operand:XF 2 "register_operand" "u")]
15948                    UNSPEC_FYL2X))
15949    (clobber (match_scratch:XF 3 "=2"))]
15950   "TARGET_USE_FANCY_MATH_387
15951    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15952        || TARGET_MIX_SSE_I387)
15953    && flag_unsafe_math_optimizations"
15954   "fyl2x"
15955   [(set_attr "type" "fpspc")
15956    (set_attr "mode" "XF")])
15957
15958 (define_expand "logxf2"
15959   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15960                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15961                                (match_dup 2)] UNSPEC_FYL2X))
15962               (clobber (match_scratch:XF 3 ""))])]
15963   "TARGET_USE_FANCY_MATH_387
15964    && flag_unsafe_math_optimizations"
15965 {
15966   operands[2] = gen_reg_rtx (XFmode);
15967   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15968 })
15969
15970 (define_expand "log<mode>2"
15971   [(use (match_operand:MODEF 0 "register_operand" ""))
15972    (use (match_operand:MODEF 1 "register_operand" ""))]
15973   "TARGET_USE_FANCY_MATH_387
15974    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15975        || TARGET_MIX_SSE_I387)
15976    && flag_unsafe_math_optimizations"
15977 {
15978   rtx op0 = gen_reg_rtx (XFmode);
15979
15980   rtx op2 = gen_reg_rtx (XFmode);
15981   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15982
15983   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15984   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15985   DONE;
15986 })
15987
15988 (define_expand "log10xf2"
15989   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15990                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15991                                (match_dup 2)] UNSPEC_FYL2X))
15992               (clobber (match_scratch:XF 3 ""))])]
15993   "TARGET_USE_FANCY_MATH_387
15994    && flag_unsafe_math_optimizations"
15995 {
15996   operands[2] = gen_reg_rtx (XFmode);
15997   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15998 })
15999
16000 (define_expand "log10<mode>2"
16001   [(use (match_operand:MODEF 0 "register_operand" ""))
16002    (use (match_operand:MODEF 1 "register_operand" ""))]
16003   "TARGET_USE_FANCY_MATH_387
16004    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16005        || TARGET_MIX_SSE_I387)
16006    && flag_unsafe_math_optimizations"
16007 {
16008   rtx op0 = gen_reg_rtx (XFmode);
16009
16010   rtx op2 = gen_reg_rtx (XFmode);
16011   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16012
16013   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16014   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16015   DONE;
16016 })
16017
16018 (define_expand "log2xf2"
16019   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16020                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16021                                (match_dup 2)] UNSPEC_FYL2X))
16022               (clobber (match_scratch:XF 3 ""))])]
16023   "TARGET_USE_FANCY_MATH_387
16024    && flag_unsafe_math_optimizations"
16025 {
16026   operands[2] = gen_reg_rtx (XFmode);
16027   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16028 })
16029
16030 (define_expand "log2<mode>2"
16031   [(use (match_operand:MODEF 0 "register_operand" ""))
16032    (use (match_operand:MODEF 1 "register_operand" ""))]
16033   "TARGET_USE_FANCY_MATH_387
16034    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16035        || TARGET_MIX_SSE_I387)
16036    && flag_unsafe_math_optimizations"
16037 {
16038   rtx op0 = gen_reg_rtx (XFmode);
16039
16040   rtx op2 = gen_reg_rtx (XFmode);
16041   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16042
16043   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16044   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16045   DONE;
16046 })
16047
16048 (define_insn "fyl2xp1xf3_i387"
16049   [(set (match_operand:XF 0 "register_operand" "=f")
16050         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16051                     (match_operand:XF 2 "register_operand" "u")]
16052                    UNSPEC_FYL2XP1))
16053    (clobber (match_scratch:XF 3 "=2"))]
16054   "TARGET_USE_FANCY_MATH_387
16055    && flag_unsafe_math_optimizations"
16056   "fyl2xp1"
16057   [(set_attr "type" "fpspc")
16058    (set_attr "mode" "XF")])
16059
16060 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16061   [(set (match_operand:XF 0 "register_operand" "=f")
16062         (unspec:XF [(float_extend:XF
16063                       (match_operand:MODEF 1 "register_operand" "0"))
16064                     (match_operand:XF 2 "register_operand" "u")]
16065                    UNSPEC_FYL2XP1))
16066    (clobber (match_scratch:XF 3 "=2"))]
16067   "TARGET_USE_FANCY_MATH_387
16068    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16069        || TARGET_MIX_SSE_I387)
16070    && flag_unsafe_math_optimizations"
16071   "fyl2xp1"
16072   [(set_attr "type" "fpspc")
16073    (set_attr "mode" "XF")])
16074
16075 (define_expand "log1pxf2"
16076   [(use (match_operand:XF 0 "register_operand" ""))
16077    (use (match_operand:XF 1 "register_operand" ""))]
16078   "TARGET_USE_FANCY_MATH_387
16079    && flag_unsafe_math_optimizations"
16080 {
16081   if (optimize_insn_for_size_p ())
16082     FAIL;
16083
16084   ix86_emit_i387_log1p (operands[0], operands[1]);
16085   DONE;
16086 })
16087
16088 (define_expand "log1p<mode>2"
16089   [(use (match_operand:MODEF 0 "register_operand" ""))
16090    (use (match_operand:MODEF 1 "register_operand" ""))]
16091   "TARGET_USE_FANCY_MATH_387
16092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16093        || TARGET_MIX_SSE_I387)
16094    && flag_unsafe_math_optimizations"
16095 {
16096   rtx op0;
16097
16098   if (optimize_insn_for_size_p ())
16099     FAIL;
16100
16101   op0 = gen_reg_rtx (XFmode);
16102
16103   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16104
16105   ix86_emit_i387_log1p (op0, operands[1]);
16106   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16107   DONE;
16108 })
16109
16110 (define_insn "fxtractxf3_i387"
16111   [(set (match_operand:XF 0 "register_operand" "=f")
16112         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16113                    UNSPEC_XTRACT_FRACT))
16114    (set (match_operand:XF 1 "register_operand" "=u")
16115         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16116   "TARGET_USE_FANCY_MATH_387
16117    && flag_unsafe_math_optimizations"
16118   "fxtract"
16119   [(set_attr "type" "fpspc")
16120    (set_attr "mode" "XF")])
16121
16122 (define_insn "fxtract_extend<mode>xf3_i387"
16123   [(set (match_operand:XF 0 "register_operand" "=f")
16124         (unspec:XF [(float_extend:XF
16125                       (match_operand:MODEF 2 "register_operand" "0"))]
16126                    UNSPEC_XTRACT_FRACT))
16127    (set (match_operand:XF 1 "register_operand" "=u")
16128         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16129   "TARGET_USE_FANCY_MATH_387
16130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16131        || TARGET_MIX_SSE_I387)
16132    && flag_unsafe_math_optimizations"
16133   "fxtract"
16134   [(set_attr "type" "fpspc")
16135    (set_attr "mode" "XF")])
16136
16137 (define_expand "logbxf2"
16138   [(parallel [(set (match_dup 2)
16139                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16140                               UNSPEC_XTRACT_FRACT))
16141               (set (match_operand:XF 0 "register_operand" "")
16142                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16143   "TARGET_USE_FANCY_MATH_387
16144    && flag_unsafe_math_optimizations"
16145 {
16146   operands[2] = gen_reg_rtx (XFmode);
16147 })
16148
16149 (define_expand "logb<mode>2"
16150   [(use (match_operand:MODEF 0 "register_operand" ""))
16151    (use (match_operand:MODEF 1 "register_operand" ""))]
16152   "TARGET_USE_FANCY_MATH_387
16153    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16154        || TARGET_MIX_SSE_I387)
16155    && flag_unsafe_math_optimizations"
16156 {
16157   rtx op0 = gen_reg_rtx (XFmode);
16158   rtx op1 = gen_reg_rtx (XFmode);
16159
16160   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16162   DONE;
16163 })
16164
16165 (define_expand "ilogbxf2"
16166   [(use (match_operand:SI 0 "register_operand" ""))
16167    (use (match_operand:XF 1 "register_operand" ""))]
16168   "TARGET_USE_FANCY_MATH_387
16169    && flag_unsafe_math_optimizations"
16170 {
16171   rtx op0, op1;
16172
16173   if (optimize_insn_for_size_p ())
16174     FAIL;
16175
16176   op0 = gen_reg_rtx (XFmode);
16177   op1 = gen_reg_rtx (XFmode);
16178
16179   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16180   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16181   DONE;
16182 })
16183
16184 (define_expand "ilogb<mode>2"
16185   [(use (match_operand:SI 0 "register_operand" ""))
16186    (use (match_operand:MODEF 1 "register_operand" ""))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16189        || TARGET_MIX_SSE_I387)
16190    && flag_unsafe_math_optimizations"
16191 {
16192   rtx op0, op1;
16193
16194   if (optimize_insn_for_size_p ())
16195     FAIL;
16196
16197   op0 = gen_reg_rtx (XFmode);
16198   op1 = gen_reg_rtx (XFmode);
16199
16200   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16201   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16202   DONE;
16203 })
16204
16205 (define_insn "*f2xm1xf2_i387"
16206   [(set (match_operand:XF 0 "register_operand" "=f")
16207         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16208                    UNSPEC_F2XM1))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && flag_unsafe_math_optimizations"
16211   "f2xm1"
16212   [(set_attr "type" "fpspc")
16213    (set_attr "mode" "XF")])
16214
16215 (define_insn "*fscalexf4_i387"
16216   [(set (match_operand:XF 0 "register_operand" "=f")
16217         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16218                     (match_operand:XF 3 "register_operand" "1")]
16219                    UNSPEC_FSCALE_FRACT))
16220    (set (match_operand:XF 1 "register_operand" "=u")
16221         (unspec:XF [(match_dup 2) (match_dup 3)]
16222                    UNSPEC_FSCALE_EXP))]
16223   "TARGET_USE_FANCY_MATH_387
16224    && flag_unsafe_math_optimizations"
16225   "fscale"
16226   [(set_attr "type" "fpspc")
16227    (set_attr "mode" "XF")])
16228
16229 (define_expand "expNcorexf3"
16230   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16231                                (match_operand:XF 2 "register_operand" "")))
16232    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16233    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16234    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16235    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16236    (parallel [(set (match_operand:XF 0 "register_operand" "")
16237                    (unspec:XF [(match_dup 8) (match_dup 4)]
16238                               UNSPEC_FSCALE_FRACT))
16239               (set (match_dup 9)
16240                    (unspec:XF [(match_dup 8) (match_dup 4)]
16241                               UNSPEC_FSCALE_EXP))])]
16242   "TARGET_USE_FANCY_MATH_387
16243    && flag_unsafe_math_optimizations"
16244 {
16245   int i;
16246
16247   if (optimize_insn_for_size_p ())
16248     FAIL;
16249
16250   for (i = 3; i < 10; i++)
16251     operands[i] = gen_reg_rtx (XFmode);
16252
16253   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16254 })
16255
16256 (define_expand "expxf2"
16257   [(use (match_operand:XF 0 "register_operand" ""))
16258    (use (match_operand:XF 1 "register_operand" ""))]
16259   "TARGET_USE_FANCY_MATH_387
16260    && flag_unsafe_math_optimizations"
16261 {
16262   rtx op2;
16263
16264   if (optimize_insn_for_size_p ())
16265     FAIL;
16266
16267   op2 = gen_reg_rtx (XFmode);
16268   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16269
16270   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16271   DONE;
16272 })
16273
16274 (define_expand "exp<mode>2"
16275   [(use (match_operand:MODEF 0 "register_operand" ""))
16276    (use (match_operand:MODEF 1 "general_operand" ""))]
16277  "TARGET_USE_FANCY_MATH_387
16278    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16279        || TARGET_MIX_SSE_I387)
16280    && flag_unsafe_math_optimizations"
16281 {
16282   rtx op0, op1;
16283
16284   if (optimize_insn_for_size_p ())
16285     FAIL;
16286
16287   op0 = gen_reg_rtx (XFmode);
16288   op1 = gen_reg_rtx (XFmode);
16289
16290   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16291   emit_insn (gen_expxf2 (op0, op1));
16292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16293   DONE;
16294 })
16295
16296 (define_expand "exp10xf2"
16297   [(use (match_operand:XF 0 "register_operand" ""))
16298    (use (match_operand:XF 1 "register_operand" ""))]
16299   "TARGET_USE_FANCY_MATH_387
16300    && flag_unsafe_math_optimizations"
16301 {
16302   rtx op2;
16303
16304   if (optimize_insn_for_size_p ())
16305     FAIL;
16306
16307   op2 = gen_reg_rtx (XFmode);
16308   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16309
16310   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16311   DONE;
16312 })
16313
16314 (define_expand "exp10<mode>2"
16315   [(use (match_operand:MODEF 0 "register_operand" ""))
16316    (use (match_operand:MODEF 1 "general_operand" ""))]
16317  "TARGET_USE_FANCY_MATH_387
16318    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16319        || TARGET_MIX_SSE_I387)
16320    && flag_unsafe_math_optimizations"
16321 {
16322   rtx op0, op1;
16323
16324   if (optimize_insn_for_size_p ())
16325     FAIL;
16326
16327   op0 = gen_reg_rtx (XFmode);
16328   op1 = gen_reg_rtx (XFmode);
16329
16330   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16331   emit_insn (gen_exp10xf2 (op0, op1));
16332   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16333   DONE;
16334 })
16335
16336 (define_expand "exp2xf2"
16337   [(use (match_operand:XF 0 "register_operand" ""))
16338    (use (match_operand:XF 1 "register_operand" ""))]
16339   "TARGET_USE_FANCY_MATH_387
16340    && flag_unsafe_math_optimizations"
16341 {
16342   rtx op2;
16343
16344   if (optimize_insn_for_size_p ())
16345     FAIL;
16346
16347   op2 = gen_reg_rtx (XFmode);
16348   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16349
16350   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16351   DONE;
16352 })
16353
16354 (define_expand "exp2<mode>2"
16355   [(use (match_operand:MODEF 0 "register_operand" ""))
16356    (use (match_operand:MODEF 1 "general_operand" ""))]
16357  "TARGET_USE_FANCY_MATH_387
16358    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16359        || TARGET_MIX_SSE_I387)
16360    && flag_unsafe_math_optimizations"
16361 {
16362   rtx op0, op1;
16363
16364   if (optimize_insn_for_size_p ())
16365     FAIL;
16366
16367   op0 = gen_reg_rtx (XFmode);
16368   op1 = gen_reg_rtx (XFmode);
16369
16370   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16371   emit_insn (gen_exp2xf2 (op0, op1));
16372   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16373   DONE;
16374 })
16375
16376 (define_expand "expm1xf2"
16377   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16378                                (match_dup 2)))
16379    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16380    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16381    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16382    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16383    (parallel [(set (match_dup 7)
16384                    (unspec:XF [(match_dup 6) (match_dup 4)]
16385                               UNSPEC_FSCALE_FRACT))
16386               (set (match_dup 8)
16387                    (unspec:XF [(match_dup 6) (match_dup 4)]
16388                               UNSPEC_FSCALE_EXP))])
16389    (parallel [(set (match_dup 10)
16390                    (unspec:XF [(match_dup 9) (match_dup 8)]
16391                               UNSPEC_FSCALE_FRACT))
16392               (set (match_dup 11)
16393                    (unspec:XF [(match_dup 9) (match_dup 8)]
16394                               UNSPEC_FSCALE_EXP))])
16395    (set (match_dup 12) (minus:XF (match_dup 10)
16396                                  (float_extend:XF (match_dup 13))))
16397    (set (match_operand:XF 0 "register_operand" "")
16398         (plus:XF (match_dup 12) (match_dup 7)))]
16399   "TARGET_USE_FANCY_MATH_387
16400    && flag_unsafe_math_optimizations"
16401 {
16402   int i;
16403
16404   if (optimize_insn_for_size_p ())
16405     FAIL;
16406
16407   for (i = 2; i < 13; i++)
16408     operands[i] = gen_reg_rtx (XFmode);
16409
16410   operands[13]
16411     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16412
16413   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16414 })
16415
16416 (define_expand "expm1<mode>2"
16417   [(use (match_operand:MODEF 0 "register_operand" ""))
16418    (use (match_operand:MODEF 1 "general_operand" ""))]
16419  "TARGET_USE_FANCY_MATH_387
16420    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16421        || TARGET_MIX_SSE_I387)
16422    && flag_unsafe_math_optimizations"
16423 {
16424   rtx op0, op1;
16425
16426   if (optimize_insn_for_size_p ())
16427     FAIL;
16428
16429   op0 = gen_reg_rtx (XFmode);
16430   op1 = gen_reg_rtx (XFmode);
16431
16432   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16433   emit_insn (gen_expm1xf2 (op0, op1));
16434   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16435   DONE;
16436 })
16437
16438 (define_expand "ldexpxf3"
16439   [(set (match_dup 3)
16440         (float:XF (match_operand:SI 2 "register_operand" "")))
16441    (parallel [(set (match_operand:XF 0 " register_operand" "")
16442                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16443                                (match_dup 3)]
16444                               UNSPEC_FSCALE_FRACT))
16445               (set (match_dup 4)
16446                    (unspec:XF [(match_dup 1) (match_dup 3)]
16447                               UNSPEC_FSCALE_EXP))])]
16448   "TARGET_USE_FANCY_MATH_387
16449    && flag_unsafe_math_optimizations"
16450 {
16451   if (optimize_insn_for_size_p ())
16452     FAIL;
16453
16454   operands[3] = gen_reg_rtx (XFmode);
16455   operands[4] = gen_reg_rtx (XFmode);
16456 })
16457
16458 (define_expand "ldexp<mode>3"
16459   [(use (match_operand:MODEF 0 "register_operand" ""))
16460    (use (match_operand:MODEF 1 "general_operand" ""))
16461    (use (match_operand:SI 2 "register_operand" ""))]
16462  "TARGET_USE_FANCY_MATH_387
16463    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16464        || TARGET_MIX_SSE_I387)
16465    && flag_unsafe_math_optimizations"
16466 {
16467   rtx op0, op1;
16468
16469   if (optimize_insn_for_size_p ())
16470     FAIL;
16471
16472   op0 = gen_reg_rtx (XFmode);
16473   op1 = gen_reg_rtx (XFmode);
16474
16475   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16476   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16477   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16478   DONE;
16479 })
16480
16481 (define_expand "scalbxf3"
16482   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16483                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16484                                (match_operand:XF 2 "register_operand" "")]
16485                               UNSPEC_FSCALE_FRACT))
16486               (set (match_dup 3)
16487                    (unspec:XF [(match_dup 1) (match_dup 2)]
16488                               UNSPEC_FSCALE_EXP))])]
16489   "TARGET_USE_FANCY_MATH_387
16490    && flag_unsafe_math_optimizations"
16491 {
16492   if (optimize_insn_for_size_p ())
16493     FAIL;
16494
16495   operands[3] = gen_reg_rtx (XFmode);
16496 })
16497
16498 (define_expand "scalb<mode>3"
16499   [(use (match_operand:MODEF 0 "register_operand" ""))
16500    (use (match_operand:MODEF 1 "general_operand" ""))
16501    (use (match_operand:MODEF 2 "general_operand" ""))]
16502  "TARGET_USE_FANCY_MATH_387
16503    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16504        || TARGET_MIX_SSE_I387)
16505    && flag_unsafe_math_optimizations"
16506 {
16507   rtx op0, op1, op2;
16508
16509   if (optimize_insn_for_size_p ())
16510     FAIL;
16511
16512   op0 = gen_reg_rtx (XFmode);
16513   op1 = gen_reg_rtx (XFmode);
16514   op2 = gen_reg_rtx (XFmode);
16515
16516   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16517   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16518   emit_insn (gen_scalbxf3 (op0, op1, op2));
16519   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16520   DONE;
16521 })
16522
16523 (define_expand "significandxf2"
16524   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16525                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16526                               UNSPEC_XTRACT_FRACT))
16527               (set (match_dup 2)
16528                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16529   "TARGET_USE_FANCY_MATH_387
16530    && flag_unsafe_math_optimizations"
16531 {
16532   operands[2] = gen_reg_rtx (XFmode);
16533 })
16534
16535 (define_expand "significand<mode>2"
16536   [(use (match_operand:MODEF 0 "register_operand" ""))
16537    (use (match_operand:MODEF 1 "register_operand" ""))]
16538   "TARGET_USE_FANCY_MATH_387
16539    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16540        || TARGET_MIX_SSE_I387)
16541    && flag_unsafe_math_optimizations"
16542 {
16543   rtx op0 = gen_reg_rtx (XFmode);
16544   rtx op1 = gen_reg_rtx (XFmode);
16545
16546   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16547   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16548   DONE;
16549 })
16550 \f
16551
16552 (define_insn "sse4_1_round<mode>2"
16553   [(set (match_operand:MODEF 0 "register_operand" "=x")
16554         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16555                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
16556                       UNSPEC_ROUND))]
16557   "TARGET_ROUND"
16558   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16559   [(set_attr "type" "ssecvt")
16560    (set_attr "prefix_extra" "1")
16561    (set_attr "prefix" "maybe_vex")
16562    (set_attr "mode" "<MODE>")])
16563
16564 (define_insn "rintxf2"
16565   [(set (match_operand:XF 0 "register_operand" "=f")
16566         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16567                    UNSPEC_FRNDINT))]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570   "frndint"
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "XF")])
16573
16574 (define_expand "rint<mode>2"
16575   [(use (match_operand:MODEF 0 "register_operand" ""))
16576    (use (match_operand:MODEF 1 "register_operand" ""))]
16577   "(TARGET_USE_FANCY_MATH_387
16578     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16579         || TARGET_MIX_SSE_I387)
16580     && flag_unsafe_math_optimizations)
16581    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16582        && !flag_trapping_math)"
16583 {
16584   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16585       && !flag_trapping_math)
16586     {
16587       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16588         FAIL;
16589       if (TARGET_ROUND)
16590         emit_insn (gen_sse4_1_round<mode>2
16591                    (operands[0], operands[1], GEN_INT (0x04)));
16592       else
16593         ix86_expand_rint (operand0, operand1);
16594     }
16595   else
16596     {
16597       rtx op0 = gen_reg_rtx (XFmode);
16598       rtx op1 = gen_reg_rtx (XFmode);
16599
16600       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16601       emit_insn (gen_rintxf2 (op0, op1));
16602
16603       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16604     }
16605   DONE;
16606 })
16607
16608 (define_expand "round<mode>2"
16609   [(match_operand:MODEF 0 "register_operand" "")
16610    (match_operand:MODEF 1 "nonimmediate_operand" "")]
16611   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16612    && !flag_trapping_math && !flag_rounding_math"
16613 {
16614   if (optimize_insn_for_size_p ())
16615     FAIL;
16616   if (TARGET_64BIT || (<MODE>mode != DFmode))
16617     ix86_expand_round (operand0, operand1);
16618   else
16619     ix86_expand_rounddf_32 (operand0, operand1);
16620   DONE;
16621 })
16622
16623 (define_insn_and_split "*fistdi2_1"
16624   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16625         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16626                    UNSPEC_FIST))]
16627   "TARGET_USE_FANCY_MATH_387
16628    && can_create_pseudo_p ()"
16629   "#"
16630   "&& 1"
16631   [(const_int 0)]
16632 {
16633   if (memory_operand (operands[0], VOIDmode))
16634     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16635   else
16636     {
16637       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16638       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16639                                          operands[2]));
16640     }
16641   DONE;
16642 }
16643   [(set_attr "type" "fpspc")
16644    (set_attr "mode" "DI")])
16645
16646 (define_insn "fistdi2"
16647   [(set (match_operand:DI 0 "memory_operand" "=m")
16648         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16649                    UNSPEC_FIST))
16650    (clobber (match_scratch:XF 2 "=&1f"))]
16651   "TARGET_USE_FANCY_MATH_387"
16652   "* return output_fix_trunc (insn, operands, 0);"
16653   [(set_attr "type" "fpspc")
16654    (set_attr "mode" "DI")])
16655
16656 (define_insn "fistdi2_with_temp"
16657   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16658         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16659                    UNSPEC_FIST))
16660    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16661    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16662   "TARGET_USE_FANCY_MATH_387"
16663   "#"
16664   [(set_attr "type" "fpspc")
16665    (set_attr "mode" "DI")])
16666
16667 (define_split
16668   [(set (match_operand:DI 0 "register_operand" "")
16669         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16670                    UNSPEC_FIST))
16671    (clobber (match_operand:DI 2 "memory_operand" ""))
16672    (clobber (match_scratch 3 ""))]
16673   "reload_completed"
16674   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16675               (clobber (match_dup 3))])
16676    (set (match_dup 0) (match_dup 2))]
16677   "")
16678
16679 (define_split
16680   [(set (match_operand:DI 0 "memory_operand" "")
16681         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16682                    UNSPEC_FIST))
16683    (clobber (match_operand:DI 2 "memory_operand" ""))
16684    (clobber (match_scratch 3 ""))]
16685   "reload_completed"
16686   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16687               (clobber (match_dup 3))])]
16688   "")
16689
16690 (define_insn_and_split "*fist<mode>2_1"
16691   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16692         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16693                            UNSPEC_FIST))]
16694   "TARGET_USE_FANCY_MATH_387
16695    && can_create_pseudo_p ()"
16696   "#"
16697   "&& 1"
16698   [(const_int 0)]
16699 {
16700   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16701   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16702                                         operands[2]));
16703   DONE;
16704 }
16705   [(set_attr "type" "fpspc")
16706    (set_attr "mode" "<MODE>")])
16707
16708 (define_insn "fist<mode>2"
16709   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16710         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16711                            UNSPEC_FIST))]
16712   "TARGET_USE_FANCY_MATH_387"
16713   "* return output_fix_trunc (insn, operands, 0);"
16714   [(set_attr "type" "fpspc")
16715    (set_attr "mode" "<MODE>")])
16716
16717 (define_insn "fist<mode>2_with_temp"
16718   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16719         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16720                            UNSPEC_FIST))
16721    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16722   "TARGET_USE_FANCY_MATH_387"
16723   "#"
16724   [(set_attr "type" "fpspc")
16725    (set_attr "mode" "<MODE>")])
16726
16727 (define_split
16728   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16729         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16730                            UNSPEC_FIST))
16731    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16732   "reload_completed"
16733   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16734    (set (match_dup 0) (match_dup 2))]
16735   "")
16736
16737 (define_split
16738   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16739         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16740                            UNSPEC_FIST))
16741    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16742   "reload_completed"
16743   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16744   "")
16745
16746 (define_expand "lrintxf<mode>2"
16747   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16748      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16749                       UNSPEC_FIST))]
16750   "TARGET_USE_FANCY_MATH_387"
16751   "")
16752
16753 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16754   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16755      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16756                         UNSPEC_FIX_NOTRUNC))]
16757   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16758    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16759   "")
16760
16761 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16762   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16763    (match_operand:MODEF 1 "register_operand" "")]
16764   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16765    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16766    && !flag_trapping_math && !flag_rounding_math"
16767 {
16768   if (optimize_insn_for_size_p ())
16769     FAIL;
16770   ix86_expand_lround (operand0, operand1);
16771   DONE;
16772 })
16773
16774 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16775 (define_insn_and_split "frndintxf2_floor"
16776   [(set (match_operand:XF 0 "register_operand" "")
16777         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16778          UNSPEC_FRNDINT_FLOOR))
16779    (clobber (reg:CC FLAGS_REG))]
16780   "TARGET_USE_FANCY_MATH_387
16781    && flag_unsafe_math_optimizations
16782    && can_create_pseudo_p ()"
16783   "#"
16784   "&& 1"
16785   [(const_int 0)]
16786 {
16787   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16788
16789   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16790   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16791
16792   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16793                                         operands[2], operands[3]));
16794   DONE;
16795 }
16796   [(set_attr "type" "frndint")
16797    (set_attr "i387_cw" "floor")
16798    (set_attr "mode" "XF")])
16799
16800 (define_insn "frndintxf2_floor_i387"
16801   [(set (match_operand:XF 0 "register_operand" "=f")
16802         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16803          UNSPEC_FRNDINT_FLOOR))
16804    (use (match_operand:HI 2 "memory_operand" "m"))
16805    (use (match_operand:HI 3 "memory_operand" "m"))]
16806   "TARGET_USE_FANCY_MATH_387
16807    && flag_unsafe_math_optimizations"
16808   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16809   [(set_attr "type" "frndint")
16810    (set_attr "i387_cw" "floor")
16811    (set_attr "mode" "XF")])
16812
16813 (define_expand "floorxf2"
16814   [(use (match_operand:XF 0 "register_operand" ""))
16815    (use (match_operand:XF 1 "register_operand" ""))]
16816   "TARGET_USE_FANCY_MATH_387
16817    && flag_unsafe_math_optimizations"
16818 {
16819   if (optimize_insn_for_size_p ())
16820     FAIL;
16821   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16822   DONE;
16823 })
16824
16825 (define_expand "floor<mode>2"
16826   [(use (match_operand:MODEF 0 "register_operand" ""))
16827    (use (match_operand:MODEF 1 "register_operand" ""))]
16828   "(TARGET_USE_FANCY_MATH_387
16829     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16830         || TARGET_MIX_SSE_I387)
16831     && flag_unsafe_math_optimizations)
16832    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16833        && !flag_trapping_math)"
16834 {
16835   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16836       && !flag_trapping_math
16837       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16838     {
16839       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16840         FAIL;
16841       if (TARGET_ROUND)
16842         emit_insn (gen_sse4_1_round<mode>2
16843                    (operands[0], operands[1], GEN_INT (0x01)));
16844       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16845         ix86_expand_floorceil (operand0, operand1, true);
16846       else
16847         ix86_expand_floorceildf_32 (operand0, operand1, true);
16848     }
16849   else
16850     {
16851       rtx op0, op1;
16852
16853       if (optimize_insn_for_size_p ())
16854         FAIL;
16855
16856       op0 = gen_reg_rtx (XFmode);
16857       op1 = gen_reg_rtx (XFmode);
16858       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16859       emit_insn (gen_frndintxf2_floor (op0, op1));
16860
16861       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16862     }
16863   DONE;
16864 })
16865
16866 (define_insn_and_split "*fist<mode>2_floor_1"
16867   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16868         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16869          UNSPEC_FIST_FLOOR))
16870    (clobber (reg:CC FLAGS_REG))]
16871   "TARGET_USE_FANCY_MATH_387
16872    && flag_unsafe_math_optimizations
16873    && can_create_pseudo_p ()"
16874   "#"
16875   "&& 1"
16876   [(const_int 0)]
16877 {
16878   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16879
16880   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16881   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16882   if (memory_operand (operands[0], VOIDmode))
16883     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16884                                       operands[2], operands[3]));
16885   else
16886     {
16887       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16888       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16889                                                   operands[2], operands[3],
16890                                                   operands[4]));
16891     }
16892   DONE;
16893 }
16894   [(set_attr "type" "fistp")
16895    (set_attr "i387_cw" "floor")
16896    (set_attr "mode" "<MODE>")])
16897
16898 (define_insn "fistdi2_floor"
16899   [(set (match_operand:DI 0 "memory_operand" "=m")
16900         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16901          UNSPEC_FIST_FLOOR))
16902    (use (match_operand:HI 2 "memory_operand" "m"))
16903    (use (match_operand:HI 3 "memory_operand" "m"))
16904    (clobber (match_scratch:XF 4 "=&1f"))]
16905   "TARGET_USE_FANCY_MATH_387
16906    && flag_unsafe_math_optimizations"
16907   "* return output_fix_trunc (insn, operands, 0);"
16908   [(set_attr "type" "fistp")
16909    (set_attr "i387_cw" "floor")
16910    (set_attr "mode" "DI")])
16911
16912 (define_insn "fistdi2_floor_with_temp"
16913   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16914         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16915          UNSPEC_FIST_FLOOR))
16916    (use (match_operand:HI 2 "memory_operand" "m,m"))
16917    (use (match_operand:HI 3 "memory_operand" "m,m"))
16918    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16919    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16920   "TARGET_USE_FANCY_MATH_387
16921    && flag_unsafe_math_optimizations"
16922   "#"
16923   [(set_attr "type" "fistp")
16924    (set_attr "i387_cw" "floor")
16925    (set_attr "mode" "DI")])
16926
16927 (define_split
16928   [(set (match_operand:DI 0 "register_operand" "")
16929         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16930          UNSPEC_FIST_FLOOR))
16931    (use (match_operand:HI 2 "memory_operand" ""))
16932    (use (match_operand:HI 3 "memory_operand" ""))
16933    (clobber (match_operand:DI 4 "memory_operand" ""))
16934    (clobber (match_scratch 5 ""))]
16935   "reload_completed"
16936   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16937               (use (match_dup 2))
16938               (use (match_dup 3))
16939               (clobber (match_dup 5))])
16940    (set (match_dup 0) (match_dup 4))]
16941   "")
16942
16943 (define_split
16944   [(set (match_operand:DI 0 "memory_operand" "")
16945         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16946          UNSPEC_FIST_FLOOR))
16947    (use (match_operand:HI 2 "memory_operand" ""))
16948    (use (match_operand:HI 3 "memory_operand" ""))
16949    (clobber (match_operand:DI 4 "memory_operand" ""))
16950    (clobber (match_scratch 5 ""))]
16951   "reload_completed"
16952   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16953               (use (match_dup 2))
16954               (use (match_dup 3))
16955               (clobber (match_dup 5))])]
16956   "")
16957
16958 (define_insn "fist<mode>2_floor"
16959   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16960         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16961          UNSPEC_FIST_FLOOR))
16962    (use (match_operand:HI 2 "memory_operand" "m"))
16963    (use (match_operand:HI 3 "memory_operand" "m"))]
16964   "TARGET_USE_FANCY_MATH_387
16965    && flag_unsafe_math_optimizations"
16966   "* return output_fix_trunc (insn, operands, 0);"
16967   [(set_attr "type" "fistp")
16968    (set_attr "i387_cw" "floor")
16969    (set_attr "mode" "<MODE>")])
16970
16971 (define_insn "fist<mode>2_floor_with_temp"
16972   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16973         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16974          UNSPEC_FIST_FLOOR))
16975    (use (match_operand:HI 2 "memory_operand" "m,m"))
16976    (use (match_operand:HI 3 "memory_operand" "m,m"))
16977    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16978   "TARGET_USE_FANCY_MATH_387
16979    && flag_unsafe_math_optimizations"
16980   "#"
16981   [(set_attr "type" "fistp")
16982    (set_attr "i387_cw" "floor")
16983    (set_attr "mode" "<MODE>")])
16984
16985 (define_split
16986   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16987         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16988          UNSPEC_FIST_FLOOR))
16989    (use (match_operand:HI 2 "memory_operand" ""))
16990    (use (match_operand:HI 3 "memory_operand" ""))
16991    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16992   "reload_completed"
16993   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16994                                   UNSPEC_FIST_FLOOR))
16995               (use (match_dup 2))
16996               (use (match_dup 3))])
16997    (set (match_dup 0) (match_dup 4))]
16998   "")
16999
17000 (define_split
17001   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17002         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17003          UNSPEC_FIST_FLOOR))
17004    (use (match_operand:HI 2 "memory_operand" ""))
17005    (use (match_operand:HI 3 "memory_operand" ""))
17006    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17007   "reload_completed"
17008   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17009                                   UNSPEC_FIST_FLOOR))
17010               (use (match_dup 2))
17011               (use (match_dup 3))])]
17012   "")
17013
17014 (define_expand "lfloorxf<mode>2"
17015   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17016                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17017                     UNSPEC_FIST_FLOOR))
17018               (clobber (reg:CC FLAGS_REG))])]
17019   "TARGET_USE_FANCY_MATH_387
17020    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17021    && flag_unsafe_math_optimizations"
17022   "")
17023
17024 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17025   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17026    (match_operand:MODEF 1 "register_operand" "")]
17027   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17028    && !flag_trapping_math"
17029 {
17030   if (TARGET_64BIT && optimize_insn_for_size_p ())
17031     FAIL;
17032   ix86_expand_lfloorceil (operand0, operand1, true);
17033   DONE;
17034 })
17035
17036 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17037 (define_insn_and_split "frndintxf2_ceil"
17038   [(set (match_operand:XF 0 "register_operand" "")
17039         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17040          UNSPEC_FRNDINT_CEIL))
17041    (clobber (reg:CC FLAGS_REG))]
17042   "TARGET_USE_FANCY_MATH_387
17043    && flag_unsafe_math_optimizations
17044    && can_create_pseudo_p ()"
17045   "#"
17046   "&& 1"
17047   [(const_int 0)]
17048 {
17049   ix86_optimize_mode_switching[I387_CEIL] = 1;
17050
17051   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17052   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17053
17054   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17055                                        operands[2], operands[3]));
17056   DONE;
17057 }
17058   [(set_attr "type" "frndint")
17059    (set_attr "i387_cw" "ceil")
17060    (set_attr "mode" "XF")])
17061
17062 (define_insn "frndintxf2_ceil_i387"
17063   [(set (match_operand:XF 0 "register_operand" "=f")
17064         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17065          UNSPEC_FRNDINT_CEIL))
17066    (use (match_operand:HI 2 "memory_operand" "m"))
17067    (use (match_operand:HI 3 "memory_operand" "m"))]
17068   "TARGET_USE_FANCY_MATH_387
17069    && flag_unsafe_math_optimizations"
17070   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17071   [(set_attr "type" "frndint")
17072    (set_attr "i387_cw" "ceil")
17073    (set_attr "mode" "XF")])
17074
17075 (define_expand "ceilxf2"
17076   [(use (match_operand:XF 0 "register_operand" ""))
17077    (use (match_operand:XF 1 "register_operand" ""))]
17078   "TARGET_USE_FANCY_MATH_387
17079    && flag_unsafe_math_optimizations"
17080 {
17081   if (optimize_insn_for_size_p ())
17082     FAIL;
17083   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17084   DONE;
17085 })
17086
17087 (define_expand "ceil<mode>2"
17088   [(use (match_operand:MODEF 0 "register_operand" ""))
17089    (use (match_operand:MODEF 1 "register_operand" ""))]
17090   "(TARGET_USE_FANCY_MATH_387
17091     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17092         || TARGET_MIX_SSE_I387)
17093     && flag_unsafe_math_optimizations)
17094    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17095        && !flag_trapping_math)"
17096 {
17097   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17098       && !flag_trapping_math
17099       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17100     {
17101       if (TARGET_ROUND)
17102         emit_insn (gen_sse4_1_round<mode>2
17103                    (operands[0], operands[1], GEN_INT (0x02)));
17104       else if (optimize_insn_for_size_p ())
17105         FAIL;
17106       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17107         ix86_expand_floorceil (operand0, operand1, false);
17108       else
17109         ix86_expand_floorceildf_32 (operand0, operand1, false);
17110     }
17111   else
17112     {
17113       rtx op0, op1;
17114
17115       if (optimize_insn_for_size_p ())
17116         FAIL;
17117
17118       op0 = gen_reg_rtx (XFmode);
17119       op1 = gen_reg_rtx (XFmode);
17120       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17121       emit_insn (gen_frndintxf2_ceil (op0, op1));
17122
17123       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17124     }
17125   DONE;
17126 })
17127
17128 (define_insn_and_split "*fist<mode>2_ceil_1"
17129   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17130         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17131          UNSPEC_FIST_CEIL))
17132    (clobber (reg:CC FLAGS_REG))]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations
17135    && can_create_pseudo_p ()"
17136   "#"
17137   "&& 1"
17138   [(const_int 0)]
17139 {
17140   ix86_optimize_mode_switching[I387_CEIL] = 1;
17141
17142   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17143   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17144   if (memory_operand (operands[0], VOIDmode))
17145     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17146                                      operands[2], operands[3]));
17147   else
17148     {
17149       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17150       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17151                                                  operands[2], operands[3],
17152                                                  operands[4]));
17153     }
17154   DONE;
17155 }
17156   [(set_attr "type" "fistp")
17157    (set_attr "i387_cw" "ceil")
17158    (set_attr "mode" "<MODE>")])
17159
17160 (define_insn "fistdi2_ceil"
17161   [(set (match_operand:DI 0 "memory_operand" "=m")
17162         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17163          UNSPEC_FIST_CEIL))
17164    (use (match_operand:HI 2 "memory_operand" "m"))
17165    (use (match_operand:HI 3 "memory_operand" "m"))
17166    (clobber (match_scratch:XF 4 "=&1f"))]
17167   "TARGET_USE_FANCY_MATH_387
17168    && flag_unsafe_math_optimizations"
17169   "* return output_fix_trunc (insn, operands, 0);"
17170   [(set_attr "type" "fistp")
17171    (set_attr "i387_cw" "ceil")
17172    (set_attr "mode" "DI")])
17173
17174 (define_insn "fistdi2_ceil_with_temp"
17175   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17176         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17177          UNSPEC_FIST_CEIL))
17178    (use (match_operand:HI 2 "memory_operand" "m,m"))
17179    (use (match_operand:HI 3 "memory_operand" "m,m"))
17180    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17181    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17182   "TARGET_USE_FANCY_MATH_387
17183    && flag_unsafe_math_optimizations"
17184   "#"
17185   [(set_attr "type" "fistp")
17186    (set_attr "i387_cw" "ceil")
17187    (set_attr "mode" "DI")])
17188
17189 (define_split
17190   [(set (match_operand:DI 0 "register_operand" "")
17191         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17192          UNSPEC_FIST_CEIL))
17193    (use (match_operand:HI 2 "memory_operand" ""))
17194    (use (match_operand:HI 3 "memory_operand" ""))
17195    (clobber (match_operand:DI 4 "memory_operand" ""))
17196    (clobber (match_scratch 5 ""))]
17197   "reload_completed"
17198   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17199               (use (match_dup 2))
17200               (use (match_dup 3))
17201               (clobber (match_dup 5))])
17202    (set (match_dup 0) (match_dup 4))]
17203   "")
17204
17205 (define_split
17206   [(set (match_operand:DI 0 "memory_operand" "")
17207         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17208          UNSPEC_FIST_CEIL))
17209    (use (match_operand:HI 2 "memory_operand" ""))
17210    (use (match_operand:HI 3 "memory_operand" ""))
17211    (clobber (match_operand:DI 4 "memory_operand" ""))
17212    (clobber (match_scratch 5 ""))]
17213   "reload_completed"
17214   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17215               (use (match_dup 2))
17216               (use (match_dup 3))
17217               (clobber (match_dup 5))])]
17218   "")
17219
17220 (define_insn "fist<mode>2_ceil"
17221   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17222         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17223          UNSPEC_FIST_CEIL))
17224    (use (match_operand:HI 2 "memory_operand" "m"))
17225    (use (match_operand:HI 3 "memory_operand" "m"))]
17226   "TARGET_USE_FANCY_MATH_387
17227    && flag_unsafe_math_optimizations"
17228   "* return output_fix_trunc (insn, operands, 0);"
17229   [(set_attr "type" "fistp")
17230    (set_attr "i387_cw" "ceil")
17231    (set_attr "mode" "<MODE>")])
17232
17233 (define_insn "fist<mode>2_ceil_with_temp"
17234   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17235         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17236          UNSPEC_FIST_CEIL))
17237    (use (match_operand:HI 2 "memory_operand" "m,m"))
17238    (use (match_operand:HI 3 "memory_operand" "m,m"))
17239    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17240   "TARGET_USE_FANCY_MATH_387
17241    && flag_unsafe_math_optimizations"
17242   "#"
17243   [(set_attr "type" "fistp")
17244    (set_attr "i387_cw" "ceil")
17245    (set_attr "mode" "<MODE>")])
17246
17247 (define_split
17248   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17249         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17250          UNSPEC_FIST_CEIL))
17251    (use (match_operand:HI 2 "memory_operand" ""))
17252    (use (match_operand:HI 3 "memory_operand" ""))
17253    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17254   "reload_completed"
17255   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17256                                   UNSPEC_FIST_CEIL))
17257               (use (match_dup 2))
17258               (use (match_dup 3))])
17259    (set (match_dup 0) (match_dup 4))]
17260   "")
17261
17262 (define_split
17263   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17264         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17265          UNSPEC_FIST_CEIL))
17266    (use (match_operand:HI 2 "memory_operand" ""))
17267    (use (match_operand:HI 3 "memory_operand" ""))
17268    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17269   "reload_completed"
17270   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17271                                   UNSPEC_FIST_CEIL))
17272               (use (match_dup 2))
17273               (use (match_dup 3))])]
17274   "")
17275
17276 (define_expand "lceilxf<mode>2"
17277   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17278                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17279                     UNSPEC_FIST_CEIL))
17280               (clobber (reg:CC FLAGS_REG))])]
17281   "TARGET_USE_FANCY_MATH_387
17282    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17283    && flag_unsafe_math_optimizations"
17284   "")
17285
17286 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17287   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17288    (match_operand:MODEF 1 "register_operand" "")]
17289   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17290    && !flag_trapping_math"
17291 {
17292   ix86_expand_lfloorceil (operand0, operand1, false);
17293   DONE;
17294 })
17295
17296 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17297 (define_insn_and_split "frndintxf2_trunc"
17298   [(set (match_operand:XF 0 "register_operand" "")
17299         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17300          UNSPEC_FRNDINT_TRUNC))
17301    (clobber (reg:CC FLAGS_REG))]
17302   "TARGET_USE_FANCY_MATH_387
17303    && flag_unsafe_math_optimizations
17304    && can_create_pseudo_p ()"
17305   "#"
17306   "&& 1"
17307   [(const_int 0)]
17308 {
17309   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17310
17311   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17312   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17313
17314   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17315                                         operands[2], operands[3]));
17316   DONE;
17317 }
17318   [(set_attr "type" "frndint")
17319    (set_attr "i387_cw" "trunc")
17320    (set_attr "mode" "XF")])
17321
17322 (define_insn "frndintxf2_trunc_i387"
17323   [(set (match_operand:XF 0 "register_operand" "=f")
17324         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17325          UNSPEC_FRNDINT_TRUNC))
17326    (use (match_operand:HI 2 "memory_operand" "m"))
17327    (use (match_operand:HI 3 "memory_operand" "m"))]
17328   "TARGET_USE_FANCY_MATH_387
17329    && flag_unsafe_math_optimizations"
17330   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17331   [(set_attr "type" "frndint")
17332    (set_attr "i387_cw" "trunc")
17333    (set_attr "mode" "XF")])
17334
17335 (define_expand "btruncxf2"
17336   [(use (match_operand:XF 0 "register_operand" ""))
17337    (use (match_operand:XF 1 "register_operand" ""))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && flag_unsafe_math_optimizations"
17340 {
17341   if (optimize_insn_for_size_p ())
17342     FAIL;
17343   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17344   DONE;
17345 })
17346
17347 (define_expand "btrunc<mode>2"
17348   [(use (match_operand:MODEF 0 "register_operand" ""))
17349    (use (match_operand:MODEF 1 "register_operand" ""))]
17350   "(TARGET_USE_FANCY_MATH_387
17351     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17352         || TARGET_MIX_SSE_I387)
17353     && flag_unsafe_math_optimizations)
17354    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17355        && !flag_trapping_math)"
17356 {
17357   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17358       && !flag_trapping_math
17359       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17360     {
17361       if (TARGET_ROUND)
17362         emit_insn (gen_sse4_1_round<mode>2
17363                    (operands[0], operands[1], GEN_INT (0x03)));
17364       else if (optimize_insn_for_size_p ())
17365         FAIL;
17366       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17367         ix86_expand_trunc (operand0, operand1);
17368       else
17369         ix86_expand_truncdf_32 (operand0, operand1);
17370     }
17371   else
17372     {
17373       rtx op0, op1;
17374
17375       if (optimize_insn_for_size_p ())
17376         FAIL;
17377
17378       op0 = gen_reg_rtx (XFmode);
17379       op1 = gen_reg_rtx (XFmode);
17380       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17381       emit_insn (gen_frndintxf2_trunc (op0, op1));
17382
17383       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17384     }
17385   DONE;
17386 })
17387
17388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17389 (define_insn_and_split "frndintxf2_mask_pm"
17390   [(set (match_operand:XF 0 "register_operand" "")
17391         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17392          UNSPEC_FRNDINT_MASK_PM))
17393    (clobber (reg:CC FLAGS_REG))]
17394   "TARGET_USE_FANCY_MATH_387
17395    && flag_unsafe_math_optimizations
17396    && can_create_pseudo_p ()"
17397   "#"
17398   "&& 1"
17399   [(const_int 0)]
17400 {
17401   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17402
17403   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17404   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17405
17406   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17407                                           operands[2], operands[3]));
17408   DONE;
17409 }
17410   [(set_attr "type" "frndint")
17411    (set_attr "i387_cw" "mask_pm")
17412    (set_attr "mode" "XF")])
17413
17414 (define_insn "frndintxf2_mask_pm_i387"
17415   [(set (match_operand:XF 0 "register_operand" "=f")
17416         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17417          UNSPEC_FRNDINT_MASK_PM))
17418    (use (match_operand:HI 2 "memory_operand" "m"))
17419    (use (match_operand:HI 3 "memory_operand" "m"))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && flag_unsafe_math_optimizations"
17422   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17423   [(set_attr "type" "frndint")
17424    (set_attr "i387_cw" "mask_pm")
17425    (set_attr "mode" "XF")])
17426
17427 (define_expand "nearbyintxf2"
17428   [(use (match_operand:XF 0 "register_operand" ""))
17429    (use (match_operand:XF 1 "register_operand" ""))]
17430   "TARGET_USE_FANCY_MATH_387
17431    && flag_unsafe_math_optimizations"
17432 {
17433   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17434
17435   DONE;
17436 })
17437
17438 (define_expand "nearbyint<mode>2"
17439   [(use (match_operand:MODEF 0 "register_operand" ""))
17440    (use (match_operand:MODEF 1 "register_operand" ""))]
17441   "TARGET_USE_FANCY_MATH_387
17442    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17443        || TARGET_MIX_SSE_I387)
17444    && flag_unsafe_math_optimizations"
17445 {
17446   rtx op0 = gen_reg_rtx (XFmode);
17447   rtx op1 = gen_reg_rtx (XFmode);
17448
17449   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17450   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17451
17452   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17453   DONE;
17454 })
17455
17456 (define_insn "fxam<mode>2_i387"
17457   [(set (match_operand:HI 0 "register_operand" "=a")
17458         (unspec:HI
17459           [(match_operand:X87MODEF 1 "register_operand" "f")]
17460           UNSPEC_FXAM))]
17461   "TARGET_USE_FANCY_MATH_387"
17462   "fxam\n\tfnstsw\t%0"
17463   [(set_attr "type" "multi")
17464    (set_attr "length" "4")
17465    (set_attr "unit" "i387")
17466    (set_attr "mode" "<MODE>")])
17467
17468 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17469   [(set (match_operand:HI 0 "register_operand" "")
17470         (unspec:HI
17471           [(match_operand:MODEF 1 "memory_operand" "")]
17472           UNSPEC_FXAM_MEM))]
17473   "TARGET_USE_FANCY_MATH_387
17474    && can_create_pseudo_p ()"
17475   "#"
17476   "&& 1"
17477   [(set (match_dup 2)(match_dup 1))
17478    (set (match_dup 0)
17479         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17480 {
17481   operands[2] = gen_reg_rtx (<MODE>mode);
17482
17483   MEM_VOLATILE_P (operands[1]) = 1;
17484 }
17485   [(set_attr "type" "multi")
17486    (set_attr "unit" "i387")
17487    (set_attr "mode" "<MODE>")])
17488
17489 (define_expand "isinfxf2"
17490   [(use (match_operand:SI 0 "register_operand" ""))
17491    (use (match_operand:XF 1 "register_operand" ""))]
17492   "TARGET_USE_FANCY_MATH_387
17493    && TARGET_C99_FUNCTIONS"
17494 {
17495   rtx mask = GEN_INT (0x45);
17496   rtx val = GEN_INT (0x05);
17497
17498   rtx cond;
17499
17500   rtx scratch = gen_reg_rtx (HImode);
17501   rtx res = gen_reg_rtx (QImode);
17502
17503   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17504
17505   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17506   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17507   cond = gen_rtx_fmt_ee (EQ, QImode,
17508                          gen_rtx_REG (CCmode, FLAGS_REG),
17509                          const0_rtx);
17510   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17511   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17512   DONE;
17513 })
17514
17515 (define_expand "isinf<mode>2"
17516   [(use (match_operand:SI 0 "register_operand" ""))
17517    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17518   "TARGET_USE_FANCY_MATH_387
17519    && TARGET_C99_FUNCTIONS
17520    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17521 {
17522   rtx mask = GEN_INT (0x45);
17523   rtx val = GEN_INT (0x05);
17524
17525   rtx cond;
17526
17527   rtx scratch = gen_reg_rtx (HImode);
17528   rtx res = gen_reg_rtx (QImode);
17529
17530   /* Remove excess precision by forcing value through memory. */
17531   if (memory_operand (operands[1], VOIDmode))
17532     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17533   else
17534     {
17535       enum ix86_stack_slot slot = (virtuals_instantiated
17536                                    ? SLOT_TEMP
17537                                    : SLOT_VIRTUAL);
17538       rtx temp = assign_386_stack_local (<MODE>mode, slot);
17539
17540       emit_move_insn (temp, operands[1]);
17541       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17542     }
17543
17544   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17545   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17546   cond = gen_rtx_fmt_ee (EQ, QImode,
17547                          gen_rtx_REG (CCmode, FLAGS_REG),
17548                          const0_rtx);
17549   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17550   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17551   DONE;
17552 })
17553
17554 (define_expand "signbit<mode>2"
17555   [(use (match_operand:SI 0 "register_operand" ""))
17556    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17557   "TARGET_USE_FANCY_MATH_387
17558    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17559 {
17560   rtx mask = GEN_INT (0x0200);
17561
17562   rtx scratch = gen_reg_rtx (HImode);
17563
17564   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17565   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17566   DONE;
17567 })
17568 \f
17569 ;; Block operation instructions
17570
17571 (define_insn "cld"
17572   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17573   ""
17574   "cld"
17575   [(set_attr "length" "1")
17576    (set_attr "length_immediate" "0")
17577    (set_attr "modrm" "0")])
17578
17579 (define_expand "movmemsi"
17580   [(use (match_operand:BLK 0 "memory_operand" ""))
17581    (use (match_operand:BLK 1 "memory_operand" ""))
17582    (use (match_operand:SI 2 "nonmemory_operand" ""))
17583    (use (match_operand:SI 3 "const_int_operand" ""))
17584    (use (match_operand:SI 4 "const_int_operand" ""))
17585    (use (match_operand:SI 5 "const_int_operand" ""))]
17586   ""
17587 {
17588  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17589                          operands[4], operands[5]))
17590    DONE;
17591  else
17592    FAIL;
17593 })
17594
17595 (define_expand "movmemdi"
17596   [(use (match_operand:BLK 0 "memory_operand" ""))
17597    (use (match_operand:BLK 1 "memory_operand" ""))
17598    (use (match_operand:DI 2 "nonmemory_operand" ""))
17599    (use (match_operand:DI 3 "const_int_operand" ""))
17600    (use (match_operand:SI 4 "const_int_operand" ""))
17601    (use (match_operand:SI 5 "const_int_operand" ""))]
17602   "TARGET_64BIT"
17603 {
17604  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17605                          operands[4], operands[5]))
17606    DONE;
17607  else
17608    FAIL;
17609 })
17610
17611 ;; Most CPUs don't like single string operations
17612 ;; Handle this case here to simplify previous expander.
17613
17614 (define_expand "strmov"
17615   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17616    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17617    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17618               (clobber (reg:CC FLAGS_REG))])
17619    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17620               (clobber (reg:CC FLAGS_REG))])]
17621   ""
17622 {
17623   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17624
17625   /* If .md ever supports :P for Pmode, these can be directly
17626      in the pattern above.  */
17627   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17628   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17629
17630   /* Can't use this if the user has appropriated esi or edi.  */
17631   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17632       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17633     {
17634       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17635                                       operands[2], operands[3],
17636                                       operands[5], operands[6]));
17637       DONE;
17638     }
17639
17640   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17641 })
17642
17643 (define_expand "strmov_singleop"
17644   [(parallel [(set (match_operand 1 "memory_operand" "")
17645                    (match_operand 3 "memory_operand" ""))
17646               (set (match_operand 0 "register_operand" "")
17647                    (match_operand 4 "" ""))
17648               (set (match_operand 2 "register_operand" "")
17649                    (match_operand 5 "" ""))])]
17650   ""
17651   "ix86_current_function_needs_cld = 1;")
17652
17653 (define_insn "*strmovdi_rex_1"
17654   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17655         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17656    (set (match_operand:DI 0 "register_operand" "=D")
17657         (plus:DI (match_dup 2)
17658                  (const_int 8)))
17659    (set (match_operand:DI 1 "register_operand" "=S")
17660         (plus:DI (match_dup 3)
17661                  (const_int 8)))]
17662   "TARGET_64BIT"
17663   "movsq"
17664   [(set_attr "type" "str")
17665    (set_attr "mode" "DI")
17666    (set_attr "memory" "both")])
17667
17668 (define_insn "*strmovsi_1"
17669   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17670         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17671    (set (match_operand:SI 0 "register_operand" "=D")
17672         (plus:SI (match_dup 2)
17673                  (const_int 4)))
17674    (set (match_operand:SI 1 "register_operand" "=S")
17675         (plus:SI (match_dup 3)
17676                  (const_int 4)))]
17677   "!TARGET_64BIT"
17678   "movs{l|d}"
17679   [(set_attr "type" "str")
17680    (set_attr "mode" "SI")
17681    (set_attr "memory" "both")])
17682
17683 (define_insn "*strmovsi_rex_1"
17684   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17685         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17686    (set (match_operand:DI 0 "register_operand" "=D")
17687         (plus:DI (match_dup 2)
17688                  (const_int 4)))
17689    (set (match_operand:DI 1 "register_operand" "=S")
17690         (plus:DI (match_dup 3)
17691                  (const_int 4)))]
17692   "TARGET_64BIT"
17693   "movs{l|d}"
17694   [(set_attr "type" "str")
17695    (set_attr "mode" "SI")
17696    (set_attr "memory" "both")])
17697
17698 (define_insn "*strmovhi_1"
17699   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17700         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17701    (set (match_operand:SI 0 "register_operand" "=D")
17702         (plus:SI (match_dup 2)
17703                  (const_int 2)))
17704    (set (match_operand:SI 1 "register_operand" "=S")
17705         (plus:SI (match_dup 3)
17706                  (const_int 2)))]
17707   "!TARGET_64BIT"
17708   "movsw"
17709   [(set_attr "type" "str")
17710    (set_attr "memory" "both")
17711    (set_attr "mode" "HI")])
17712
17713 (define_insn "*strmovhi_rex_1"
17714   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17715         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17716    (set (match_operand:DI 0 "register_operand" "=D")
17717         (plus:DI (match_dup 2)
17718                  (const_int 2)))
17719    (set (match_operand:DI 1 "register_operand" "=S")
17720         (plus:DI (match_dup 3)
17721                  (const_int 2)))]
17722   "TARGET_64BIT"
17723   "movsw"
17724   [(set_attr "type" "str")
17725    (set_attr "memory" "both")
17726    (set_attr "mode" "HI")])
17727
17728 (define_insn "*strmovqi_1"
17729   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17730         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17731    (set (match_operand:SI 0 "register_operand" "=D")
17732         (plus:SI (match_dup 2)
17733                  (const_int 1)))
17734    (set (match_operand:SI 1 "register_operand" "=S")
17735         (plus:SI (match_dup 3)
17736                  (const_int 1)))]
17737   "!TARGET_64BIT"
17738   "movsb"
17739   [(set_attr "type" "str")
17740    (set_attr "memory" "both")
17741    (set_attr "mode" "QI")])
17742
17743 (define_insn "*strmovqi_rex_1"
17744   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17745         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17746    (set (match_operand:DI 0 "register_operand" "=D")
17747         (plus:DI (match_dup 2)
17748                  (const_int 1)))
17749    (set (match_operand:DI 1 "register_operand" "=S")
17750         (plus:DI (match_dup 3)
17751                  (const_int 1)))]
17752   "TARGET_64BIT"
17753   "movsb"
17754   [(set_attr "type" "str")
17755    (set_attr "memory" "both")
17756    (set_attr "prefix_rex" "0")
17757    (set_attr "mode" "QI")])
17758
17759 (define_expand "rep_mov"
17760   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17761               (set (match_operand 0 "register_operand" "")
17762                    (match_operand 5 "" ""))
17763               (set (match_operand 2 "register_operand" "")
17764                    (match_operand 6 "" ""))
17765               (set (match_operand 1 "memory_operand" "")
17766                    (match_operand 3 "memory_operand" ""))
17767               (use (match_dup 4))])]
17768   ""
17769   "ix86_current_function_needs_cld = 1;")
17770
17771 (define_insn "*rep_movdi_rex64"
17772   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17773    (set (match_operand:DI 0 "register_operand" "=D")
17774         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17775                             (const_int 3))
17776                  (match_operand:DI 3 "register_operand" "0")))
17777    (set (match_operand:DI 1 "register_operand" "=S")
17778         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17779                  (match_operand:DI 4 "register_operand" "1")))
17780    (set (mem:BLK (match_dup 3))
17781         (mem:BLK (match_dup 4)))
17782    (use (match_dup 5))]
17783   "TARGET_64BIT"
17784   "rep movsq"
17785   [(set_attr "type" "str")
17786    (set_attr "prefix_rep" "1")
17787    (set_attr "memory" "both")
17788    (set_attr "mode" "DI")])
17789
17790 (define_insn "*rep_movsi"
17791   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17792    (set (match_operand:SI 0 "register_operand" "=D")
17793         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17794                             (const_int 2))
17795                  (match_operand:SI 3 "register_operand" "0")))
17796    (set (match_operand:SI 1 "register_operand" "=S")
17797         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17798                  (match_operand:SI 4 "register_operand" "1")))
17799    (set (mem:BLK (match_dup 3))
17800         (mem:BLK (match_dup 4)))
17801    (use (match_dup 5))]
17802   "!TARGET_64BIT"
17803   "rep movs{l|d}"
17804   [(set_attr "type" "str")
17805    (set_attr "prefix_rep" "1")
17806    (set_attr "memory" "both")
17807    (set_attr "mode" "SI")])
17808
17809 (define_insn "*rep_movsi_rex64"
17810   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17811    (set (match_operand:DI 0 "register_operand" "=D")
17812         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17813                             (const_int 2))
17814                  (match_operand:DI 3 "register_operand" "0")))
17815    (set (match_operand:DI 1 "register_operand" "=S")
17816         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17817                  (match_operand:DI 4 "register_operand" "1")))
17818    (set (mem:BLK (match_dup 3))
17819         (mem:BLK (match_dup 4)))
17820    (use (match_dup 5))]
17821   "TARGET_64BIT"
17822   "rep movs{l|d}"
17823   [(set_attr "type" "str")
17824    (set_attr "prefix_rep" "1")
17825    (set_attr "memory" "both")
17826    (set_attr "mode" "SI")])
17827
17828 (define_insn "*rep_movqi"
17829   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17830    (set (match_operand:SI 0 "register_operand" "=D")
17831         (plus:SI (match_operand:SI 3 "register_operand" "0")
17832                  (match_operand:SI 5 "register_operand" "2")))
17833    (set (match_operand:SI 1 "register_operand" "=S")
17834         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17835    (set (mem:BLK (match_dup 3))
17836         (mem:BLK (match_dup 4)))
17837    (use (match_dup 5))]
17838   "!TARGET_64BIT"
17839   "rep movsb"
17840   [(set_attr "type" "str")
17841    (set_attr "prefix_rep" "1")
17842    (set_attr "memory" "both")
17843    (set_attr "mode" "SI")])
17844
17845 (define_insn "*rep_movqi_rex64"
17846   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17847    (set (match_operand:DI 0 "register_operand" "=D")
17848         (plus:DI (match_operand:DI 3 "register_operand" "0")
17849                  (match_operand:DI 5 "register_operand" "2")))
17850    (set (match_operand:DI 1 "register_operand" "=S")
17851         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17852    (set (mem:BLK (match_dup 3))
17853         (mem:BLK (match_dup 4)))
17854    (use (match_dup 5))]
17855   "TARGET_64BIT"
17856   "rep movsb"
17857   [(set_attr "type" "str")
17858    (set_attr "prefix_rep" "1")
17859    (set_attr "memory" "both")
17860    (set_attr "mode" "SI")])
17861
17862 (define_expand "setmemsi"
17863    [(use (match_operand:BLK 0 "memory_operand" ""))
17864     (use (match_operand:SI 1 "nonmemory_operand" ""))
17865     (use (match_operand 2 "const_int_operand" ""))
17866     (use (match_operand 3 "const_int_operand" ""))
17867     (use (match_operand:SI 4 "const_int_operand" ""))
17868     (use (match_operand:SI 5 "const_int_operand" ""))]
17869   ""
17870 {
17871  if (ix86_expand_setmem (operands[0], operands[1],
17872                          operands[2], operands[3],
17873                          operands[4], operands[5]))
17874    DONE;
17875  else
17876    FAIL;
17877 })
17878
17879 (define_expand "setmemdi"
17880    [(use (match_operand:BLK 0 "memory_operand" ""))
17881     (use (match_operand:DI 1 "nonmemory_operand" ""))
17882     (use (match_operand 2 "const_int_operand" ""))
17883     (use (match_operand 3 "const_int_operand" ""))
17884     (use (match_operand 4 "const_int_operand" ""))
17885     (use (match_operand 5 "const_int_operand" ""))]
17886   "TARGET_64BIT"
17887 {
17888  if (ix86_expand_setmem (operands[0], operands[1],
17889                          operands[2], operands[3],
17890                          operands[4], operands[5]))
17891    DONE;
17892  else
17893    FAIL;
17894 })
17895
17896 ;; Most CPUs don't like single string operations
17897 ;; Handle this case here to simplify previous expander.
17898
17899 (define_expand "strset"
17900   [(set (match_operand 1 "memory_operand" "")
17901         (match_operand 2 "register_operand" ""))
17902    (parallel [(set (match_operand 0 "register_operand" "")
17903                    (match_dup 3))
17904               (clobber (reg:CC FLAGS_REG))])]
17905   ""
17906 {
17907   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17908     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17909
17910   /* If .md ever supports :P for Pmode, this can be directly
17911      in the pattern above.  */
17912   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17913                               GEN_INT (GET_MODE_SIZE (GET_MODE
17914                                                       (operands[2]))));
17915   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17916     {
17917       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17918                                       operands[3]));
17919       DONE;
17920     }
17921 })
17922
17923 (define_expand "strset_singleop"
17924   [(parallel [(set (match_operand 1 "memory_operand" "")
17925                    (match_operand 2 "register_operand" ""))
17926               (set (match_operand 0 "register_operand" "")
17927                    (match_operand 3 "" ""))])]
17928   ""
17929   "ix86_current_function_needs_cld = 1;")
17930
17931 (define_insn "*strsetdi_rex_1"
17932   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17933         (match_operand:DI 2 "register_operand" "a"))
17934    (set (match_operand:DI 0 "register_operand" "=D")
17935         (plus:DI (match_dup 1)
17936                  (const_int 8)))]
17937   "TARGET_64BIT"
17938   "stosq"
17939   [(set_attr "type" "str")
17940    (set_attr "memory" "store")
17941    (set_attr "mode" "DI")])
17942
17943 (define_insn "*strsetsi_1"
17944   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17945         (match_operand:SI 2 "register_operand" "a"))
17946    (set (match_operand:SI 0 "register_operand" "=D")
17947         (plus:SI (match_dup 1)
17948                  (const_int 4)))]
17949   "!TARGET_64BIT"
17950   "stos{l|d}"
17951   [(set_attr "type" "str")
17952    (set_attr "memory" "store")
17953    (set_attr "mode" "SI")])
17954
17955 (define_insn "*strsetsi_rex_1"
17956   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17957         (match_operand:SI 2 "register_operand" "a"))
17958    (set (match_operand:DI 0 "register_operand" "=D")
17959         (plus:DI (match_dup 1)
17960                  (const_int 4)))]
17961   "TARGET_64BIT"
17962   "stos{l|d}"
17963   [(set_attr "type" "str")
17964    (set_attr "memory" "store")
17965    (set_attr "mode" "SI")])
17966
17967 (define_insn "*strsethi_1"
17968   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17969         (match_operand:HI 2 "register_operand" "a"))
17970    (set (match_operand:SI 0 "register_operand" "=D")
17971         (plus:SI (match_dup 1)
17972                  (const_int 2)))]
17973   "!TARGET_64BIT"
17974   "stosw"
17975   [(set_attr "type" "str")
17976    (set_attr "memory" "store")
17977    (set_attr "mode" "HI")])
17978
17979 (define_insn "*strsethi_rex_1"
17980   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17981         (match_operand:HI 2 "register_operand" "a"))
17982    (set (match_operand:DI 0 "register_operand" "=D")
17983         (plus:DI (match_dup 1)
17984                  (const_int 2)))]
17985   "TARGET_64BIT"
17986   "stosw"
17987   [(set_attr "type" "str")
17988    (set_attr "memory" "store")
17989    (set_attr "mode" "HI")])
17990
17991 (define_insn "*strsetqi_1"
17992   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17993         (match_operand:QI 2 "register_operand" "a"))
17994    (set (match_operand:SI 0 "register_operand" "=D")
17995         (plus:SI (match_dup 1)
17996                  (const_int 1)))]
17997   "!TARGET_64BIT"
17998   "stosb"
17999   [(set_attr "type" "str")
18000    (set_attr "memory" "store")
18001    (set_attr "mode" "QI")])
18002
18003 (define_insn "*strsetqi_rex_1"
18004   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18005         (match_operand:QI 2 "register_operand" "a"))
18006    (set (match_operand:DI 0 "register_operand" "=D")
18007         (plus:DI (match_dup 1)
18008                  (const_int 1)))]
18009   "TARGET_64BIT"
18010   "stosb"
18011   [(set_attr "type" "str")
18012    (set_attr "memory" "store")
18013    (set_attr "prefix_rex" "0")
18014    (set_attr "mode" "QI")])
18015
18016 (define_expand "rep_stos"
18017   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18018               (set (match_operand 0 "register_operand" "")
18019                    (match_operand 4 "" ""))
18020               (set (match_operand 2 "memory_operand" "") (const_int 0))
18021               (use (match_operand 3 "register_operand" ""))
18022               (use (match_dup 1))])]
18023   ""
18024   "ix86_current_function_needs_cld = 1;")
18025
18026 (define_insn "*rep_stosdi_rex64"
18027   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18028    (set (match_operand:DI 0 "register_operand" "=D")
18029         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18030                             (const_int 3))
18031                  (match_operand:DI 3 "register_operand" "0")))
18032    (set (mem:BLK (match_dup 3))
18033         (const_int 0))
18034    (use (match_operand:DI 2 "register_operand" "a"))
18035    (use (match_dup 4))]
18036   "TARGET_64BIT"
18037   "rep stosq"
18038   [(set_attr "type" "str")
18039    (set_attr "prefix_rep" "1")
18040    (set_attr "memory" "store")
18041    (set_attr "mode" "DI")])
18042
18043 (define_insn "*rep_stossi"
18044   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18045    (set (match_operand:SI 0 "register_operand" "=D")
18046         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18047                             (const_int 2))
18048                  (match_operand:SI 3 "register_operand" "0")))
18049    (set (mem:BLK (match_dup 3))
18050         (const_int 0))
18051    (use (match_operand:SI 2 "register_operand" "a"))
18052    (use (match_dup 4))]
18053   "!TARGET_64BIT"
18054   "rep stos{l|d}"
18055   [(set_attr "type" "str")
18056    (set_attr "prefix_rep" "1")
18057    (set_attr "memory" "store")
18058    (set_attr "mode" "SI")])
18059
18060 (define_insn "*rep_stossi_rex64"
18061   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18062    (set (match_operand:DI 0 "register_operand" "=D")
18063         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18064                             (const_int 2))
18065                  (match_operand:DI 3 "register_operand" "0")))
18066    (set (mem:BLK (match_dup 3))
18067         (const_int 0))
18068    (use (match_operand:SI 2 "register_operand" "a"))
18069    (use (match_dup 4))]
18070   "TARGET_64BIT"
18071   "rep stos{l|d}"
18072   [(set_attr "type" "str")
18073    (set_attr "prefix_rep" "1")
18074    (set_attr "memory" "store")
18075    (set_attr "mode" "SI")])
18076
18077 (define_insn "*rep_stosqi"
18078   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18079    (set (match_operand:SI 0 "register_operand" "=D")
18080         (plus:SI (match_operand:SI 3 "register_operand" "0")
18081                  (match_operand:SI 4 "register_operand" "1")))
18082    (set (mem:BLK (match_dup 3))
18083         (const_int 0))
18084    (use (match_operand:QI 2 "register_operand" "a"))
18085    (use (match_dup 4))]
18086   "!TARGET_64BIT"
18087   "rep stosb"
18088   [(set_attr "type" "str")
18089    (set_attr "prefix_rep" "1")
18090    (set_attr "memory" "store")
18091    (set_attr "mode" "QI")])
18092
18093 (define_insn "*rep_stosqi_rex64"
18094   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18095    (set (match_operand:DI 0 "register_operand" "=D")
18096         (plus:DI (match_operand:DI 3 "register_operand" "0")
18097                  (match_operand:DI 4 "register_operand" "1")))
18098    (set (mem:BLK (match_dup 3))
18099         (const_int 0))
18100    (use (match_operand:QI 2 "register_operand" "a"))
18101    (use (match_dup 4))]
18102   "TARGET_64BIT"
18103   "rep stosb"
18104   [(set_attr "type" "str")
18105    (set_attr "prefix_rep" "1")
18106    (set_attr "memory" "store")
18107    (set_attr "prefix_rex" "0")
18108    (set_attr "mode" "QI")])
18109
18110 (define_expand "cmpstrnsi"
18111   [(set (match_operand:SI 0 "register_operand" "")
18112         (compare:SI (match_operand:BLK 1 "general_operand" "")
18113                     (match_operand:BLK 2 "general_operand" "")))
18114    (use (match_operand 3 "general_operand" ""))
18115    (use (match_operand 4 "immediate_operand" ""))]
18116   ""
18117 {
18118   rtx addr1, addr2, out, outlow, count, countreg, align;
18119
18120   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18121     FAIL;
18122
18123   /* Can't use this if the user has appropriated esi or edi.  */
18124   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18125     FAIL;
18126
18127   out = operands[0];
18128   if (!REG_P (out))
18129     out = gen_reg_rtx (SImode);
18130
18131   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18132   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18133   if (addr1 != XEXP (operands[1], 0))
18134     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18135   if (addr2 != XEXP (operands[2], 0))
18136     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18137
18138   count = operands[3];
18139   countreg = ix86_zero_extend_to_Pmode (count);
18140
18141   /* %%% Iff we are testing strict equality, we can use known alignment
18142      to good advantage.  This may be possible with combine, particularly
18143      once cc0 is dead.  */
18144   align = operands[4];
18145
18146   if (CONST_INT_P (count))
18147     {
18148       if (INTVAL (count) == 0)
18149         {
18150           emit_move_insn (operands[0], const0_rtx);
18151           DONE;
18152         }
18153       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18154                                      operands[1], operands[2]));
18155     }
18156   else
18157     {
18158       rtx (*cmp_insn)(rtx, rtx);
18159
18160       if (TARGET_64BIT)
18161         cmp_insn = gen_cmpdi_1;
18162       else
18163         cmp_insn = gen_cmpsi_1;
18164       emit_insn (cmp_insn (countreg, countreg));
18165       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18166                                   operands[1], operands[2]));
18167     }
18168
18169   outlow = gen_lowpart (QImode, out);
18170   emit_insn (gen_cmpintqi (outlow));
18171   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18172
18173   if (operands[0] != out)
18174     emit_move_insn (operands[0], out);
18175
18176   DONE;
18177 })
18178
18179 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18180
18181 (define_expand "cmpintqi"
18182   [(set (match_dup 1)
18183         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18184    (set (match_dup 2)
18185         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18186    (parallel [(set (match_operand:QI 0 "register_operand" "")
18187                    (minus:QI (match_dup 1)
18188                              (match_dup 2)))
18189               (clobber (reg:CC FLAGS_REG))])]
18190   ""
18191   "operands[1] = gen_reg_rtx (QImode);
18192    operands[2] = gen_reg_rtx (QImode);")
18193
18194 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18195 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18196
18197 (define_expand "cmpstrnqi_nz_1"
18198   [(parallel [(set (reg:CC FLAGS_REG)
18199                    (compare:CC (match_operand 4 "memory_operand" "")
18200                                (match_operand 5 "memory_operand" "")))
18201               (use (match_operand 2 "register_operand" ""))
18202               (use (match_operand:SI 3 "immediate_operand" ""))
18203               (clobber (match_operand 0 "register_operand" ""))
18204               (clobber (match_operand 1 "register_operand" ""))
18205               (clobber (match_dup 2))])]
18206   ""
18207   "ix86_current_function_needs_cld = 1;")
18208
18209 (define_insn "*cmpstrnqi_nz_1"
18210   [(set (reg:CC FLAGS_REG)
18211         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18212                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18213    (use (match_operand:SI 6 "register_operand" "2"))
18214    (use (match_operand:SI 3 "immediate_operand" "i"))
18215    (clobber (match_operand:SI 0 "register_operand" "=S"))
18216    (clobber (match_operand:SI 1 "register_operand" "=D"))
18217    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18218   "!TARGET_64BIT"
18219   "repz cmpsb"
18220   [(set_attr "type" "str")
18221    (set_attr "mode" "QI")
18222    (set_attr "prefix_rep" "1")])
18223
18224 (define_insn "*cmpstrnqi_nz_rex_1"
18225   [(set (reg:CC FLAGS_REG)
18226         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18227                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18228    (use (match_operand:DI 6 "register_operand" "2"))
18229    (use (match_operand:SI 3 "immediate_operand" "i"))
18230    (clobber (match_operand:DI 0 "register_operand" "=S"))
18231    (clobber (match_operand:DI 1 "register_operand" "=D"))
18232    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18233   "TARGET_64BIT"
18234   "repz cmpsb"
18235   [(set_attr "type" "str")
18236    (set_attr "mode" "QI")
18237    (set_attr "prefix_rex" "0")
18238    (set_attr "prefix_rep" "1")])
18239
18240 ;; The same, but the count is not known to not be zero.
18241
18242 (define_expand "cmpstrnqi_1"
18243   [(parallel [(set (reg:CC FLAGS_REG)
18244                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18245                                      (const_int 0))
18246                   (compare:CC (match_operand 4 "memory_operand" "")
18247                               (match_operand 5 "memory_operand" ""))
18248                   (const_int 0)))
18249               (use (match_operand:SI 3 "immediate_operand" ""))
18250               (use (reg:CC FLAGS_REG))
18251               (clobber (match_operand 0 "register_operand" ""))
18252               (clobber (match_operand 1 "register_operand" ""))
18253               (clobber (match_dup 2))])]
18254   ""
18255   "ix86_current_function_needs_cld = 1;")
18256
18257 (define_insn "*cmpstrnqi_1"
18258   [(set (reg:CC FLAGS_REG)
18259         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18260                              (const_int 0))
18261           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18262                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18263           (const_int 0)))
18264    (use (match_operand:SI 3 "immediate_operand" "i"))
18265    (use (reg:CC FLAGS_REG))
18266    (clobber (match_operand:SI 0 "register_operand" "=S"))
18267    (clobber (match_operand:SI 1 "register_operand" "=D"))
18268    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18269   "!TARGET_64BIT"
18270   "repz cmpsb"
18271   [(set_attr "type" "str")
18272    (set_attr "mode" "QI")
18273    (set_attr "prefix_rep" "1")])
18274
18275 (define_insn "*cmpstrnqi_rex_1"
18276   [(set (reg:CC FLAGS_REG)
18277         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18278                              (const_int 0))
18279           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18280                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18281           (const_int 0)))
18282    (use (match_operand:SI 3 "immediate_operand" "i"))
18283    (use (reg:CC FLAGS_REG))
18284    (clobber (match_operand:DI 0 "register_operand" "=S"))
18285    (clobber (match_operand:DI 1 "register_operand" "=D"))
18286    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18287   "TARGET_64BIT"
18288   "repz cmpsb"
18289   [(set_attr "type" "str")
18290    (set_attr "mode" "QI")
18291    (set_attr "prefix_rex" "0")
18292    (set_attr "prefix_rep" "1")])
18293
18294 (define_expand "strlensi"
18295   [(set (match_operand:SI 0 "register_operand" "")
18296         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18297                     (match_operand:QI 2 "immediate_operand" "")
18298                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18299   ""
18300 {
18301  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18302    DONE;
18303  else
18304    FAIL;
18305 })
18306
18307 (define_expand "strlendi"
18308   [(set (match_operand:DI 0 "register_operand" "")
18309         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18310                     (match_operand:QI 2 "immediate_operand" "")
18311                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18312   ""
18313 {
18314  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18315    DONE;
18316  else
18317    FAIL;
18318 })
18319
18320 (define_expand "strlenqi_1"
18321   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18322               (clobber (match_operand 1 "register_operand" ""))
18323               (clobber (reg:CC FLAGS_REG))])]
18324   ""
18325   "ix86_current_function_needs_cld = 1;")
18326
18327 (define_insn "*strlenqi_1"
18328   [(set (match_operand:SI 0 "register_operand" "=&c")
18329         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18330                     (match_operand:QI 2 "register_operand" "a")
18331                     (match_operand:SI 3 "immediate_operand" "i")
18332                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18333    (clobber (match_operand:SI 1 "register_operand" "=D"))
18334    (clobber (reg:CC FLAGS_REG))]
18335   "!TARGET_64BIT"
18336   "repnz scasb"
18337   [(set_attr "type" "str")
18338    (set_attr "mode" "QI")
18339    (set_attr "prefix_rep" "1")])
18340
18341 (define_insn "*strlenqi_rex_1"
18342   [(set (match_operand:DI 0 "register_operand" "=&c")
18343         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18344                     (match_operand:QI 2 "register_operand" "a")
18345                     (match_operand:DI 3 "immediate_operand" "i")
18346                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18347    (clobber (match_operand:DI 1 "register_operand" "=D"))
18348    (clobber (reg:CC FLAGS_REG))]
18349   "TARGET_64BIT"
18350   "repnz scasb"
18351   [(set_attr "type" "str")
18352    (set_attr "mode" "QI")
18353    (set_attr "prefix_rex" "0")
18354    (set_attr "prefix_rep" "1")])
18355
18356 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18357 ;; handled in combine, but it is not currently up to the task.
18358 ;; When used for their truth value, the cmpstrn* expanders generate
18359 ;; code like this:
18360 ;;
18361 ;;   repz cmpsb
18362 ;;   seta       %al
18363 ;;   setb       %dl
18364 ;;   cmpb       %al, %dl
18365 ;;   jcc        label
18366 ;;
18367 ;; The intermediate three instructions are unnecessary.
18368
18369 ;; This one handles cmpstrn*_nz_1...
18370 (define_peephole2
18371   [(parallel[
18372      (set (reg:CC FLAGS_REG)
18373           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18374                       (mem:BLK (match_operand 5 "register_operand" ""))))
18375      (use (match_operand 6 "register_operand" ""))
18376      (use (match_operand:SI 3 "immediate_operand" ""))
18377      (clobber (match_operand 0 "register_operand" ""))
18378      (clobber (match_operand 1 "register_operand" ""))
18379      (clobber (match_operand 2 "register_operand" ""))])
18380    (set (match_operand:QI 7 "register_operand" "")
18381         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18382    (set (match_operand:QI 8 "register_operand" "")
18383         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18384    (set (reg FLAGS_REG)
18385         (compare (match_dup 7) (match_dup 8)))
18386   ]
18387   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18388   [(parallel[
18389      (set (reg:CC FLAGS_REG)
18390           (compare:CC (mem:BLK (match_dup 4))
18391                       (mem:BLK (match_dup 5))))
18392      (use (match_dup 6))
18393      (use (match_dup 3))
18394      (clobber (match_dup 0))
18395      (clobber (match_dup 1))
18396      (clobber (match_dup 2))])]
18397   "")
18398
18399 ;; ...and this one handles cmpstrn*_1.
18400 (define_peephole2
18401   [(parallel[
18402      (set (reg:CC FLAGS_REG)
18403           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18404                                (const_int 0))
18405             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18406                         (mem:BLK (match_operand 5 "register_operand" "")))
18407             (const_int 0)))
18408      (use (match_operand:SI 3 "immediate_operand" ""))
18409      (use (reg:CC FLAGS_REG))
18410      (clobber (match_operand 0 "register_operand" ""))
18411      (clobber (match_operand 1 "register_operand" ""))
18412      (clobber (match_operand 2 "register_operand" ""))])
18413    (set (match_operand:QI 7 "register_operand" "")
18414         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18415    (set (match_operand:QI 8 "register_operand" "")
18416         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18417    (set (reg FLAGS_REG)
18418         (compare (match_dup 7) (match_dup 8)))
18419   ]
18420   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18421   [(parallel[
18422      (set (reg:CC FLAGS_REG)
18423           (if_then_else:CC (ne (match_dup 6)
18424                                (const_int 0))
18425             (compare:CC (mem:BLK (match_dup 4))
18426                         (mem:BLK (match_dup 5)))
18427             (const_int 0)))
18428      (use (match_dup 3))
18429      (use (reg:CC FLAGS_REG))
18430      (clobber (match_dup 0))
18431      (clobber (match_dup 1))
18432      (clobber (match_dup 2))])]
18433   "")
18434
18435
18436 \f
18437 ;; Conditional move instructions.
18438
18439 (define_expand "mov<mode>cc"
18440   [(set (match_operand:SWIM 0 "register_operand" "")
18441         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18442                            (match_operand:SWIM 2 "general_operand" "")
18443                            (match_operand:SWIM 3 "general_operand" "")))]
18444   ""
18445   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18446
18447 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18448 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18449 ;; So just document what we're doing explicitly.
18450
18451 (define_expand "x86_mov<mode>cc_0_m1"
18452   [(parallel
18453     [(set (match_operand:SWI48 0 "register_operand" "")
18454           (if_then_else:SWI48
18455             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18456              [(match_operand 1 "flags_reg_operand" "")
18457               (const_int 0)])
18458             (const_int -1)
18459             (const_int 0)))
18460      (clobber (reg:CC FLAGS_REG))])]
18461   ""
18462   "")
18463
18464 (define_insn "*x86_mov<mode>cc_0_m1"
18465   [(set (match_operand:SWI48 0 "register_operand" "=r")
18466         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18467                              [(reg FLAGS_REG) (const_int 0)])
18468           (const_int -1)
18469           (const_int 0)))
18470    (clobber (reg:CC FLAGS_REG))]
18471   ""
18472   "sbb{<imodesuffix>}\t%0, %0"
18473   ; Since we don't have the proper number of operands for an alu insn,
18474   ; fill in all the blanks.
18475   [(set_attr "type" "alu")
18476    (set_attr "use_carry" "1")
18477    (set_attr "pent_pair" "pu")
18478    (set_attr "memory" "none")
18479    (set_attr "imm_disp" "false")
18480    (set_attr "mode" "<MODE>")
18481    (set_attr "length_immediate" "0")])
18482
18483 (define_insn "*x86_mov<mode>cc_0_m1_se"
18484   [(set (match_operand:SWI48 0 "register_operand" "=r")
18485         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18486                              [(reg FLAGS_REG) (const_int 0)])
18487                             (const_int 1)
18488                             (const_int 0)))
18489    (clobber (reg:CC FLAGS_REG))]
18490   ""
18491   "sbb{<imodesuffix>}\t%0, %0"
18492   [(set_attr "type" "alu")
18493    (set_attr "use_carry" "1")
18494    (set_attr "pent_pair" "pu")
18495    (set_attr "memory" "none")
18496    (set_attr "imm_disp" "false")
18497    (set_attr "mode" "<MODE>")
18498    (set_attr "length_immediate" "0")])
18499
18500 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18501   [(set (match_operand:SWI48 0 "register_operand" "=r")
18502         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18503                     [(reg FLAGS_REG) (const_int 0)])))]
18504   ""
18505   "sbb{<imodesuffix>}\t%0, %0"
18506   [(set_attr "type" "alu")
18507    (set_attr "use_carry" "1")
18508    (set_attr "pent_pair" "pu")
18509    (set_attr "memory" "none")
18510    (set_attr "imm_disp" "false")
18511    (set_attr "mode" "<MODE>")
18512    (set_attr "length_immediate" "0")])
18513
18514 (define_insn "*mov<mode>cc_noc"
18515   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18516         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18517                                [(reg FLAGS_REG) (const_int 0)])
18518           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18519           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18520   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18521   "@
18522    cmov%O2%C1\t{%2, %0|%0, %2}
18523    cmov%O2%c1\t{%3, %0|%0, %3}"
18524   [(set_attr "type" "icmov")
18525    (set_attr "mode" "<MODE>")])
18526
18527 (define_insn_and_split "*movqicc_noc"
18528   [(set (match_operand:QI 0 "register_operand" "=r,r")
18529         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18530                            [(match_operand 4 "flags_reg_operand" "")
18531                             (const_int 0)])
18532                       (match_operand:QI 2 "register_operand" "r,0")
18533                       (match_operand:QI 3 "register_operand" "0,r")))]
18534   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18535   "#"
18536   "&& reload_completed"
18537   [(set (match_dup 0)
18538         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18539                       (match_dup 2)
18540                       (match_dup 3)))]
18541   "operands[0] = gen_lowpart (SImode, operands[0]);
18542    operands[2] = gen_lowpart (SImode, operands[2]);
18543    operands[3] = gen_lowpart (SImode, operands[3]);"
18544   [(set_attr "type" "icmov")
18545    (set_attr "mode" "SI")])
18546
18547 (define_expand "mov<mode>cc"
18548   [(set (match_operand:X87MODEF 0 "register_operand" "")
18549         (if_then_else:X87MODEF
18550           (match_operand 1 "ix86_fp_comparison_operator" "")
18551           (match_operand:X87MODEF 2 "register_operand" "")
18552           (match_operand:X87MODEF 3 "register_operand" "")))]
18553   "(TARGET_80387 && TARGET_CMOVE)
18554    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18555   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18556
18557 (define_insn "*movsfcc_1_387"
18558   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18559         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18560                                 [(reg FLAGS_REG) (const_int 0)])
18561                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18562                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18563   "TARGET_80387 && TARGET_CMOVE
18564    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18565   "@
18566    fcmov%F1\t{%2, %0|%0, %2}
18567    fcmov%f1\t{%3, %0|%0, %3}
18568    cmov%O2%C1\t{%2, %0|%0, %2}
18569    cmov%O2%c1\t{%3, %0|%0, %3}"
18570   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18571    (set_attr "mode" "SF,SF,SI,SI")])
18572
18573 (define_insn "*movdfcc_1"
18574   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18575         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18576                                 [(reg FLAGS_REG) (const_int 0)])
18577                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18578                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18579   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18580    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18581   "@
18582    fcmov%F1\t{%2, %0|%0, %2}
18583    fcmov%f1\t{%3, %0|%0, %3}
18584    #
18585    #"
18586   [(set_attr "type" "fcmov,fcmov,multi,multi")
18587    (set_attr "mode" "DF")])
18588
18589 (define_insn "*movdfcc_1_rex64"
18590   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18591         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18592                                 [(reg FLAGS_REG) (const_int 0)])
18593                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18594                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18595   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18596    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18597   "@
18598    fcmov%F1\t{%2, %0|%0, %2}
18599    fcmov%f1\t{%3, %0|%0, %3}
18600    cmov%O2%C1\t{%2, %0|%0, %2}
18601    cmov%O2%c1\t{%3, %0|%0, %3}"
18602   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18603    (set_attr "mode" "DF")])
18604
18605 (define_split
18606   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18607         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18608                                 [(match_operand 4 "flags_reg_operand" "")
18609                                  (const_int 0)])
18610                       (match_operand:DF 2 "nonimmediate_operand" "")
18611                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18612   "!TARGET_64BIT && reload_completed"
18613   [(set (match_dup 2)
18614         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18615                       (match_dup 5)
18616                       (match_dup 6)))
18617    (set (match_dup 3)
18618         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18619                       (match_dup 7)
18620                       (match_dup 8)))]
18621   "split_di (&operands[2], 2, &operands[5], &operands[7]);
18622    split_di (&operands[0], 1, &operands[2], &operands[3]);")
18623
18624 (define_insn "*movxfcc_1"
18625   [(set (match_operand:XF 0 "register_operand" "=f,f")
18626         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18627                                 [(reg FLAGS_REG) (const_int 0)])
18628                       (match_operand:XF 2 "register_operand" "f,0")
18629                       (match_operand:XF 3 "register_operand" "0,f")))]
18630   "TARGET_80387 && TARGET_CMOVE"
18631   "@
18632    fcmov%F1\t{%2, %0|%0, %2}
18633    fcmov%f1\t{%3, %0|%0, %3}"
18634   [(set_attr "type" "fcmov")
18635    (set_attr "mode" "XF")])
18636
18637 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18638 ;; the scalar versions to have only XMM registers as operands.
18639
18640 ;; XOP conditional move
18641 (define_insn "*xop_pcmov_<mode>"
18642   [(set (match_operand:MODEF 0 "register_operand" "=x")
18643         (if_then_else:MODEF
18644           (match_operand:MODEF 1 "register_operand" "x")
18645           (match_operand:MODEF 2 "register_operand" "x")
18646           (match_operand:MODEF 3 "register_operand" "x")))]
18647   "TARGET_XOP"
18648   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18649   [(set_attr "type" "sse4arg")])
18650
18651 ;; These versions of the min/max patterns are intentionally ignorant of
18652 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18653 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18654 ;; are undefined in this condition, we're certain this is correct.
18655
18656 (define_insn "*avx_<code><mode>3"
18657   [(set (match_operand:MODEF 0 "register_operand" "=x")
18658         (smaxmin:MODEF
18659           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18660           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18661   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18662   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18663   [(set_attr "type" "sseadd")
18664    (set_attr "prefix" "vex")
18665    (set_attr "mode" "<MODE>")])
18666
18667 (define_insn "<code><mode>3"
18668   [(set (match_operand:MODEF 0 "register_operand" "=x")
18669         (smaxmin:MODEF
18670           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18671           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18672   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18673   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18674   [(set_attr "type" "sseadd")
18675    (set_attr "mode" "<MODE>")])
18676
18677 ;; These versions of the min/max patterns implement exactly the operations
18678 ;;   min = (op1 < op2 ? op1 : op2)
18679 ;;   max = (!(op1 < op2) ? op1 : op2)
18680 ;; Their operands are not commutative, and thus they may be used in the
18681 ;; presence of -0.0 and NaN.
18682
18683 (define_insn "*avx_ieee_smin<mode>3"
18684   [(set (match_operand:MODEF 0 "register_operand" "=x")
18685         (unspec:MODEF
18686           [(match_operand:MODEF 1 "register_operand" "x")
18687            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18688          UNSPEC_IEEE_MIN))]
18689   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18690   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18691   [(set_attr "type" "sseadd")
18692    (set_attr "prefix" "vex")
18693    (set_attr "mode" "<MODE>")])
18694
18695 (define_insn "*ieee_smin<mode>3"
18696   [(set (match_operand:MODEF 0 "register_operand" "=x")
18697         (unspec:MODEF
18698           [(match_operand:MODEF 1 "register_operand" "0")
18699            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18700          UNSPEC_IEEE_MIN))]
18701   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18702   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18703   [(set_attr "type" "sseadd")
18704    (set_attr "mode" "<MODE>")])
18705
18706 (define_insn "*avx_ieee_smax<mode>3"
18707   [(set (match_operand:MODEF 0 "register_operand" "=x")
18708         (unspec:MODEF
18709           [(match_operand:MODEF 1 "register_operand" "0")
18710            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18711          UNSPEC_IEEE_MAX))]
18712   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18713   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18714   [(set_attr "type" "sseadd")
18715    (set_attr "prefix" "vex")
18716    (set_attr "mode" "<MODE>")])
18717
18718 (define_insn "*ieee_smax<mode>3"
18719   [(set (match_operand:MODEF 0 "register_operand" "=x")
18720         (unspec:MODEF
18721           [(match_operand:MODEF 1 "register_operand" "0")
18722            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18723          UNSPEC_IEEE_MAX))]
18724   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18725   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18726   [(set_attr "type" "sseadd")
18727    (set_attr "mode" "<MODE>")])
18728
18729 ;; Make two stack loads independent:
18730 ;;   fld aa              fld aa
18731 ;;   fld %st(0)     ->   fld bb
18732 ;;   fmul bb             fmul %st(1), %st
18733 ;;
18734 ;; Actually we only match the last two instructions for simplicity.
18735 (define_peephole2
18736   [(set (match_operand 0 "fp_register_operand" "")
18737         (match_operand 1 "fp_register_operand" ""))
18738    (set (match_dup 0)
18739         (match_operator 2 "binary_fp_operator"
18740            [(match_dup 0)
18741             (match_operand 3 "memory_operand" "")]))]
18742   "REGNO (operands[0]) != REGNO (operands[1])"
18743   [(set (match_dup 0) (match_dup 3))
18744    (set (match_dup 0) (match_dup 4))]
18745
18746   ;; The % modifier is not operational anymore in peephole2's, so we have to
18747   ;; swap the operands manually in the case of addition and multiplication.
18748   "if (COMMUTATIVE_ARITH_P (operands[2]))
18749      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18750                                  operands[0], operands[1]);
18751    else
18752      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18753                                  operands[1], operands[0]);")
18754
18755 ;; Conditional addition patterns
18756 (define_expand "add<mode>cc"
18757   [(match_operand:SWI 0 "register_operand" "")
18758    (match_operand 1 "comparison_operator" "")
18759    (match_operand:SWI 2 "register_operand" "")
18760    (match_operand:SWI 3 "const_int_operand" "")]
18761   ""
18762   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18763
18764 \f
18765 ;; Misc patterns (?)
18766
18767 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18768 ;; Otherwise there will be nothing to keep
18769 ;;
18770 ;; [(set (reg ebp) (reg esp))]
18771 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18772 ;;  (clobber (eflags)]
18773 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18774 ;;
18775 ;; in proper program order.
18776 (define_insn "pro_epilogue_adjust_stack_1"
18777   [(set (match_operand:SI 0 "register_operand" "=r,r")
18778         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18779                  (match_operand:SI 2 "immediate_operand" "i,i")))
18780    (clobber (reg:CC FLAGS_REG))
18781    (clobber (mem:BLK (scratch)))]
18782   "!TARGET_64BIT"
18783 {
18784   switch (get_attr_type (insn))
18785     {
18786     case TYPE_IMOV:
18787       return "mov{l}\t{%1, %0|%0, %1}";
18788
18789     case TYPE_ALU:
18790       if (CONST_INT_P (operands[2])
18791           && (INTVAL (operands[2]) == 128
18792               || (INTVAL (operands[2]) < 0
18793                   && INTVAL (operands[2]) != -128)))
18794         {
18795           operands[2] = GEN_INT (-INTVAL (operands[2]));
18796           return "sub{l}\t{%2, %0|%0, %2}";
18797         }
18798       return "add{l}\t{%2, %0|%0, %2}";
18799
18800     case TYPE_LEA:
18801       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18802       return "lea{l}\t{%a2, %0|%0, %a2}";
18803
18804     default:
18805       gcc_unreachable ();
18806     }
18807 }
18808   [(set (attr "type")
18809         (cond [(and (eq_attr "alternative" "0") 
18810                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18811                  (const_string "alu")
18812                (match_operand:SI 2 "const0_operand" "")
18813                  (const_string "imov")
18814               ]
18815               (const_string "lea")))
18816    (set (attr "length_immediate")
18817         (cond [(eq_attr "type" "imov")
18818                  (const_string "0")
18819                (and (eq_attr "type" "alu")
18820                     (match_operand 2 "const128_operand" ""))
18821                  (const_string "1")
18822               ]
18823               (const_string "*")))
18824    (set_attr "mode" "SI")])
18825
18826 (define_insn "pro_epilogue_adjust_stack_rex64"
18827   [(set (match_operand:DI 0 "register_operand" "=r,r")
18828         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18829                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18830    (clobber (reg:CC FLAGS_REG))
18831    (clobber (mem:BLK (scratch)))]
18832   "TARGET_64BIT"
18833 {
18834   switch (get_attr_type (insn))
18835     {
18836     case TYPE_IMOV:
18837       return "mov{q}\t{%1, %0|%0, %1}";
18838
18839     case TYPE_ALU:
18840       if (CONST_INT_P (operands[2])
18841           /* Avoid overflows.  */
18842           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18843           && (INTVAL (operands[2]) == 128
18844               || (INTVAL (operands[2]) < 0
18845                   && INTVAL (operands[2]) != -128)))
18846         {
18847           operands[2] = GEN_INT (-INTVAL (operands[2]));
18848           return "sub{q}\t{%2, %0|%0, %2}";
18849         }
18850       return "add{q}\t{%2, %0|%0, %2}";
18851
18852     case TYPE_LEA:
18853       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18854       return "lea{q}\t{%a2, %0|%0, %a2}";
18855
18856     default:
18857       gcc_unreachable ();
18858     }
18859 }
18860   [(set (attr "type")
18861         (cond [(and (eq_attr "alternative" "0")
18862                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18863                  (const_string "alu")
18864                (match_operand:DI 2 "const0_operand" "")
18865                  (const_string "imov")
18866               ]
18867               (const_string "lea")))
18868    (set (attr "length_immediate")
18869         (cond [(eq_attr "type" "imov")
18870                  (const_string "0")
18871                (and (eq_attr "type" "alu")
18872                     (match_operand 2 "const128_operand" ""))
18873                  (const_string "1")
18874               ]
18875               (const_string "*")))
18876    (set_attr "mode" "DI")])
18877
18878 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18879   [(set (match_operand:DI 0 "register_operand" "=r,r")
18880         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18881                  (match_operand:DI 3 "immediate_operand" "i,i")))
18882    (use (match_operand:DI 2 "register_operand" "r,r"))
18883    (clobber (reg:CC FLAGS_REG))
18884    (clobber (mem:BLK (scratch)))]
18885   "TARGET_64BIT"
18886 {
18887   switch (get_attr_type (insn))
18888     {
18889     case TYPE_ALU:
18890       return "add{q}\t{%2, %0|%0, %2}";
18891
18892     case TYPE_LEA:
18893       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18894       return "lea{q}\t{%a2, %0|%0, %a2}";
18895
18896     default:
18897       gcc_unreachable ();
18898     }
18899 }
18900   [(set_attr "type" "alu,lea")
18901    (set_attr "mode" "DI")])
18902
18903 (define_insn "allocate_stack_worker_32"
18904   [(set (match_operand:SI 0 "register_operand" "=a")
18905         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18906                             UNSPECV_STACK_PROBE))
18907    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18908    (clobber (reg:CC FLAGS_REG))]
18909   "!TARGET_64BIT && TARGET_STACK_PROBE"
18910   "call\t___chkstk"
18911   [(set_attr "type" "multi")
18912    (set_attr "length" "5")])
18913
18914 (define_insn "allocate_stack_worker_64"
18915   [(set (match_operand:DI 0 "register_operand" "=a")
18916         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18917                             UNSPECV_STACK_PROBE))
18918    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18919    (clobber (reg:DI R10_REG))
18920    (clobber (reg:DI R11_REG))
18921    (clobber (reg:CC FLAGS_REG))]
18922   "TARGET_64BIT && TARGET_STACK_PROBE"
18923   "call\t___chkstk"
18924   [(set_attr "type" "multi")
18925    (set_attr "length" "5")])
18926
18927 (define_expand "allocate_stack"
18928   [(match_operand 0 "register_operand" "")
18929    (match_operand 1 "general_operand" "")]
18930   "TARGET_STACK_PROBE"
18931 {
18932   rtx x;
18933
18934 #ifndef CHECK_STACK_LIMIT
18935 #define CHECK_STACK_LIMIT 0
18936 #endif
18937
18938   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18939       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18940     {
18941       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18942                                stack_pointer_rtx, 0, OPTAB_DIRECT);
18943       if (x != stack_pointer_rtx)
18944         emit_move_insn (stack_pointer_rtx, x);
18945     }
18946   else
18947     {
18948       x = copy_to_mode_reg (Pmode, operands[1]);
18949       if (TARGET_64BIT)
18950         x = gen_allocate_stack_worker_64 (x, x);
18951       else
18952         x = gen_allocate_stack_worker_32 (x, x);
18953       emit_insn (x);
18954     }
18955
18956   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18957   DONE;
18958 })
18959
18960 ;; Use IOR for stack probes, this is shorter.
18961 (define_expand "probe_stack"
18962   [(match_operand 0 "memory_operand" "")]
18963   ""
18964 {
18965   if (GET_MODE (operands[0]) == DImode)
18966     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18967   else
18968     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18969   DONE;
18970 })
18971
18972 (define_expand "builtin_setjmp_receiver"
18973   [(label_ref (match_operand 0 "" ""))]
18974   "!TARGET_64BIT && flag_pic"
18975 {
18976 #if TARGET_MACHO
18977   if (TARGET_MACHO)
18978     {
18979       rtx xops[3];
18980       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18981       rtx label_rtx = gen_label_rtx ();
18982       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18983       xops[0] = xops[1] = picreg;
18984       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18985       ix86_expand_binary_operator (MINUS, SImode, xops);
18986     }
18987   else
18988 #endif
18989     emit_insn (gen_set_got (pic_offset_table_rtx));
18990   DONE;
18991 })
18992 \f
18993 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18994
18995 (define_split
18996   [(set (match_operand 0 "register_operand" "")
18997         (match_operator 3 "promotable_binary_operator"
18998            [(match_operand 1 "register_operand" "")
18999             (match_operand 2 "aligned_operand" "")]))
19000    (clobber (reg:CC FLAGS_REG))]
19001   "! TARGET_PARTIAL_REG_STALL && reload_completed
19002    && ((GET_MODE (operands[0]) == HImode
19003         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19004             /* ??? next two lines just !satisfies_constraint_K (...) */
19005             || !CONST_INT_P (operands[2])
19006             || satisfies_constraint_K (operands[2])))
19007        || (GET_MODE (operands[0]) == QImode
19008            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19009   [(parallel [(set (match_dup 0)
19010                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19011               (clobber (reg:CC FLAGS_REG))])]
19012   "operands[0] = gen_lowpart (SImode, operands[0]);
19013    operands[1] = gen_lowpart (SImode, operands[1]);
19014    if (GET_CODE (operands[3]) != ASHIFT)
19015      operands[2] = gen_lowpart (SImode, operands[2]);
19016    PUT_MODE (operands[3], SImode);")
19017
19018 ; Promote the QImode tests, as i386 has encoding of the AND
19019 ; instruction with 32-bit sign-extended immediate and thus the
19020 ; instruction size is unchanged, except in the %eax case for
19021 ; which it is increased by one byte, hence the ! optimize_size.
19022 (define_split
19023   [(set (match_operand 0 "flags_reg_operand" "")
19024         (match_operator 2 "compare_operator"
19025           [(and (match_operand 3 "aligned_operand" "")
19026                 (match_operand 4 "const_int_operand" ""))
19027            (const_int 0)]))
19028    (set (match_operand 1 "register_operand" "")
19029         (and (match_dup 3) (match_dup 4)))]
19030   "! TARGET_PARTIAL_REG_STALL && reload_completed
19031    && optimize_insn_for_speed_p ()
19032    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19033        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19034    /* Ensure that the operand will remain sign-extended immediate.  */
19035    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19036   [(parallel [(set (match_dup 0)
19037                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19038                                     (const_int 0)]))
19039               (set (match_dup 1)
19040                    (and:SI (match_dup 3) (match_dup 4)))])]
19041 {
19042   operands[4]
19043     = gen_int_mode (INTVAL (operands[4])
19044                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19045   operands[1] = gen_lowpart (SImode, operands[1]);
19046   operands[3] = gen_lowpart (SImode, operands[3]);
19047 })
19048
19049 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19050 ; the TEST instruction with 32-bit sign-extended immediate and thus
19051 ; the instruction size would at least double, which is not what we
19052 ; want even with ! optimize_size.
19053 (define_split
19054   [(set (match_operand 0 "flags_reg_operand" "")
19055         (match_operator 1 "compare_operator"
19056           [(and (match_operand:HI 2 "aligned_operand" "")
19057                 (match_operand:HI 3 "const_int_operand" ""))
19058            (const_int 0)]))]
19059   "! TARGET_PARTIAL_REG_STALL && reload_completed
19060    && ! TARGET_FAST_PREFIX
19061    && optimize_insn_for_speed_p ()
19062    /* Ensure that the operand will remain sign-extended immediate.  */
19063    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19064   [(set (match_dup 0)
19065         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19066                          (const_int 0)]))]
19067 {
19068   operands[3]
19069     = gen_int_mode (INTVAL (operands[3])
19070                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19071   operands[2] = gen_lowpart (SImode, operands[2]);
19072 })
19073
19074 (define_split
19075   [(set (match_operand 0 "register_operand" "")
19076         (neg (match_operand 1 "register_operand" "")))
19077    (clobber (reg:CC FLAGS_REG))]
19078   "! TARGET_PARTIAL_REG_STALL && reload_completed
19079    && (GET_MODE (operands[0]) == HImode
19080        || (GET_MODE (operands[0]) == QImode
19081            && (TARGET_PROMOTE_QImode
19082                || optimize_insn_for_size_p ())))"
19083   [(parallel [(set (match_dup 0)
19084                    (neg:SI (match_dup 1)))
19085               (clobber (reg:CC FLAGS_REG))])]
19086   "operands[0] = gen_lowpart (SImode, operands[0]);
19087    operands[1] = gen_lowpart (SImode, operands[1]);")
19088
19089 (define_split
19090   [(set (match_operand 0 "register_operand" "")
19091         (not (match_operand 1 "register_operand" "")))]
19092   "! TARGET_PARTIAL_REG_STALL && reload_completed
19093    && (GET_MODE (operands[0]) == HImode
19094        || (GET_MODE (operands[0]) == QImode
19095            && (TARGET_PROMOTE_QImode
19096                || optimize_insn_for_size_p ())))"
19097   [(set (match_dup 0)
19098         (not:SI (match_dup 1)))]
19099   "operands[0] = gen_lowpart (SImode, operands[0]);
19100    operands[1] = gen_lowpart (SImode, operands[1]);")
19101
19102 (define_split
19103   [(set (match_operand 0 "register_operand" "")
19104         (if_then_else (match_operator 1 "comparison_operator"
19105                                 [(reg FLAGS_REG) (const_int 0)])
19106                       (match_operand 2 "register_operand" "")
19107                       (match_operand 3 "register_operand" "")))]
19108   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19109    && (GET_MODE (operands[0]) == HImode
19110        || (GET_MODE (operands[0]) == QImode
19111            && (TARGET_PROMOTE_QImode
19112                || optimize_insn_for_size_p ())))"
19113   [(set (match_dup 0)
19114         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19115   "operands[0] = gen_lowpart (SImode, operands[0]);
19116    operands[2] = gen_lowpart (SImode, operands[2]);
19117    operands[3] = gen_lowpart (SImode, operands[3]);")
19118
19119 \f
19120 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19121 ;; transform a complex memory operation into two memory to register operations.
19122
19123 ;; Don't push memory operands
19124 (define_peephole2
19125   [(set (match_operand:SI 0 "push_operand" "")
19126         (match_operand:SI 1 "memory_operand" ""))
19127    (match_scratch:SI 2 "r")]
19128   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19129    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19130   [(set (match_dup 2) (match_dup 1))
19131    (set (match_dup 0) (match_dup 2))]
19132   "")
19133
19134 (define_peephole2
19135   [(set (match_operand:DI 0 "push_operand" "")
19136         (match_operand:DI 1 "memory_operand" ""))
19137    (match_scratch:DI 2 "r")]
19138   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19139    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19140   [(set (match_dup 2) (match_dup 1))
19141    (set (match_dup 0) (match_dup 2))]
19142   "")
19143
19144 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19145 ;; SImode pushes.
19146 (define_peephole2
19147   [(set (match_operand:SF 0 "push_operand" "")
19148         (match_operand:SF 1 "memory_operand" ""))
19149    (match_scratch:SF 2 "r")]
19150   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19151    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19152   [(set (match_dup 2) (match_dup 1))
19153    (set (match_dup 0) (match_dup 2))]
19154   "")
19155
19156 (define_peephole2
19157   [(set (match_operand:HI 0 "push_operand" "")
19158         (match_operand:HI 1 "memory_operand" ""))
19159    (match_scratch:HI 2 "r")]
19160   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19161    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19162   [(set (match_dup 2) (match_dup 1))
19163    (set (match_dup 0) (match_dup 2))]
19164   "")
19165
19166 (define_peephole2
19167   [(set (match_operand:QI 0 "push_operand" "")
19168         (match_operand:QI 1 "memory_operand" ""))
19169    (match_scratch:QI 2 "q")]
19170   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19171    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19172   [(set (match_dup 2) (match_dup 1))
19173    (set (match_dup 0) (match_dup 2))]
19174   "")
19175
19176 ;; Don't move an immediate directly to memory when the instruction
19177 ;; gets too big.
19178 (define_peephole2
19179   [(match_scratch:SI 1 "r")
19180    (set (match_operand:SI 0 "memory_operand" "")
19181         (const_int 0))]
19182   "optimize_insn_for_speed_p ()
19183    && ! TARGET_USE_MOV0
19184    && TARGET_SPLIT_LONG_MOVES
19185    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19186    && peep2_regno_dead_p (0, FLAGS_REG)"
19187   [(parallel [(set (match_dup 1) (const_int 0))
19188               (clobber (reg:CC FLAGS_REG))])
19189    (set (match_dup 0) (match_dup 1))]
19190   "")
19191
19192 (define_peephole2
19193   [(match_scratch:HI 1 "r")
19194    (set (match_operand:HI 0 "memory_operand" "")
19195         (const_int 0))]
19196   "optimize_insn_for_speed_p ()
19197    && ! TARGET_USE_MOV0
19198    && TARGET_SPLIT_LONG_MOVES
19199    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19200    && peep2_regno_dead_p (0, FLAGS_REG)"
19201   [(parallel [(set (match_dup 2) (const_int 0))
19202               (clobber (reg:CC FLAGS_REG))])
19203    (set (match_dup 0) (match_dup 1))]
19204   "operands[2] = gen_lowpart (SImode, operands[1]);")
19205
19206 (define_peephole2
19207   [(match_scratch:QI 1 "q")
19208    (set (match_operand:QI 0 "memory_operand" "")
19209         (const_int 0))]
19210   "optimize_insn_for_speed_p ()
19211    && ! TARGET_USE_MOV0
19212    && TARGET_SPLIT_LONG_MOVES
19213    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19214    && peep2_regno_dead_p (0, FLAGS_REG)"
19215   [(parallel [(set (match_dup 2) (const_int 0))
19216               (clobber (reg:CC FLAGS_REG))])
19217    (set (match_dup 0) (match_dup 1))]
19218   "operands[2] = gen_lowpart (SImode, operands[1]);")
19219
19220 (define_peephole2
19221   [(match_scratch:SI 2 "r")
19222    (set (match_operand:SI 0 "memory_operand" "")
19223         (match_operand:SI 1 "immediate_operand" ""))]
19224   "optimize_insn_for_speed_p ()
19225    && TARGET_SPLIT_LONG_MOVES
19226    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19227   [(set (match_dup 2) (match_dup 1))
19228    (set (match_dup 0) (match_dup 2))]
19229   "")
19230
19231 (define_peephole2
19232   [(match_scratch:HI 2 "r")
19233    (set (match_operand:HI 0 "memory_operand" "")
19234         (match_operand:HI 1 "immediate_operand" ""))]
19235   "optimize_insn_for_speed_p ()
19236    && TARGET_SPLIT_LONG_MOVES
19237    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19238   [(set (match_dup 2) (match_dup 1))
19239    (set (match_dup 0) (match_dup 2))]
19240   "")
19241
19242 (define_peephole2
19243   [(match_scratch:QI 2 "q")
19244    (set (match_operand:QI 0 "memory_operand" "")
19245         (match_operand:QI 1 "immediate_operand" ""))]
19246   "optimize_insn_for_speed_p ()
19247    && TARGET_SPLIT_LONG_MOVES
19248    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19249   [(set (match_dup 2) (match_dup 1))
19250    (set (match_dup 0) (match_dup 2))]
19251   "")
19252
19253 ;; Don't compare memory with zero, load and use a test instead.
19254 (define_peephole2
19255   [(set (match_operand 0 "flags_reg_operand" "")
19256         (match_operator 1 "compare_operator"
19257           [(match_operand:SI 2 "memory_operand" "")
19258            (const_int 0)]))
19259    (match_scratch:SI 3 "r")]
19260   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19261   [(set (match_dup 3) (match_dup 2))
19262    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19263   "")
19264
19265 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19266 ;; Don't split NOTs with a displacement operand, because resulting XOR
19267 ;; will not be pairable anyway.
19268 ;;
19269 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19270 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19271 ;; so this split helps here as well.
19272 ;;
19273 ;; Note: Can't do this as a regular split because we can't get proper
19274 ;; lifetime information then.
19275
19276 (define_peephole2
19277   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19278         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19279   "optimize_insn_for_speed_p ()
19280    && ((TARGET_NOT_UNPAIRABLE
19281         && (!MEM_P (operands[0])
19282             || !memory_displacement_operand (operands[0], SImode)))
19283        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19284    && peep2_regno_dead_p (0, FLAGS_REG)"
19285   [(parallel [(set (match_dup 0)
19286                    (xor:SI (match_dup 1) (const_int -1)))
19287               (clobber (reg:CC FLAGS_REG))])]
19288   "")
19289
19290 (define_peephole2
19291   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19292         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19293   "optimize_insn_for_speed_p ()
19294    && ((TARGET_NOT_UNPAIRABLE
19295         && (!MEM_P (operands[0])
19296             || !memory_displacement_operand (operands[0], HImode)))
19297        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19298    && peep2_regno_dead_p (0, FLAGS_REG)"
19299   [(parallel [(set (match_dup 0)
19300                    (xor:HI (match_dup 1) (const_int -1)))
19301               (clobber (reg:CC FLAGS_REG))])]
19302   "")
19303
19304 (define_peephole2
19305   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19306         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19307   "optimize_insn_for_speed_p ()
19308    && ((TARGET_NOT_UNPAIRABLE
19309         && (!MEM_P (operands[0])
19310             || !memory_displacement_operand (operands[0], QImode)))
19311        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19312    && peep2_regno_dead_p (0, FLAGS_REG)"
19313   [(parallel [(set (match_dup 0)
19314                    (xor:QI (match_dup 1) (const_int -1)))
19315               (clobber (reg:CC FLAGS_REG))])]
19316   "")
19317
19318 ;; Non pairable "test imm, reg" instructions can be translated to
19319 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19320 ;; byte opcode instead of two, have a short form for byte operands),
19321 ;; so do it for other CPUs as well.  Given that the value was dead,
19322 ;; this should not create any new dependencies.  Pass on the sub-word
19323 ;; versions if we're concerned about partial register stalls.
19324
19325 (define_peephole2
19326   [(set (match_operand 0 "flags_reg_operand" "")
19327         (match_operator 1 "compare_operator"
19328           [(and:SI (match_operand:SI 2 "register_operand" "")
19329                    (match_operand:SI 3 "immediate_operand" ""))
19330            (const_int 0)]))]
19331   "ix86_match_ccmode (insn, CCNOmode)
19332    && (true_regnum (operands[2]) != AX_REG
19333        || satisfies_constraint_K (operands[3]))
19334    && peep2_reg_dead_p (1, operands[2])"
19335   [(parallel
19336      [(set (match_dup 0)
19337            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19338                             (const_int 0)]))
19339       (set (match_dup 2)
19340            (and:SI (match_dup 2) (match_dup 3)))])]
19341   "")
19342
19343 ;; We don't need to handle HImode case, because it will be promoted to SImode
19344 ;; on ! TARGET_PARTIAL_REG_STALL
19345
19346 (define_peephole2
19347   [(set (match_operand 0 "flags_reg_operand" "")
19348         (match_operator 1 "compare_operator"
19349           [(and:QI (match_operand:QI 2 "register_operand" "")
19350                    (match_operand:QI 3 "immediate_operand" ""))
19351            (const_int 0)]))]
19352   "! TARGET_PARTIAL_REG_STALL
19353    && ix86_match_ccmode (insn, CCNOmode)
19354    && true_regnum (operands[2]) != AX_REG
19355    && peep2_reg_dead_p (1, operands[2])"
19356   [(parallel
19357      [(set (match_dup 0)
19358            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19359                             (const_int 0)]))
19360       (set (match_dup 2)
19361            (and:QI (match_dup 2) (match_dup 3)))])]
19362   "")
19363
19364 (define_peephole2
19365   [(set (match_operand 0 "flags_reg_operand" "")
19366         (match_operator 1 "compare_operator"
19367           [(and:SI
19368              (zero_extract:SI
19369                (match_operand 2 "ext_register_operand" "")
19370                (const_int 8)
19371                (const_int 8))
19372              (match_operand 3 "const_int_operand" ""))
19373            (const_int 0)]))]
19374   "! TARGET_PARTIAL_REG_STALL
19375    && ix86_match_ccmode (insn, CCNOmode)
19376    && true_regnum (operands[2]) != AX_REG
19377    && peep2_reg_dead_p (1, operands[2])"
19378   [(parallel [(set (match_dup 0)
19379                    (match_op_dup 1
19380                      [(and:SI
19381                         (zero_extract:SI
19382                           (match_dup 2)
19383                           (const_int 8)
19384                           (const_int 8))
19385                         (match_dup 3))
19386                       (const_int 0)]))
19387               (set (zero_extract:SI (match_dup 2)
19388                                     (const_int 8)
19389                                     (const_int 8))
19390                    (and:SI
19391                      (zero_extract:SI
19392                        (match_dup 2)
19393                        (const_int 8)
19394                        (const_int 8))
19395                      (match_dup 3)))])]
19396   "")
19397
19398 ;; Don't do logical operations with memory inputs.
19399 (define_peephole2
19400   [(match_scratch:SI 2 "r")
19401    (parallel [(set (match_operand:SI 0 "register_operand" "")
19402                    (match_operator:SI 3 "arith_or_logical_operator"
19403                      [(match_dup 0)
19404                       (match_operand:SI 1 "memory_operand" "")]))
19405               (clobber (reg:CC FLAGS_REG))])]
19406   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19407   [(set (match_dup 2) (match_dup 1))
19408    (parallel [(set (match_dup 0)
19409                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19410               (clobber (reg:CC FLAGS_REG))])]
19411   "")
19412
19413 (define_peephole2
19414   [(match_scratch:SI 2 "r")
19415    (parallel [(set (match_operand:SI 0 "register_operand" "")
19416                    (match_operator:SI 3 "arith_or_logical_operator"
19417                      [(match_operand:SI 1 "memory_operand" "")
19418                       (match_dup 0)]))
19419               (clobber (reg:CC FLAGS_REG))])]
19420   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19421   [(set (match_dup 2) (match_dup 1))
19422    (parallel [(set (match_dup 0)
19423                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19424               (clobber (reg:CC FLAGS_REG))])]
19425   "")
19426
19427 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
19428 ;; refers to the destination of the load!
19429
19430 (define_peephole2
19431   [(set (match_operand:SI 0 "register_operand" "")
19432         (match_operand:SI 1 "register_operand" ""))
19433    (parallel [(set (match_dup 0)
19434                    (match_operator:SI 3 "commutative_operator"
19435                      [(match_dup 0)
19436                       (match_operand:SI 2 "memory_operand" "")]))
19437               (clobber (reg:CC FLAGS_REG))])]
19438   "REGNO (operands[0]) != REGNO (operands[1])
19439    && GENERAL_REGNO_P (REGNO (operands[0]))
19440    && GENERAL_REGNO_P (REGNO (operands[1]))"
19441   [(set (match_dup 0) (match_dup 4))
19442    (parallel [(set (match_dup 0)
19443                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19444               (clobber (reg:CC FLAGS_REG))])]
19445   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19446
19447 (define_peephole2
19448   [(set (match_operand 0 "register_operand" "")
19449         (match_operand 1 "register_operand" ""))
19450    (set (match_dup 0)
19451                    (match_operator 3 "commutative_operator"
19452                      [(match_dup 0)
19453                       (match_operand 2 "memory_operand" "")]))]
19454   "REGNO (operands[0]) != REGNO (operands[1])
19455    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
19456        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19457   [(set (match_dup 0) (match_dup 2))
19458    (set (match_dup 0)
19459         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19460   "")
19461
19462 ; Don't do logical operations with memory outputs
19463 ;
19464 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19465 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19466 ; the same decoder scheduling characteristics as the original.
19467
19468 (define_peephole2
19469   [(match_scratch:SI 2 "r")
19470    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19471                    (match_operator:SI 3 "arith_or_logical_operator"
19472                      [(match_dup 0)
19473                       (match_operand:SI 1 "nonmemory_operand" "")]))
19474               (clobber (reg:CC FLAGS_REG))])]
19475   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19476    /* Do not split stack checking probes.  */
19477    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19478   [(set (match_dup 2) (match_dup 0))
19479    (parallel [(set (match_dup 2)
19480                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19481               (clobber (reg:CC FLAGS_REG))])
19482    (set (match_dup 0) (match_dup 2))]
19483   "")
19484
19485 (define_peephole2
19486   [(match_scratch:SI 2 "r")
19487    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19488                    (match_operator:SI 3 "arith_or_logical_operator"
19489                      [(match_operand:SI 1 "nonmemory_operand" "")
19490                       (match_dup 0)]))
19491               (clobber (reg:CC FLAGS_REG))])]
19492   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19493    /* Do not split stack checking probes.  */
19494    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19495   [(set (match_dup 2) (match_dup 0))
19496    (parallel [(set (match_dup 2)
19497                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19498               (clobber (reg:CC FLAGS_REG))])
19499    (set (match_dup 0) (match_dup 2))]
19500   "")
19501
19502 ;; Attempt to always use XOR for zeroing registers.
19503 (define_peephole2
19504   [(set (match_operand 0 "register_operand" "")
19505         (match_operand 1 "const0_operand" ""))]
19506   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19507    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19508    && GENERAL_REG_P (operands[0])
19509    && peep2_regno_dead_p (0, FLAGS_REG)"
19510   [(parallel [(set (match_dup 0) (const_int 0))
19511               (clobber (reg:CC FLAGS_REG))])]
19512 {
19513   operands[0] = gen_lowpart (word_mode, operands[0]);
19514 })
19515
19516 (define_peephole2
19517   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19518         (const_int 0))]
19519   "(GET_MODE (operands[0]) == QImode
19520     || GET_MODE (operands[0]) == HImode)
19521    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19522    && peep2_regno_dead_p (0, FLAGS_REG)"
19523   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19524               (clobber (reg:CC FLAGS_REG))])])
19525
19526 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19527 (define_peephole2
19528   [(set (match_operand 0 "register_operand" "")
19529         (const_int -1))]
19530   "(GET_MODE (operands[0]) == HImode
19531     || GET_MODE (operands[0]) == SImode
19532     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19533    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19534    && peep2_regno_dead_p (0, FLAGS_REG)"
19535   [(parallel [(set (match_dup 0) (const_int -1))
19536               (clobber (reg:CC FLAGS_REG))])]
19537   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19538                               operands[0]);")
19539
19540 ;; Attempt to convert simple leas to adds. These can be created by
19541 ;; move expanders.
19542 (define_peephole2
19543   [(set (match_operand:SI 0 "register_operand" "")
19544         (plus:SI (match_dup 0)
19545                  (match_operand:SI 1 "nonmemory_operand" "")))]
19546   "peep2_regno_dead_p (0, FLAGS_REG)"
19547   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19548               (clobber (reg:CC FLAGS_REG))])]
19549   "")
19550
19551 (define_peephole2
19552   [(set (match_operand:SI 0 "register_operand" "")
19553         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19554                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19555   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19556   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19557               (clobber (reg:CC FLAGS_REG))])]
19558   "operands[2] = gen_lowpart (SImode, operands[2]);")
19559
19560 (define_peephole2
19561   [(set (match_operand:DI 0 "register_operand" "")
19562         (plus:DI (match_dup 0)
19563                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19564   "peep2_regno_dead_p (0, FLAGS_REG)"
19565   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19566               (clobber (reg:CC FLAGS_REG))])]
19567   "")
19568
19569 (define_peephole2
19570   [(set (match_operand:SI 0 "register_operand" "")
19571         (mult:SI (match_dup 0)
19572                  (match_operand:SI 1 "const_int_operand" "")))]
19573   "exact_log2 (INTVAL (operands[1])) >= 0
19574    && peep2_regno_dead_p (0, FLAGS_REG)"
19575   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19576               (clobber (reg:CC FLAGS_REG))])]
19577   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19578
19579 (define_peephole2
19580   [(set (match_operand:DI 0 "register_operand" "")
19581         (mult:DI (match_dup 0)
19582                  (match_operand:DI 1 "const_int_operand" "")))]
19583   "exact_log2 (INTVAL (operands[1])) >= 0
19584    && peep2_regno_dead_p (0, FLAGS_REG)"
19585   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19586               (clobber (reg:CC FLAGS_REG))])]
19587   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19588
19589 (define_peephole2
19590   [(set (match_operand:SI 0 "register_operand" "")
19591         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19592                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19593   "exact_log2 (INTVAL (operands[2])) >= 0
19594    && REGNO (operands[0]) == REGNO (operands[1])
19595    && peep2_regno_dead_p (0, FLAGS_REG)"
19596   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19597               (clobber (reg:CC FLAGS_REG))])]
19598   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19599
19600 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19601 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19602 ;; many CPUs it is also faster, since special hardware to avoid esp
19603 ;; dependencies is present.
19604
19605 ;; While some of these conversions may be done using splitters, we use peepholes
19606 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19607
19608 ;; Convert prologue esp subtractions to push.
19609 ;; We need register to push.  In order to keep verify_flow_info happy we have
19610 ;; two choices
19611 ;; - use scratch and clobber it in order to avoid dependencies
19612 ;; - use already live register
19613 ;; We can't use the second way right now, since there is no reliable way how to
19614 ;; verify that given register is live.  First choice will also most likely in
19615 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19616 ;; call clobbered registers are dead.  We may want to use base pointer as an
19617 ;; alternative when no register is available later.
19618
19619 (define_peephole2
19620   [(match_scratch:SI 0 "r")
19621    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19622               (clobber (reg:CC FLAGS_REG))
19623               (clobber (mem:BLK (scratch)))])]
19624   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19625   [(clobber (match_dup 0))
19626    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19627               (clobber (mem:BLK (scratch)))])])
19628
19629 (define_peephole2
19630   [(match_scratch:SI 0 "r")
19631    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19632               (clobber (reg:CC FLAGS_REG))
19633               (clobber (mem:BLK (scratch)))])]
19634   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19635   [(clobber (match_dup 0))
19636    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19637    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19638               (clobber (mem:BLK (scratch)))])])
19639
19640 ;; Convert esp subtractions to push.
19641 (define_peephole2
19642   [(match_scratch:SI 0 "r")
19643    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19644               (clobber (reg:CC FLAGS_REG))])]
19645   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19646   [(clobber (match_dup 0))
19647    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19648
19649 (define_peephole2
19650   [(match_scratch:SI 0 "r")
19651    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19652               (clobber (reg:CC FLAGS_REG))])]
19653   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19654   [(clobber (match_dup 0))
19655    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19656    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19657
19658 ;; Convert epilogue deallocator to pop.
19659 (define_peephole2
19660   [(match_scratch:SI 0 "r")
19661    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19662               (clobber (reg:CC FLAGS_REG))
19663               (clobber (mem:BLK (scratch)))])]
19664   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19665   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19666               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19667               (clobber (mem:BLK (scratch)))])]
19668   "")
19669
19670 ;; Two pops case is tricky, since pop causes dependency on destination register.
19671 ;; We use two registers if available.
19672 (define_peephole2
19673   [(match_scratch:SI 0 "r")
19674    (match_scratch:SI 1 "r")
19675    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19676               (clobber (reg:CC FLAGS_REG))
19677               (clobber (mem:BLK (scratch)))])]
19678   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19679   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19680               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19681               (clobber (mem:BLK (scratch)))])
19682    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19683               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19684   "")
19685
19686 (define_peephole2
19687   [(match_scratch:SI 0 "r")
19688    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19689               (clobber (reg:CC FLAGS_REG))
19690               (clobber (mem:BLK (scratch)))])]
19691   "optimize_insn_for_size_p ()"
19692   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19693               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19694               (clobber (mem:BLK (scratch)))])
19695    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19696               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19697   "")
19698
19699 ;; Convert esp additions to pop.
19700 (define_peephole2
19701   [(match_scratch:SI 0 "r")
19702    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19703               (clobber (reg:CC FLAGS_REG))])]
19704   ""
19705   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19706               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19707   "")
19708
19709 ;; Two pops case is tricky, since pop causes dependency on destination register.
19710 ;; We use two registers if available.
19711 (define_peephole2
19712   [(match_scratch:SI 0 "r")
19713    (match_scratch:SI 1 "r")
19714    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19715               (clobber (reg:CC FLAGS_REG))])]
19716   ""
19717   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19718               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19719    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19720               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19721   "")
19722
19723 (define_peephole2
19724   [(match_scratch:SI 0 "r")
19725    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19726               (clobber (reg:CC FLAGS_REG))])]
19727   "optimize_insn_for_size_p ()"
19728   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19729               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19730    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19731               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19732   "")
19733 \f
19734 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19735 ;; required and register dies.  Similarly for 128 to -128.
19736 (define_peephole2
19737   [(set (match_operand 0 "flags_reg_operand" "")
19738         (match_operator 1 "compare_operator"
19739           [(match_operand 2 "register_operand" "")
19740            (match_operand 3 "const_int_operand" "")]))]
19741   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19742      && incdec_operand (operands[3], GET_MODE (operands[3])))
19743     || (!TARGET_FUSE_CMP_AND_BRANCH
19744         && INTVAL (operands[3]) == 128))
19745    && ix86_match_ccmode (insn, CCGCmode)
19746    && peep2_reg_dead_p (1, operands[2])"
19747   [(parallel [(set (match_dup 0)
19748                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19749               (clobber (match_dup 2))])]
19750   "")
19751 \f
19752 (define_peephole2
19753   [(match_scratch:DI 0 "r")
19754    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19755               (clobber (reg:CC FLAGS_REG))
19756               (clobber (mem:BLK (scratch)))])]
19757   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19758   [(clobber (match_dup 0))
19759    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19760               (clobber (mem:BLK (scratch)))])])
19761
19762 (define_peephole2
19763   [(match_scratch:DI 0 "r")
19764    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19765               (clobber (reg:CC FLAGS_REG))
19766               (clobber (mem:BLK (scratch)))])]
19767   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19768   [(clobber (match_dup 0))
19769    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19770    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19771               (clobber (mem:BLK (scratch)))])])
19772
19773 ;; Convert esp subtractions to push.
19774 (define_peephole2
19775   [(match_scratch:DI 0 "r")
19776    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19779   [(clobber (match_dup 0))
19780    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19781
19782 (define_peephole2
19783   [(match_scratch:DI 0 "r")
19784    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19785               (clobber (reg:CC FLAGS_REG))])]
19786   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19787   [(clobber (match_dup 0))
19788    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19789    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19790
19791 ;; Convert epilogue deallocator to pop.
19792 (define_peephole2
19793   [(match_scratch:DI 0 "r")
19794    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19795               (clobber (reg:CC FLAGS_REG))
19796               (clobber (mem:BLK (scratch)))])]
19797   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19798   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19799               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19800               (clobber (mem:BLK (scratch)))])]
19801   "")
19802
19803 ;; Two pops case is tricky, since pop causes dependency on destination register.
19804 ;; We use two registers if available.
19805 (define_peephole2
19806   [(match_scratch:DI 0 "r")
19807    (match_scratch:DI 1 "r")
19808    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19809               (clobber (reg:CC FLAGS_REG))
19810               (clobber (mem:BLK (scratch)))])]
19811   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19812   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19813               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19814               (clobber (mem:BLK (scratch)))])
19815    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19816               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19817   "")
19818
19819 (define_peephole2
19820   [(match_scratch:DI 0 "r")
19821    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19822               (clobber (reg:CC FLAGS_REG))
19823               (clobber (mem:BLK (scratch)))])]
19824   "optimize_insn_for_size_p ()"
19825   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19826               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19827               (clobber (mem:BLK (scratch)))])
19828    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19829               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19830   "")
19831
19832 ;; Convert esp additions to pop.
19833 (define_peephole2
19834   [(match_scratch:DI 0 "r")
19835    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19836               (clobber (reg:CC FLAGS_REG))])]
19837   ""
19838   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19839               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19840   "")
19841
19842 ;; Two pops case is tricky, since pop causes dependency on destination register.
19843 ;; We use two registers if available.
19844 (define_peephole2
19845   [(match_scratch:DI 0 "r")
19846    (match_scratch:DI 1 "r")
19847    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19848               (clobber (reg:CC FLAGS_REG))])]
19849   ""
19850   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19851               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19852    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19853               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19854   "")
19855
19856 (define_peephole2
19857   [(match_scratch:DI 0 "r")
19858    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19859               (clobber (reg:CC FLAGS_REG))])]
19860   "optimize_insn_for_size_p ()"
19861   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19862               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19863    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19864               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19865   "")
19866 \f
19867 ;; Convert imul by three, five and nine into lea
19868 (define_peephole2
19869   [(parallel
19870     [(set (match_operand:SI 0 "register_operand" "")
19871           (mult:SI (match_operand:SI 1 "register_operand" "")
19872                    (match_operand:SI 2 "const_int_operand" "")))
19873      (clobber (reg:CC FLAGS_REG))])]
19874   "INTVAL (operands[2]) == 3
19875    || INTVAL (operands[2]) == 5
19876    || INTVAL (operands[2]) == 9"
19877   [(set (match_dup 0)
19878         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19879                  (match_dup 1)))]
19880   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19881
19882 (define_peephole2
19883   [(parallel
19884     [(set (match_operand:SI 0 "register_operand" "")
19885           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19886                    (match_operand:SI 2 "const_int_operand" "")))
19887      (clobber (reg:CC FLAGS_REG))])]
19888   "optimize_insn_for_speed_p ()
19889    && (INTVAL (operands[2]) == 3
19890        || INTVAL (operands[2]) == 5
19891        || INTVAL (operands[2]) == 9)"
19892   [(set (match_dup 0) (match_dup 1))
19893    (set (match_dup 0)
19894         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19895                  (match_dup 0)))]
19896   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19897
19898 (define_peephole2
19899   [(parallel
19900     [(set (match_operand:DI 0 "register_operand" "")
19901           (mult:DI (match_operand:DI 1 "register_operand" "")
19902                    (match_operand:DI 2 "const_int_operand" "")))
19903      (clobber (reg:CC FLAGS_REG))])]
19904   "TARGET_64BIT
19905    && (INTVAL (operands[2]) == 3
19906        || INTVAL (operands[2]) == 5
19907        || INTVAL (operands[2]) == 9)"
19908   [(set (match_dup 0)
19909         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19910                  (match_dup 1)))]
19911   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19912
19913 (define_peephole2
19914   [(parallel
19915     [(set (match_operand:DI 0 "register_operand" "")
19916           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19917                    (match_operand:DI 2 "const_int_operand" "")))
19918      (clobber (reg:CC FLAGS_REG))])]
19919   "TARGET_64BIT
19920    && optimize_insn_for_speed_p ()
19921    && (INTVAL (operands[2]) == 3
19922        || INTVAL (operands[2]) == 5
19923        || INTVAL (operands[2]) == 9)"
19924   [(set (match_dup 0) (match_dup 1))
19925    (set (match_dup 0)
19926         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19927                  (match_dup 0)))]
19928   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19929
19930 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19931 ;; imul $32bit_imm, reg, reg is direct decoded.
19932 (define_peephole2
19933   [(match_scratch:DI 3 "r")
19934    (parallel [(set (match_operand:DI 0 "register_operand" "")
19935                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19936                             (match_operand:DI 2 "immediate_operand" "")))
19937               (clobber (reg:CC FLAGS_REG))])]
19938   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19939    && !satisfies_constraint_K (operands[2])"
19940   [(set (match_dup 3) (match_dup 1))
19941    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19942               (clobber (reg:CC FLAGS_REG))])]
19943 "")
19944
19945 (define_peephole2
19946   [(match_scratch:SI 3 "r")
19947    (parallel [(set (match_operand:SI 0 "register_operand" "")
19948                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19949                             (match_operand:SI 2 "immediate_operand" "")))
19950               (clobber (reg:CC FLAGS_REG))])]
19951   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19952    && !satisfies_constraint_K (operands[2])"
19953   [(set (match_dup 3) (match_dup 1))
19954    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19955               (clobber (reg:CC FLAGS_REG))])]
19956 "")
19957
19958 (define_peephole2
19959   [(match_scratch:SI 3 "r")
19960    (parallel [(set (match_operand:DI 0 "register_operand" "")
19961                    (zero_extend:DI
19962                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19963                               (match_operand:SI 2 "immediate_operand" ""))))
19964               (clobber (reg:CC FLAGS_REG))])]
19965   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19966    && !satisfies_constraint_K (operands[2])"
19967   [(set (match_dup 3) (match_dup 1))
19968    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19969               (clobber (reg:CC FLAGS_REG))])]
19970 "")
19971
19972 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19973 ;; Convert it into imul reg, reg
19974 ;; It would be better to force assembler to encode instruction using long
19975 ;; immediate, but there is apparently no way to do so.
19976 (define_peephole2
19977   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19978                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19979                             (match_operand:DI 2 "const_int_operand" "")))
19980               (clobber (reg:CC FLAGS_REG))])
19981    (match_scratch:DI 3 "r")]
19982   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19983    && satisfies_constraint_K (operands[2])"
19984   [(set (match_dup 3) (match_dup 2))
19985    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19986               (clobber (reg:CC FLAGS_REG))])]
19987 {
19988   if (!rtx_equal_p (operands[0], operands[1]))
19989     emit_move_insn (operands[0], operands[1]);
19990 })
19991
19992 (define_peephole2
19993   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19994                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19995                             (match_operand:SI 2 "const_int_operand" "")))
19996               (clobber (reg:CC FLAGS_REG))])
19997    (match_scratch:SI 3 "r")]
19998   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19999    && satisfies_constraint_K (operands[2])"
20000   [(set (match_dup 3) (match_dup 2))
20001    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20002               (clobber (reg:CC FLAGS_REG))])]
20003 {
20004   if (!rtx_equal_p (operands[0], operands[1]))
20005     emit_move_insn (operands[0], operands[1]);
20006 })
20007
20008 (define_peephole2
20009   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20010                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20011                             (match_operand:HI 2 "immediate_operand" "")))
20012               (clobber (reg:CC FLAGS_REG))])
20013    (match_scratch:HI 3 "r")]
20014   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20015   [(set (match_dup 3) (match_dup 2))
20016    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20017               (clobber (reg:CC FLAGS_REG))])]
20018 {
20019   if (!rtx_equal_p (operands[0], operands[1]))
20020     emit_move_insn (operands[0], operands[1]);
20021 })
20022
20023 ;; After splitting up read-modify operations, array accesses with memory
20024 ;; operands might end up in form:
20025 ;;  sall    $2, %eax
20026 ;;  movl    4(%esp), %edx
20027 ;;  addl    %edx, %eax
20028 ;; instead of pre-splitting:
20029 ;;  sall    $2, %eax
20030 ;;  addl    4(%esp), %eax
20031 ;; Turn it into:
20032 ;;  movl    4(%esp), %edx
20033 ;;  leal    (%edx,%eax,4), %eax
20034
20035 (define_peephole2
20036   [(parallel [(set (match_operand 0 "register_operand" "")
20037                    (ashift (match_operand 1 "register_operand" "")
20038                            (match_operand 2 "const_int_operand" "")))
20039                (clobber (reg:CC FLAGS_REG))])
20040    (set (match_operand 3 "register_operand")
20041         (match_operand 4 "x86_64_general_operand" ""))
20042    (parallel [(set (match_operand 5 "register_operand" "")
20043                    (plus (match_operand 6 "register_operand" "")
20044                          (match_operand 7 "register_operand" "")))
20045                    (clobber (reg:CC FLAGS_REG))])]
20046   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20047    /* Validate MODE for lea.  */
20048    && ((!TARGET_PARTIAL_REG_STALL
20049         && (GET_MODE (operands[0]) == QImode
20050             || GET_MODE (operands[0]) == HImode))
20051        || GET_MODE (operands[0]) == SImode
20052        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20053    /* We reorder load and the shift.  */
20054    && !rtx_equal_p (operands[1], operands[3])
20055    && !reg_overlap_mentioned_p (operands[0], operands[4])
20056    /* Last PLUS must consist of operand 0 and 3.  */
20057    && !rtx_equal_p (operands[0], operands[3])
20058    && (rtx_equal_p (operands[3], operands[6])
20059        || rtx_equal_p (operands[3], operands[7]))
20060    && (rtx_equal_p (operands[0], operands[6])
20061        || rtx_equal_p (operands[0], operands[7]))
20062    /* The intermediate operand 0 must die or be same as output.  */
20063    && (rtx_equal_p (operands[0], operands[5])
20064        || peep2_reg_dead_p (3, operands[0]))"
20065   [(set (match_dup 3) (match_dup 4))
20066    (set (match_dup 0) (match_dup 1))]
20067 {
20068   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20069   int scale = 1 << INTVAL (operands[2]);
20070   rtx index = gen_lowpart (Pmode, operands[1]);
20071   rtx base = gen_lowpart (Pmode, operands[3]);
20072   rtx dest = gen_lowpart (mode, operands[5]);
20073
20074   operands[1] = gen_rtx_PLUS (Pmode, base,
20075                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20076   if (mode != Pmode)
20077     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20078   operands[0] = dest;
20079 })
20080 \f
20081 ;; Call-value patterns last so that the wildcard operand does not
20082 ;; disrupt insn-recog's switch tables.
20083
20084 (define_insn "*call_value_pop_0"
20085   [(set (match_operand 0 "" "")
20086         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20087               (match_operand:SI 2 "" "")))
20088    (set (reg:SI SP_REG)
20089         (plus:SI (reg:SI SP_REG)
20090                  (match_operand:SI 3 "immediate_operand" "")))]
20091   "!TARGET_64BIT"
20092 {
20093   if (SIBLING_CALL_P (insn))
20094     return "jmp\t%P1";
20095   else
20096     return "call\t%P1";
20097 }
20098   [(set_attr "type" "callv")])
20099
20100 (define_insn "*call_value_pop_1"
20101   [(set (match_operand 0 "" "")
20102         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20103               (match_operand:SI 2 "" "")))
20104    (set (reg:SI SP_REG)
20105         (plus:SI (reg:SI SP_REG)
20106                  (match_operand:SI 3 "immediate_operand" "i")))]
20107   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20108 {
20109   if (constant_call_address_operand (operands[1], Pmode))
20110     return "call\t%P1";
20111   return "call\t%A1";
20112 }
20113   [(set_attr "type" "callv")])
20114
20115 (define_insn "*sibcall_value_pop_1"
20116   [(set (match_operand 0 "" "")
20117         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20118               (match_operand:SI 2 "" "")))
20119    (set (reg:SI SP_REG)
20120         (plus:SI (reg:SI SP_REG)
20121                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20122   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20123   "@
20124    jmp\t%P1
20125    jmp\t%A1"
20126   [(set_attr "type" "callv")])
20127
20128 (define_insn "*call_value_0"
20129   [(set (match_operand 0 "" "")
20130         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20131               (match_operand:SI 2 "" "")))]
20132   "!TARGET_64BIT"
20133 {
20134   if (SIBLING_CALL_P (insn))
20135     return "jmp\t%P1";
20136   else
20137     return "call\t%P1";
20138 }
20139   [(set_attr "type" "callv")])
20140
20141 (define_insn "*call_value_0_rex64"
20142   [(set (match_operand 0 "" "")
20143         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20144               (match_operand:DI 2 "const_int_operand" "")))]
20145   "TARGET_64BIT"
20146 {
20147   if (SIBLING_CALL_P (insn))
20148     return "jmp\t%P1";
20149   else
20150     return "call\t%P1";
20151 }
20152   [(set_attr "type" "callv")])
20153
20154 (define_insn "*call_value_0_rex64_ms_sysv"
20155   [(set (match_operand 0 "" "")
20156         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20157               (match_operand:DI 2 "const_int_operand" "")))
20158    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20159    (clobber (reg:TI XMM6_REG))
20160    (clobber (reg:TI XMM7_REG))
20161    (clobber (reg:TI XMM8_REG))
20162    (clobber (reg:TI XMM9_REG))
20163    (clobber (reg:TI XMM10_REG))
20164    (clobber (reg:TI XMM11_REG))
20165    (clobber (reg:TI XMM12_REG))
20166    (clobber (reg:TI XMM13_REG))
20167    (clobber (reg:TI XMM14_REG))
20168    (clobber (reg:TI XMM15_REG))
20169    (clobber (reg:DI SI_REG))
20170    (clobber (reg:DI DI_REG))]
20171   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20172 {
20173   if (SIBLING_CALL_P (insn))
20174     return "jmp\t%P1";
20175   else
20176     return "call\t%P1";
20177 }
20178   [(set_attr "type" "callv")])
20179
20180 (define_insn "*call_value_1"
20181   [(set (match_operand 0 "" "")
20182         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20183               (match_operand:SI 2 "" "")))]
20184   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20185 {
20186   if (constant_call_address_operand (operands[1], Pmode))
20187     return "call\t%P1";
20188   return "call\t%A1";
20189 }
20190   [(set_attr "type" "callv")])
20191
20192 (define_insn "*sibcall_value_1"
20193   [(set (match_operand 0 "" "")
20194         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20195               (match_operand:SI 2 "" "")))]
20196   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20197   "@
20198    jmp\t%P1
20199    jmp\t%A1"
20200   [(set_attr "type" "callv")])
20201
20202 (define_insn "*call_value_1_rex64"
20203   [(set (match_operand 0 "" "")
20204         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20205               (match_operand:DI 2 "" "")))]
20206   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20207    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20208 {
20209   if (constant_call_address_operand (operands[1], Pmode))
20210     return "call\t%P1";
20211   return "call\t%A1";
20212 }
20213   [(set_attr "type" "callv")])
20214
20215 (define_insn "*call_value_1_rex64_ms_sysv"
20216   [(set (match_operand 0 "" "")
20217         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20218               (match_operand:DI 2 "" "")))
20219    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20220    (clobber (reg:TI XMM6_REG))
20221    (clobber (reg:TI XMM7_REG))
20222    (clobber (reg:TI XMM8_REG))
20223    (clobber (reg:TI XMM9_REG))
20224    (clobber (reg:TI XMM10_REG))
20225    (clobber (reg:TI XMM11_REG))
20226    (clobber (reg:TI XMM12_REG))
20227    (clobber (reg:TI XMM13_REG))
20228    (clobber (reg:TI XMM14_REG))
20229    (clobber (reg:TI XMM15_REG))
20230    (clobber (reg:DI SI_REG))
20231    (clobber (reg:DI DI_REG))]
20232   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20233 {
20234   if (constant_call_address_operand (operands[1], Pmode))
20235     return "call\t%P1";
20236   return "call\t%A1";
20237 }
20238   [(set_attr "type" "callv")])
20239
20240 (define_insn "*call_value_1_rex64_large"
20241   [(set (match_operand 0 "" "")
20242         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20243               (match_operand:DI 2 "" "")))]
20244   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20245   "call\t%A1"
20246   [(set_attr "type" "callv")])
20247
20248 (define_insn "*sibcall_value_1_rex64"
20249   [(set (match_operand 0 "" "")
20250         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20251               (match_operand:DI 2 "" "")))]
20252   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20253   "@
20254    jmp\t%P1
20255    jmp\t%A1"
20256   [(set_attr "type" "callv")])
20257 \f
20258 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20259 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20260 ;; caught for use by garbage collectors and the like.  Using an insn that
20261 ;; maps to SIGILL makes it more likely the program will rightfully die.
20262 ;; Keeping with tradition, "6" is in honor of #UD.
20263 (define_insn "trap"
20264   [(trap_if (const_int 1) (const_int 6))]
20265   ""
20266   { return ASM_SHORT "0x0b0f"; }
20267   [(set_attr "length" "2")])
20268
20269 (define_expand "sse_prologue_save"
20270   [(parallel [(set (match_operand:BLK 0 "" "")
20271                    (unspec:BLK [(reg:DI XMM0_REG)
20272                                 (reg:DI XMM1_REG)
20273                                 (reg:DI XMM2_REG)
20274                                 (reg:DI XMM3_REG)
20275                                 (reg:DI XMM4_REG)
20276                                 (reg:DI XMM5_REG)
20277                                 (reg:DI XMM6_REG)
20278                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20279               (use (match_operand:DI 1 "register_operand" ""))
20280               (use (match_operand:DI 2 "immediate_operand" ""))
20281               (use (label_ref:DI (match_operand 3 "" "")))])]
20282   "TARGET_64BIT"
20283   "")
20284
20285 (define_insn "*sse_prologue_save_insn"
20286   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20287                           (match_operand:DI 4 "const_int_operand" "n")))
20288         (unspec:BLK [(reg:DI XMM0_REG)
20289                      (reg:DI XMM1_REG)
20290                      (reg:DI XMM2_REG)
20291                      (reg:DI XMM3_REG)
20292                      (reg:DI XMM4_REG)
20293                      (reg:DI XMM5_REG)
20294                      (reg:DI XMM6_REG)
20295                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20296    (use (match_operand:DI 1 "register_operand" "r"))
20297    (use (match_operand:DI 2 "const_int_operand" "i"))
20298    (use (label_ref:DI (match_operand 3 "" "X")))]
20299   "TARGET_64BIT
20300    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20301    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20302 {
20303   int i;
20304   operands[0] = gen_rtx_MEM (Pmode,
20305                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20306   /* VEX instruction with a REX prefix will #UD.  */
20307   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20308     gcc_unreachable ();
20309
20310   output_asm_insn ("jmp\t%A1", operands);
20311   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20312     {
20313       operands[4] = adjust_address (operands[0], DImode, i*16);
20314       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20315       PUT_MODE (operands[4], TImode);
20316       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20317         output_asm_insn ("rex", operands);
20318       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20319     }
20320   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20321                                      CODE_LABEL_NUMBER (operands[3]));
20322   return "";
20323 }
20324   [(set_attr "type" "other")
20325    (set_attr "length_immediate" "0")
20326    (set_attr "length_address" "0")
20327    (set (attr "length")
20328      (if_then_else
20329        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20330        (const_string "34")
20331        (const_string "42")))
20332    (set_attr "memory" "store")
20333    (set_attr "modrm" "0")
20334    (set_attr "prefix" "maybe_vex")
20335    (set_attr "mode" "DI")])
20336
20337 (define_expand "prefetch"
20338   [(prefetch (match_operand 0 "address_operand" "")
20339              (match_operand:SI 1 "const_int_operand" "")
20340              (match_operand:SI 2 "const_int_operand" ""))]
20341   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20342 {
20343   int rw = INTVAL (operands[1]);
20344   int locality = INTVAL (operands[2]);
20345
20346   gcc_assert (rw == 0 || rw == 1);
20347   gcc_assert (locality >= 0 && locality <= 3);
20348   gcc_assert (GET_MODE (operands[0]) == Pmode
20349               || GET_MODE (operands[0]) == VOIDmode);
20350
20351   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20352      supported by SSE counterpart or the SSE prefetch is not available
20353      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20354      of locality.  */
20355   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20356     operands[2] = GEN_INT (3);
20357   else
20358     operands[1] = const0_rtx;
20359 })
20360
20361 (define_insn "*prefetch_sse"
20362   [(prefetch (match_operand:SI 0 "address_operand" "p")
20363              (const_int 0)
20364              (match_operand:SI 1 "const_int_operand" ""))]
20365   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20366 {
20367   static const char * const patterns[4] = {
20368    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20369   };
20370
20371   int locality = INTVAL (operands[1]);
20372   gcc_assert (locality >= 0 && locality <= 3);
20373
20374   return patterns[locality];
20375 }
20376   [(set_attr "type" "sse")
20377    (set_attr "atom_sse_attr" "prefetch")
20378    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20379    (set_attr "memory" "none")])
20380
20381 (define_insn "*prefetch_sse_rex"
20382   [(prefetch (match_operand:DI 0 "address_operand" "p")
20383              (const_int 0)
20384              (match_operand:SI 1 "const_int_operand" ""))]
20385   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20386 {
20387   static const char * const patterns[4] = {
20388    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20389   };
20390
20391   int locality = INTVAL (operands[1]);
20392   gcc_assert (locality >= 0 && locality <= 3);
20393
20394   return patterns[locality];
20395 }
20396   [(set_attr "type" "sse")
20397    (set_attr "atom_sse_attr" "prefetch")
20398    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20399    (set_attr "memory" "none")])
20400
20401 (define_insn "*prefetch_3dnow"
20402   [(prefetch (match_operand:SI 0 "address_operand" "p")
20403              (match_operand:SI 1 "const_int_operand" "n")
20404              (const_int 3))]
20405   "TARGET_3DNOW && !TARGET_64BIT"
20406 {
20407   if (INTVAL (operands[1]) == 0)
20408     return "prefetch\t%a0";
20409   else
20410     return "prefetchw\t%a0";
20411 }
20412   [(set_attr "type" "mmx")
20413    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20414    (set_attr "memory" "none")])
20415
20416 (define_insn "*prefetch_3dnow_rex"
20417   [(prefetch (match_operand:DI 0 "address_operand" "p")
20418              (match_operand:SI 1 "const_int_operand" "n")
20419              (const_int 3))]
20420   "TARGET_3DNOW && TARGET_64BIT"
20421 {
20422   if (INTVAL (operands[1]) == 0)
20423     return "prefetch\t%a0";
20424   else
20425     return "prefetchw\t%a0";
20426 }
20427   [(set_attr "type" "mmx")
20428    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20429    (set_attr "memory" "none")])
20430
20431 (define_expand "stack_protect_set"
20432   [(match_operand 0 "memory_operand" "")
20433    (match_operand 1 "memory_operand" "")]
20434   ""
20435 {
20436 #ifdef TARGET_THREAD_SSP_OFFSET
20437   if (TARGET_64BIT)
20438     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20439                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20440   else
20441     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20442                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20443 #else
20444   if (TARGET_64BIT)
20445     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20446   else
20447     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20448 #endif
20449   DONE;
20450 })
20451
20452 (define_insn "stack_protect_set_si"
20453   [(set (match_operand:SI 0 "memory_operand" "=m")
20454         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20455    (set (match_scratch:SI 2 "=&r") (const_int 0))
20456    (clobber (reg:CC FLAGS_REG))]
20457   ""
20458   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20459   [(set_attr "type" "multi")])
20460
20461 (define_insn "stack_protect_set_di"
20462   [(set (match_operand:DI 0 "memory_operand" "=m")
20463         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20464    (set (match_scratch:DI 2 "=&r") (const_int 0))
20465    (clobber (reg:CC FLAGS_REG))]
20466   "TARGET_64BIT"
20467   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20468   [(set_attr "type" "multi")])
20469
20470 (define_insn "stack_tls_protect_set_si"
20471   [(set (match_operand:SI 0 "memory_operand" "=m")
20472         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20473    (set (match_scratch:SI 2 "=&r") (const_int 0))
20474    (clobber (reg:CC FLAGS_REG))]
20475   ""
20476   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20477   [(set_attr "type" "multi")])
20478
20479 (define_insn "stack_tls_protect_set_di"
20480   [(set (match_operand:DI 0 "memory_operand" "=m")
20481         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20482    (set (match_scratch:DI 2 "=&r") (const_int 0))
20483    (clobber (reg:CC FLAGS_REG))]
20484   "TARGET_64BIT"
20485   {
20486      /* The kernel uses a different segment register for performance reasons; a
20487         system call would not have to trash the userspace segment register,
20488         which would be expensive */
20489      if (ix86_cmodel != CM_KERNEL)
20490         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20491      else
20492         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20493   }
20494   [(set_attr "type" "multi")])
20495
20496 (define_expand "stack_protect_test"
20497   [(match_operand 0 "memory_operand" "")
20498    (match_operand 1 "memory_operand" "")
20499    (match_operand 2 "" "")]
20500   ""
20501 {
20502   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20503
20504 #ifdef TARGET_THREAD_SSP_OFFSET
20505   if (TARGET_64BIT)
20506     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20507                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20508   else
20509     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20510                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20511 #else
20512   if (TARGET_64BIT)
20513     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20514   else
20515     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20516 #endif
20517
20518   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20519                                   flags, const0_rtx, operands[2]));
20520   DONE;
20521 })
20522
20523 (define_insn "stack_protect_test_si"
20524   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20525         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20526                      (match_operand:SI 2 "memory_operand" "m")]
20527                     UNSPEC_SP_TEST))
20528    (clobber (match_scratch:SI 3 "=&r"))]
20529   ""
20530   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20531   [(set_attr "type" "multi")])
20532
20533 (define_insn "stack_protect_test_di"
20534   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20535         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20536                      (match_operand:DI 2 "memory_operand" "m")]
20537                     UNSPEC_SP_TEST))
20538    (clobber (match_scratch:DI 3 "=&r"))]
20539   "TARGET_64BIT"
20540   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20541   [(set_attr "type" "multi")])
20542
20543 (define_insn "stack_tls_protect_test_si"
20544   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20545         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20546                      (match_operand:SI 2 "const_int_operand" "i")]
20547                     UNSPEC_SP_TLS_TEST))
20548    (clobber (match_scratch:SI 3 "=r"))]
20549   ""
20550   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20551   [(set_attr "type" "multi")])
20552
20553 (define_insn "stack_tls_protect_test_di"
20554   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20555         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20556                      (match_operand:DI 2 "const_int_operand" "i")]
20557                     UNSPEC_SP_TLS_TEST))
20558    (clobber (match_scratch:DI 3 "=r"))]
20559   "TARGET_64BIT"
20560   {
20561      /* The kernel uses a different segment register for performance reasons; a
20562         system call would not have to trash the userspace segment register,
20563         which would be expensive */
20564      if (ix86_cmodel != CM_KERNEL)
20565         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20566      else
20567         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20568   }
20569   [(set_attr "type" "multi")])
20570
20571 (define_insn "sse4_2_crc32<mode>"
20572   [(set (match_operand:SI 0 "register_operand" "=r")
20573         (unspec:SI
20574           [(match_operand:SI 1 "register_operand" "0")
20575            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20576           UNSPEC_CRC32))]
20577   "TARGET_SSE4_2 || TARGET_CRC32"
20578   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20579   [(set_attr "type" "sselog1")
20580    (set_attr "prefix_rep" "1")
20581    (set_attr "prefix_extra" "1")
20582    (set (attr "prefix_data16")
20583      (if_then_else (match_operand:HI 2 "" "")
20584        (const_string "1")
20585        (const_string "*")))
20586    (set (attr "prefix_rex")
20587      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20588        (const_string "1")
20589        (const_string "*")))
20590    (set_attr "mode" "SI")])
20591
20592 (define_insn "sse4_2_crc32di"
20593   [(set (match_operand:DI 0 "register_operand" "=r")
20594         (unspec:DI
20595           [(match_operand:DI 1 "register_operand" "0")
20596            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20597           UNSPEC_CRC32))]
20598   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20599   "crc32{q}\t{%2, %0|%0, %2}"
20600   [(set_attr "type" "sselog1")
20601    (set_attr "prefix_rep" "1")
20602    (set_attr "prefix_extra" "1")
20603    (set_attr "mode" "DI")])
20604
20605 (define_expand "rdpmc"
20606   [(match_operand:DI 0 "register_operand" "")
20607    (match_operand:SI 1 "register_operand" "")]
20608   ""
20609 {
20610   rtx reg = gen_reg_rtx (DImode);
20611   rtx si;
20612
20613   /* Force operand 1 into ECX.  */
20614   rtx ecx = gen_rtx_REG (SImode, CX_REG);
20615   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20616   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20617                                 UNSPECV_RDPMC);
20618
20619   if (TARGET_64BIT)
20620     {
20621       rtvec vec = rtvec_alloc (2);
20622       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20623       rtx upper = gen_reg_rtx (DImode);
20624       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20625                                         gen_rtvec (1, const0_rtx),
20626                                         UNSPECV_RDPMC);
20627       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20628       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20629       emit_insn (load);
20630       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20631                                    NULL, 1, OPTAB_DIRECT);
20632       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20633                                  OPTAB_DIRECT);
20634     }
20635   else
20636     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20637   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20638   DONE;
20639 })
20640
20641 (define_insn "*rdpmc"
20642   [(set (match_operand:DI 0 "register_operand" "=A")
20643         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20644                             UNSPECV_RDPMC))]
20645   "!TARGET_64BIT"
20646   "rdpmc"
20647   [(set_attr "type" "other")
20648    (set_attr "length" "2")])
20649
20650 (define_insn "*rdpmc_rex64"
20651   [(set (match_operand:DI 0 "register_operand" "=a")
20652         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20653                             UNSPECV_RDPMC))
20654   (set (match_operand:DI 1 "register_operand" "=d")
20655        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20656   "TARGET_64BIT"
20657   "rdpmc"
20658   [(set_attr "type" "other")
20659    (set_attr "length" "2")])
20660
20661 (define_expand "rdtsc"
20662   [(set (match_operand:DI 0 "register_operand" "")
20663         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20664   ""
20665 {
20666   if (TARGET_64BIT)
20667     {
20668       rtvec vec = rtvec_alloc (2);
20669       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20670       rtx upper = gen_reg_rtx (DImode);
20671       rtx lower = gen_reg_rtx (DImode);
20672       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20673                                          gen_rtvec (1, const0_rtx),
20674                                          UNSPECV_RDTSC);
20675       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20676       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20677       emit_insn (load);
20678       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20679                                    NULL, 1, OPTAB_DIRECT);
20680       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20681                                    OPTAB_DIRECT);
20682       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20683       DONE;
20684     }
20685 })
20686
20687 (define_insn "*rdtsc"
20688   [(set (match_operand:DI 0 "register_operand" "=A")
20689         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20690   "!TARGET_64BIT"
20691   "rdtsc"
20692   [(set_attr "type" "other")
20693    (set_attr "length" "2")])
20694
20695 (define_insn "*rdtsc_rex64"
20696   [(set (match_operand:DI 0 "register_operand" "=a")
20697         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20698    (set (match_operand:DI 1 "register_operand" "=d")
20699         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20700   "TARGET_64BIT"
20701   "rdtsc"
20702   [(set_attr "type" "other")
20703    (set_attr "length" "2")])
20704
20705 (define_expand "rdtscp"
20706   [(match_operand:DI 0 "register_operand" "")
20707    (match_operand:SI 1 "memory_operand" "")]
20708   ""
20709 {
20710   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20711                                     gen_rtvec (1, const0_rtx),
20712                                     UNSPECV_RDTSCP);
20713   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20714                                     gen_rtvec (1, const0_rtx),
20715                                     UNSPECV_RDTSCP);
20716   rtx reg = gen_reg_rtx (DImode);
20717   rtx tmp = gen_reg_rtx (SImode);
20718
20719   if (TARGET_64BIT)
20720     {
20721       rtvec vec = rtvec_alloc (3);
20722       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20723       rtx upper = gen_reg_rtx (DImode);
20724       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20725       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20726       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20727       emit_insn (load);
20728       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20729                                    NULL, 1, OPTAB_DIRECT);
20730       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20731                                  OPTAB_DIRECT);
20732     }
20733   else
20734     {
20735       rtvec vec = rtvec_alloc (2);
20736       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20737       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20738       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20739       emit_insn (load);
20740     }
20741   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20742   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20743   DONE;
20744 })
20745
20746 (define_insn "*rdtscp"
20747   [(set (match_operand:DI 0 "register_operand" "=A")
20748         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20749    (set (match_operand:SI 1 "register_operand" "=c")
20750         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20751   "!TARGET_64BIT"
20752   "rdtscp"
20753   [(set_attr "type" "other")
20754    (set_attr "length" "3")])
20755
20756 (define_insn "*rdtscp_rex64"
20757   [(set (match_operand:DI 0 "register_operand" "=a")
20758         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20759    (set (match_operand:DI 1 "register_operand" "=d")
20760         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20761    (set (match_operand:SI 2 "register_operand" "=c")
20762         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20763   "TARGET_64BIT"
20764   "rdtscp"
20765   [(set_attr "type" "other")
20766    (set_attr "length" "3")])
20767
20768 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20769 ;;
20770 ;; LWP instructions
20771 ;;
20772 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20773
20774 (define_expand "lwp_llwpcb"
20775   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20776                     UNSPECV_LLWP_INTRINSIC)]
20777   "TARGET_LWP"
20778   "")
20779
20780 (define_insn "*lwp_llwpcb<mode>1"
20781   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20782                     UNSPECV_LLWP_INTRINSIC)]
20783   "TARGET_LWP"
20784   "llwpcb\t%0"
20785   [(set_attr "type" "lwp")
20786    (set_attr "mode" "<MODE>")
20787    (set_attr "length" "5")])
20788
20789 (define_expand "lwp_slwpcb"
20790   [(set (match_operand 0 "register_operand" "=r")
20791         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20792   "TARGET_LWP"
20793   {
20794     if (TARGET_64BIT)
20795       emit_insn (gen_lwp_slwpcbdi (operands[0]));
20796     else
20797       emit_insn (gen_lwp_slwpcbsi (operands[0]));
20798     DONE;
20799   })
20800
20801 (define_insn "lwp_slwpcb<mode>"
20802   [(set (match_operand:P 0 "register_operand" "=r")
20803         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20804   "TARGET_LWP"
20805   "slwpcb\t%0"
20806   [(set_attr "type" "lwp")
20807    (set_attr "mode" "<MODE>")
20808    (set_attr "length" "5")])
20809
20810 (define_expand "lwp_lwpval<mode>3"
20811   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20812                      (match_operand:SI 2 "nonimmediate_operand" "rm")
20813                      (match_operand:SI 3 "const_int_operand" "i")]
20814                     UNSPECV_LWPVAL_INTRINSIC)]
20815   "TARGET_LWP"
20816   "/* Avoid unused variable warning.  */
20817    (void) operand0;")
20818
20819 (define_insn "*lwp_lwpval<mode>3_1"
20820   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20821                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20822                      (match_operand:SI 2 "const_int_operand" "i")]
20823                     UNSPECV_LWPVAL_INTRINSIC)]
20824   "TARGET_LWP"
20825   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20826   [(set_attr "type" "lwp")
20827    (set_attr "mode" "<MODE>")
20828    (set (attr "length")
20829         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20830
20831 (define_expand "lwp_lwpins<mode>3"
20832   [(set (reg:CCC FLAGS_REG)
20833         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20834                               (match_operand:SI 2 "nonimmediate_operand" "rm")
20835                               (match_operand:SI 3 "const_int_operand" "i")]
20836                              UNSPECV_LWPINS_INTRINSIC))
20837    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20838         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20839   "TARGET_LWP"
20840   "")
20841
20842 (define_insn "*lwp_lwpins<mode>3_1"
20843   [(set (reg:CCC FLAGS_REG)
20844         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20845                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20846                               (match_operand:SI 2 "const_int_operand" "i")]
20847                              UNSPECV_LWPINS_INTRINSIC))]
20848   "TARGET_LWP"
20849   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20850   [(set_attr "type" "lwp")
20851    (set_attr "mode" "<MODE>")
20852    (set (attr "length")
20853         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20854
20855 (include "mmx.md")
20856 (include "sse.md")
20857 (include "sync.md")