OSDN Git Service

* config/i386/i386.md (float<SSEMODEI24:mode><X87MODEF:mode>2):
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63
64 ;; UNSPEC usage:
65
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
79
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
89
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
95
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
106
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
126
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
131
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
143
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
151
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
163
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
166
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
172
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
177
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
183
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
193
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
198
199    ; For FMA4 support
200    (UNSPEC_FMA4_INTRINSIC       150)
201    (UNSPEC_FMA4_FMADDSUB        151)
202    (UNSPEC_FMA4_FMSUBADD        152)
203    (UNSPEC_XOP_UNSIGNED_CMP     151)
204    (UNSPEC_XOP_TRUEFALSE        152)
205    (UNSPEC_XOP_PERMUTE          153)
206    (UNSPEC_FRCZ                 154)
207    (UNSPEC_LLWP_INTRINSIC       155)
208    (UNSPEC_SLWP_INTRINSIC       156)
209    (UNSPECV_LWPVAL_INTRINSIC    157)
210    (UNSPECV_LWPINS_INTRINSIC    158)
211
212    ; For AES support
213    (UNSPEC_AESENC               159)
214    (UNSPEC_AESENCLAST           160)
215    (UNSPEC_AESDEC               161)
216    (UNSPEC_AESDECLAST           162)
217    (UNSPEC_AESIMC               163)
218    (UNSPEC_AESKEYGENASSIST      164)
219
220    ; For PCLMUL support
221    (UNSPEC_PCLMUL               165)
222
223    ; For AVX support
224    (UNSPEC_PCMP                 166)
225    (UNSPEC_VPERMIL              167)
226    (UNSPEC_VPERMIL2F128         168)
227    (UNSPEC_MASKLOAD             169)
228    (UNSPEC_MASKSTORE            170)
229    (UNSPEC_CAST                 171)
230    (UNSPEC_VTESTP               172)
231   ])
232
233 (define_constants
234   [(UNSPECV_BLOCKAGE            0)
235    (UNSPECV_STACK_PROBE         1)
236    (UNSPECV_EMMS                2)
237    (UNSPECV_LDMXCSR             3)
238    (UNSPECV_STMXCSR             4)
239    (UNSPECV_FEMMS               5)
240    (UNSPECV_CLFLUSH             6)
241    (UNSPECV_ALIGN               7)
242    (UNSPECV_MONITOR             8)
243    (UNSPECV_MWAIT               9)
244    (UNSPECV_CMPXCHG             10)
245    (UNSPECV_XCHG                12)
246    (UNSPECV_LOCK                13)
247    (UNSPECV_PROLOGUE_USE        14)
248    (UNSPECV_CLD                 15)
249    (UNSPECV_VZEROALL            16)
250    (UNSPECV_VZEROUPPER          17)
251    (UNSPECV_RDTSC               18)
252    (UNSPECV_RDTSCP              19)
253    (UNSPECV_RDPMC               20)
254    (UNSPECV_VSWAPMOV    21)
255   ])
256
257 ;; Constants to represent pcomtrue/pcomfalse variants
258 (define_constants
259   [(PCOM_FALSE                  0)
260    (PCOM_TRUE                   1)
261    (COM_FALSE_S                 2)
262    (COM_FALSE_P                 3)
263    (COM_TRUE_S                  4)
264    (COM_TRUE_P                  5)
265   ])
266
267 ;; Constants used in the XOP pperm instruction
268 (define_constants
269   [(PPERM_SRC                   0x00)   /* copy source */
270    (PPERM_INVERT                0x20)   /* invert source */
271    (PPERM_REVERSE               0x40)   /* bit reverse source */
272    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
273    (PPERM_ZERO                  0x80)   /* all 0's */
274    (PPERM_ONES                  0xa0)   /* all 1's */
275    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
276    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
277    (PPERM_SRC1                  0x00)   /* use first source byte */
278    (PPERM_SRC2                  0x10)   /* use second source byte */
279    ])
280
281 ;; Registers by name.
282 (define_constants
283   [(AX_REG                       0)
284    (DX_REG                       1)
285    (CX_REG                       2)
286    (BX_REG                       3)
287    (SI_REG                       4)
288    (DI_REG                       5)
289    (BP_REG                       6)
290    (SP_REG                       7)
291    (ST0_REG                      8)
292    (ST1_REG                      9)
293    (ST2_REG                     10)
294    (ST3_REG                     11)
295    (ST4_REG                     12)
296    (ST5_REG                     13)
297    (ST6_REG                     14)
298    (ST7_REG                     15)
299    (FLAGS_REG                   17)
300    (FPSR_REG                    18)
301    (FPCR_REG                    19)
302    (XMM0_REG                    21)
303    (XMM1_REG                    22)
304    (XMM2_REG                    23)
305    (XMM3_REG                    24)
306    (XMM4_REG                    25)
307    (XMM5_REG                    26)
308    (XMM6_REG                    27)
309    (XMM7_REG                    28)
310    (MM0_REG                     29)
311    (MM1_REG                     30)
312    (MM2_REG                     31)
313    (MM3_REG                     32)
314    (MM4_REG                     33)
315    (MM5_REG                     34)
316    (MM6_REG                     35)
317    (MM7_REG                     36)
318    (R8_REG                      37)
319    (R9_REG                      38)
320    (R10_REG                     39)
321    (R11_REG                     40)
322    (R12_REG                     41)
323    (R13_REG                     42)
324    (XMM8_REG                    45)
325    (XMM9_REG                    46)
326    (XMM10_REG                   47)
327    (XMM11_REG                   48)
328    (XMM12_REG                   49)
329    (XMM13_REG                   50)
330    (XMM14_REG                   51)
331    (XMM15_REG                   52)
332   ])
333
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
335 ;; from i386.c.
336
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first.  This allows for better optimization.  For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
341
342 \f
343 ;; Processor type.
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
345                     generic64,amdfam10"
346   (const (symbol_ref "ix86_schedule")))
347
348 ;; A basic instruction type.  Refinements due to arguments to be
349 ;; provided in other attributes.
350 (define_attr "type"
351   "other,multi,
352    alu,alu1,negnot,imov,imovx,lea,
353    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354    icmp,test,ibr,setcc,icmov,
355    push,pop,call,callv,leave,
356    str,bitmanip,
357    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360    ssemuladd,sse4arg,lwp,
361    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362   (const_string "other"))
363
364 ;; Main data type used by the insn
365 (define_attr "mode"
366   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367   (const_string "unknown"))
368
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372            (const_string "i387")
373          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
376            (const_string "sse")
377          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
378            (const_string "mmx")
379          (eq_attr "type" "other")
380            (const_string "unknown")]
381          (const_string "integer")))
382
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
386                           bitmanip")
387            (const_int 0)
388          (eq_attr "unit" "i387,sse,mmx")
389            (const_int 0)
390          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
391                           imul,icmp,push,pop")
392            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393          (eq_attr "type" "imov,test")
394            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395          (eq_attr "type" "call")
396            (if_then_else (match_operand 0 "constant_call_address_operand" "")
397              (const_int 4)
398              (const_int 0))
399          (eq_attr "type" "callv")
400            (if_then_else (match_operand 1 "constant_call_address_operand" "")
401              (const_int 4)
402              (const_int 0))
403          ;; We don't know the size before shorten_branches.  Expect
404          ;; the instruction to fit for better scheduling.
405          (eq_attr "type" "ibr")
406            (const_int 1)
407          ]
408          (symbol_ref "/* Update immediate_length and other attributes! */
409                       gcc_unreachable (),1")))
410
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413   (cond [(eq_attr "type" "str,other,multi,fxch")
414            (const_int 0)
415          (and (eq_attr "type" "call")
416               (match_operand 0 "constant_call_address_operand" ""))
417              (const_int 0)
418          (and (eq_attr "type" "callv")
419               (match_operand 1 "constant_call_address_operand" ""))
420              (const_int 0)
421          ]
422          (symbol_ref "ix86_attr_length_address_default (insn)")))
423
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
427            (const_int 0)
428          (eq_attr "mode" "HI")
429            (const_int 1)
430          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
431            (const_int 1)
432         ]
433         (const_int 0)))
434
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
440            (const_int 1)
441         ]
442         (const_int 0)))
443
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
446   (if_then_else
447     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448          (eq_attr "unit" "sse,mmx"))
449     (const_int 1)
450     (const_int 0)))
451
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
455            (const_int 0)
456          (and (eq_attr "mode" "DI")
457               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458                    (eq_attr "unit" "!mmx")))
459            (const_int 1)
460          (and (eq_attr "mode" "QI")
461               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
462                   (const_int 0)))
463            (const_int 1)
464          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
465              (const_int 0))
466            (const_int 1)
467          (and (eq_attr "type" "imovx")
468               (match_operand:QI 1 "ext_QIreg_operand" ""))
469            (const_int 1)
470         ]
471         (const_int 0)))
472
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg")
479            (const_int 2)
480          (eq_attr "type" "sseiadd1,ssecvt1")
481            (const_int 1)
482         ]
483         (const_int 0)))
484
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
488     (const_string "vex")
489     (const_string "orig")))
490
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
493
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499   (if_then_else (and (eq_attr "prefix_0f" "1")
500                      (eq_attr "prefix_extra" "0"))
501     (if_then_else (eq_attr "prefix_vex_w" "1")
502       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504     (if_then_else (eq_attr "prefix_vex_w" "1")
505       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
507
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510   (cond [(eq_attr "type" "str,leave")
511            (const_int 0)
512          (eq_attr "unit" "i387")
513            (const_int 0)
514          (and (eq_attr "type" "incdec")
515               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516                    (ior (match_operand:SI 1 "register_operand" "")
517                         (match_operand:HI 1 "register_operand" ""))))
518            (const_int 0)
519          (and (eq_attr "type" "push")
520               (not (match_operand 1 "memory_operand" "")))
521            (const_int 0)
522          (and (eq_attr "type" "pop")
523               (not (match_operand 0 "memory_operand" "")))
524            (const_int 0)
525          (and (eq_attr "type" "imov")
526               (and (not (eq_attr "mode" "DI"))
527                    (ior (and (match_operand 0 "register_operand" "")
528                              (match_operand 1 "immediate_operand" ""))
529                         (ior (and (match_operand 0 "ax_reg_operand" "")
530                                   (match_operand 1 "memory_displacement_only_operand" ""))
531                              (and (match_operand 0 "memory_displacement_only_operand" "")
532                                   (match_operand 1 "ax_reg_operand" ""))))))
533            (const_int 0)
534          (and (eq_attr "type" "call")
535               (match_operand 0 "constant_call_address_operand" ""))
536              (const_int 0)
537          (and (eq_attr "type" "callv")
538               (match_operand 1 "constant_call_address_operand" ""))
539              (const_int 0)
540          (and (eq_attr "type" "alu,alu1,icmp,test")
541               (match_operand 0 "ax_reg_operand" ""))
542              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
543          ]
544          (const_int 1)))
545
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
549 ;; other insns.
550 (define_attr "length" ""
551   (cond [(eq_attr "type" "other,multi,fistp,frndint")
552            (const_int 16)
553          (eq_attr "type" "fcmp")
554            (const_int 4)
555          (eq_attr "unit" "i387")
556            (plus (const_int 2)
557                  (plus (attr "prefix_data16")
558                        (attr "length_address")))
559          (ior (eq_attr "prefix" "vex")
560               (and (eq_attr "prefix" "maybe_vex")
561                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562            (plus (attr "length_vex")
563                  (plus (attr "length_immediate")
564                        (plus (attr "modrm")
565                              (attr "length_address"))))]
566          (plus (plus (attr "modrm")
567                      (plus (attr "prefix_0f")
568                            (plus (attr "prefix_rex")
569                                  (plus (attr "prefix_extra")
570                                        (const_int 1)))))
571                (plus (attr "prefix_rep")
572                      (plus (attr "prefix_data16")
573                            (plus (attr "length_immediate")
574                                  (attr "length_address")))))))
575
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
579
580 (define_attr "memory" "none,load,store,both,unknown"
581   (cond [(eq_attr "type" "other,multi,str")
582            (const_string "unknown")
583          (eq_attr "type" "lea,fcmov,fpspc")
584            (const_string "none")
585          (eq_attr "type" "fistp,leave")
586            (const_string "both")
587          (eq_attr "type" "frndint")
588            (const_string "load")
589          (eq_attr "type" "push")
590            (if_then_else (match_operand 1 "memory_operand" "")
591              (const_string "both")
592              (const_string "store"))
593          (eq_attr "type" "pop")
594            (if_then_else (match_operand 0 "memory_operand" "")
595              (const_string "both")
596              (const_string "load"))
597          (eq_attr "type" "setcc")
598            (if_then_else (match_operand 0 "memory_operand" "")
599              (const_string "store")
600              (const_string "none"))
601          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602            (if_then_else (ior (match_operand 0 "memory_operand" "")
603                               (match_operand 1 "memory_operand" ""))
604              (const_string "load")
605              (const_string "none"))
606          (eq_attr "type" "ibr")
607            (if_then_else (match_operand 0 "memory_operand" "")
608              (const_string "load")
609              (const_string "none"))
610          (eq_attr "type" "call")
611            (if_then_else (match_operand 0 "constant_call_address_operand" "")
612              (const_string "none")
613              (const_string "load"))
614          (eq_attr "type" "callv")
615            (if_then_else (match_operand 1 "constant_call_address_operand" "")
616              (const_string "none")
617              (const_string "load"))
618          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619               (match_operand 1 "memory_operand" ""))
620            (const_string "both")
621          (and (match_operand 0 "memory_operand" "")
622               (match_operand 1 "memory_operand" ""))
623            (const_string "both")
624          (match_operand 0 "memory_operand" "")
625            (const_string "store")
626          (match_operand 1 "memory_operand" "")
627            (const_string "load")
628          (and (eq_attr "type"
629                  "!alu1,negnot,ishift1,
630                    imov,imovx,icmp,test,bitmanip,
631                    fmov,fcmp,fsgn,
632                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634               (match_operand 2 "memory_operand" ""))
635            (const_string "load")
636          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637               (match_operand 3 "memory_operand" ""))
638            (const_string "load")
639         ]
640         (const_string "none")))
641
642 ;; Indicates if an instruction has both an immediate and a displacement.
643
644 (define_attr "imm_disp" "false,true,unknown"
645   (cond [(eq_attr "type" "other,multi")
646            (const_string "unknown")
647          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648               (and (match_operand 0 "memory_displacement_operand" "")
649                    (match_operand 1 "immediate_operand" "")))
650            (const_string "true")
651          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652               (and (match_operand 0 "memory_displacement_operand" "")
653                    (match_operand 2 "immediate_operand" "")))
654            (const_string "true")
655         ]
656         (const_string "false")))
657
658 ;; Indicates if an FP operation has an integer source.
659
660 (define_attr "fp_int_src" "false,true"
661   (const_string "false"))
662
663 ;; Defines rounding mode of an FP operation.
664
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666   (const_string "any"))
667
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
670
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
673
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676   [(set_attr "length" "128")
677    (set_attr "type" "multi")])
678
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
681
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684                                uneq unge ungt unle unlt ltgt ])
685
686 (define_code_iterator plusminus [plus minus])
687
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
689
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
694
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697   [(plus "add") (ss_plus "adds") (us_plus "addus")
698    (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (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 parallel logic operators
721 (define_code_iterator plogic [and ior xor])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
725
726 ;; Mapping of abs neg operators
727 (define_code_iterator absneg [abs neg])
728
729 ;; Base name for x87 insn mnemonic.
730 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
731
732 ;; Used in signed and unsigned widening multiplications.
733 (define_code_iterator any_extend [sign_extend zero_extend])
734
735 ;; Used in signed and unsigned divisions.
736 (define_code_iterator any_div [div udiv])
737
738 ;; Various insn prefixes for signed and unsigned operations.
739 (define_code_attr u [(sign_extend "") (zero_extend "u")
740                      (div "") (udiv "u")])
741 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
742
743 ;; Instruction prefix for signed and unsigned operations.
744 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
745                              (div "i") (udiv "")])
746
747 ;; All single word integer modes.
748 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
749
750 ;; Single word integer modes without DImode.
751 (define_mode_iterator SWI124 [QI HI SI])
752
753 ;; Single word integer modes without QImode.
754 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
755
756 ;; Single word integer modes without QImode and HImode.
757 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
758
759 ;; All math-dependant single and double word integer modes.
760 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
761                              (HI "TARGET_HIMODE_MATH")
762                              SI DI (TI "TARGET_64BIT")])
763
764 ;; Math-dependant single word integer modes.
765 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
766                             (HI "TARGET_HIMODE_MATH")
767                             SI (DI "TARGET_64BIT")])
768
769 ;; Math-dependant single word integer modes without QImode.
770 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
771                                SI (DI "TARGET_64BIT")])
772
773 ;; Half mode for double word integer modes.
774 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
775                             (DI "TARGET_64BIT")])
776
777 ;; Double word integer modes.
778 (define_mode_attr DWI [(SI "DI") (DI "TI")])
779 (define_mode_attr dwi [(SI "di") (DI "ti")])
780
781 ;; Instruction suffix for integer modes.
782 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
783
784 ;; Register class for integer modes.
785 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
786
787 ;; Immediate operand constraint for integer modes.
788 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
789
790 ;; General operand constraint for word modes.
791 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
792
793 ;; Immediate operand constraint for double integer modes.
794 (define_mode_attr di [(SI "iF") (DI "e")])
795
796 ;; General operand predicate for integer modes.
797 (define_mode_attr general_operand
798         [(QI "general_operand")
799          (HI "general_operand")
800          (SI "general_operand")
801          (DI "x86_64_general_operand")
802          (TI "x86_64_general_operand")])
803
804 ;; General sign/zero extend operand predicate for integer modes.
805 (define_mode_attr general_szext_operand
806         [(QI "general_operand")
807          (HI "general_operand")
808          (SI "general_operand")
809          (DI "x86_64_szext_general_operand")])
810
811 ;; SSE and x87 SFmode and DFmode floating point modes
812 (define_mode_iterator MODEF [SF DF])
813
814 ;; All x87 floating point modes
815 (define_mode_iterator X87MODEF [SF DF XF])
816
817 ;; All integer modes handled by x87 fisttp operator.
818 (define_mode_iterator X87MODEI [HI SI DI])
819
820 ;; All integer modes handled by integer x87 operators.
821 (define_mode_iterator X87MODEI12 [HI SI])
822
823 ;; All integer modes handled by SSE cvtts?2si* operators.
824 (define_mode_iterator SSEMODEI24 [SI DI])
825
826 ;; SSE asm suffix for floating point modes
827 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
828
829 ;; SSE vector mode corresponding to a scalar mode
830 (define_mode_attr ssevecmode
831   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
832
833 ;; Instruction suffix for REX 64bit operators.
834 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
835
836 ;; This mode iterator allows :P to be used for patterns that operate on
837 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
838 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
839 \f
840 ;; Scheduling descriptions
841
842 (include "pentium.md")
843 (include "ppro.md")
844 (include "k6.md")
845 (include "athlon.md")
846 (include "geode.md")
847 (include "atom.md")
848
849 \f
850 ;; Operand and operator predicates and constraints
851
852 (include "predicates.md")
853 (include "constraints.md")
854
855 \f
856 ;; Compare and branch/compare and store instructions.
857
858 (define_expand "cbranch<mode>4"
859   [(set (reg:CC FLAGS_REG)
860         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
861                     (match_operand:SDWIM 2 "<general_operand>" "")))
862    (set (pc) (if_then_else
863                (match_operator 0 "comparison_operator"
864                 [(reg:CC FLAGS_REG) (const_int 0)])
865                (label_ref (match_operand 3 "" ""))
866                (pc)))]
867   ""
868 {
869   if (MEM_P (operands[1]) && MEM_P (operands[2]))
870     operands[1] = force_reg (<MODE>mode, operands[1]);
871   ix86_compare_op0 = operands[1];
872   ix86_compare_op1 = operands[2];
873   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
874   DONE;
875 })
876
877 (define_expand "cstore<mode>4"
878   [(set (reg:CC FLAGS_REG)
879         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
880                     (match_operand:SWIM 3 "<general_operand>" "")))
881    (set (match_operand:QI 0 "register_operand" "")
882         (match_operator 1 "comparison_operator"
883           [(reg:CC FLAGS_REG) (const_int 0)]))]
884   ""
885 {
886   if (MEM_P (operands[2]) && MEM_P (operands[3]))
887     operands[2] = force_reg (<MODE>mode, operands[2]);
888   ix86_compare_op0 = operands[2];
889   ix86_compare_op1 = operands[3];
890   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
891   DONE;
892 })
893
894 (define_expand "cmp<mode>_1"
895   [(set (reg:CC FLAGS_REG)
896         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
897                     (match_operand:SWI48 1 "<general_operand>" "")))]
898   ""
899   "")
900
901 (define_insn "*cmp<mode>_ccno_1"
902   [(set (reg FLAGS_REG)
903         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
904                  (match_operand:SWI 1 "const0_operand" "")))]
905   "ix86_match_ccmode (insn, CCNOmode)"
906   "@
907    test{<imodesuffix>}\t%0, %0
908    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
909   [(set_attr "type" "test,icmp")
910    (set_attr "length_immediate" "0,1")
911    (set_attr "mode" "<MODE>")])
912
913 (define_insn "*cmp<mode>_1"
914   [(set (reg FLAGS_REG)
915         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
916                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
917   "ix86_match_ccmode (insn, CCmode)"
918   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
919   [(set_attr "type" "icmp")
920    (set_attr "mode" "<MODE>")])
921
922 (define_insn "*cmp<mode>_minus_1"
923   [(set (reg FLAGS_REG)
924         (compare
925           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
926                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
927           (const_int 0)))]
928   "ix86_match_ccmode (insn, CCGOCmode)"
929   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
930   [(set_attr "type" "icmp")
931    (set_attr "mode" "<MODE>")])
932
933 (define_insn "*cmpqi_ext_1"
934   [(set (reg FLAGS_REG)
935         (compare
936           (match_operand:QI 0 "general_operand" "Qm")
937           (subreg:QI
938             (zero_extract:SI
939               (match_operand 1 "ext_register_operand" "Q")
940               (const_int 8)
941               (const_int 8)) 0)))]
942   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
943   "cmp{b}\t{%h1, %0|%0, %h1}"
944   [(set_attr "type" "icmp")
945    (set_attr "mode" "QI")])
946
947 (define_insn "*cmpqi_ext_1_rex64"
948   [(set (reg FLAGS_REG)
949         (compare
950           (match_operand:QI 0 "register_operand" "Q")
951           (subreg:QI
952             (zero_extract:SI
953               (match_operand 1 "ext_register_operand" "Q")
954               (const_int 8)
955               (const_int 8)) 0)))]
956   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
957   "cmp{b}\t{%h1, %0|%0, %h1}"
958   [(set_attr "type" "icmp")
959    (set_attr "mode" "QI")])
960
961 (define_insn "*cmpqi_ext_2"
962   [(set (reg FLAGS_REG)
963         (compare
964           (subreg:QI
965             (zero_extract:SI
966               (match_operand 0 "ext_register_operand" "Q")
967               (const_int 8)
968               (const_int 8)) 0)
969           (match_operand:QI 1 "const0_operand" "")))]
970   "ix86_match_ccmode (insn, CCNOmode)"
971   "test{b}\t%h0, %h0"
972   [(set_attr "type" "test")
973    (set_attr "length_immediate" "0")
974    (set_attr "mode" "QI")])
975
976 (define_expand "cmpqi_ext_3"
977   [(set (reg:CC FLAGS_REG)
978         (compare:CC
979           (subreg:QI
980             (zero_extract:SI
981               (match_operand 0 "ext_register_operand" "")
982               (const_int 8)
983               (const_int 8)) 0)
984           (match_operand:QI 1 "immediate_operand" "")))]
985   ""
986   "")
987
988 (define_insn "*cmpqi_ext_3_insn"
989   [(set (reg FLAGS_REG)
990         (compare
991           (subreg:QI
992             (zero_extract:SI
993               (match_operand 0 "ext_register_operand" "Q")
994               (const_int 8)
995               (const_int 8)) 0)
996           (match_operand:QI 1 "general_operand" "Qmn")))]
997   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
998   "cmp{b}\t{%1, %h0|%h0, %1}"
999   [(set_attr "type" "icmp")
1000    (set_attr "modrm" "1")
1001    (set_attr "mode" "QI")])
1002
1003 (define_insn "*cmpqi_ext_3_insn_rex64"
1004   [(set (reg FLAGS_REG)
1005         (compare
1006           (subreg:QI
1007             (zero_extract:SI
1008               (match_operand 0 "ext_register_operand" "Q")
1009               (const_int 8)
1010               (const_int 8)) 0)
1011           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1012   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013   "cmp{b}\t{%1, %h0|%h0, %1}"
1014   [(set_attr "type" "icmp")
1015    (set_attr "modrm" "1")
1016    (set_attr "mode" "QI")])
1017
1018 (define_insn "*cmpqi_ext_4"
1019   [(set (reg FLAGS_REG)
1020         (compare
1021           (subreg:QI
1022             (zero_extract:SI
1023               (match_operand 0 "ext_register_operand" "Q")
1024               (const_int 8)
1025               (const_int 8)) 0)
1026           (subreg:QI
1027             (zero_extract:SI
1028               (match_operand 1 "ext_register_operand" "Q")
1029               (const_int 8)
1030               (const_int 8)) 0)))]
1031   "ix86_match_ccmode (insn, CCmode)"
1032   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1033   [(set_attr "type" "icmp")
1034    (set_attr "mode" "QI")])
1035
1036 ;; These implement float point compares.
1037 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1038 ;; which would allow mix and match FP modes on the compares.  Which is what
1039 ;; the old patterns did, but with many more of them.
1040
1041 (define_expand "cbranchxf4"
1042   [(set (reg:CC FLAGS_REG)
1043         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1044                     (match_operand:XF 2 "nonmemory_operand" "")))
1045    (set (pc) (if_then_else
1046               (match_operator 0 "ix86_fp_comparison_operator"
1047                [(reg:CC FLAGS_REG)
1048                 (const_int 0)])
1049               (label_ref (match_operand 3 "" ""))
1050               (pc)))]
1051   "TARGET_80387"
1052 {
1053   ix86_compare_op0 = operands[1];
1054   ix86_compare_op1 = operands[2];
1055   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1056   DONE;
1057 })
1058
1059 (define_expand "cstorexf4"
1060   [(set (reg:CC FLAGS_REG)
1061         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1062                     (match_operand:XF 3 "nonmemory_operand" "")))
1063    (set (match_operand:QI 0 "register_operand" "")
1064               (match_operator 1 "ix86_fp_comparison_operator"
1065                [(reg:CC FLAGS_REG)
1066                 (const_int 0)]))]
1067   "TARGET_80387"
1068 {
1069   ix86_compare_op0 = operands[2];
1070   ix86_compare_op1 = operands[3];
1071   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1072   DONE;
1073 })
1074
1075 (define_expand "cbranch<mode>4"
1076   [(set (reg:CC FLAGS_REG)
1077         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1078                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1079    (set (pc) (if_then_else
1080               (match_operator 0 "ix86_fp_comparison_operator"
1081                [(reg:CC FLAGS_REG)
1082                 (const_int 0)])
1083               (label_ref (match_operand 3 "" ""))
1084               (pc)))]
1085   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1086 {
1087   ix86_compare_op0 = operands[1];
1088   ix86_compare_op1 = operands[2];
1089   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1090   DONE;
1091 })
1092
1093 (define_expand "cstore<mode>4"
1094   [(set (reg:CC FLAGS_REG)
1095         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1096                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1097    (set (match_operand:QI 0 "register_operand" "")
1098               (match_operator 1 "ix86_fp_comparison_operator"
1099                [(reg:CC FLAGS_REG)
1100                 (const_int 0)]))]
1101   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1102 {
1103   ix86_compare_op0 = operands[2];
1104   ix86_compare_op1 = operands[3];
1105   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1106   DONE;
1107 })
1108
1109 (define_expand "cbranchcc4"
1110   [(set (pc) (if_then_else
1111               (match_operator 0 "comparison_operator"
1112                [(match_operand 1 "flags_reg_operand" "")
1113                 (match_operand 2 "const0_operand" "")])
1114               (label_ref (match_operand 3 "" ""))
1115               (pc)))]
1116   ""
1117 {
1118   ix86_compare_op0 = operands[1];
1119   ix86_compare_op1 = operands[2];
1120   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1121   DONE;
1122 })
1123
1124 (define_expand "cstorecc4"
1125   [(set (match_operand:QI 0 "register_operand" "")
1126               (match_operator 1 "comparison_operator"
1127                [(match_operand 2 "flags_reg_operand" "")
1128                 (match_operand 3 "const0_operand" "")]))]
1129   ""
1130 {
1131   ix86_compare_op0 = operands[2];
1132   ix86_compare_op1 = operands[3];
1133   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1134   DONE;
1135 })
1136
1137
1138 ;; FP compares, step 1:
1139 ;; Set the FP condition codes.
1140 ;;
1141 ;; CCFPmode     compare with exceptions
1142 ;; CCFPUmode    compare with no exceptions
1143
1144 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1145 ;; used to manage the reg stack popping would not be preserved.
1146
1147 (define_insn "*cmpfp_0"
1148   [(set (match_operand:HI 0 "register_operand" "=a")
1149         (unspec:HI
1150           [(compare:CCFP
1151              (match_operand 1 "register_operand" "f")
1152              (match_operand 2 "const0_operand" ""))]
1153         UNSPEC_FNSTSW))]
1154   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1155    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1156   "* return output_fp_compare (insn, operands, 0, 0);"
1157   [(set_attr "type" "multi")
1158    (set_attr "unit" "i387")
1159    (set (attr "mode")
1160      (cond [(match_operand:SF 1 "" "")
1161               (const_string "SF")
1162             (match_operand:DF 1 "" "")
1163               (const_string "DF")
1164            ]
1165            (const_string "XF")))])
1166
1167 (define_insn_and_split "*cmpfp_0_cc"
1168   [(set (reg:CCFP FLAGS_REG)
1169         (compare:CCFP
1170           (match_operand 1 "register_operand" "f")
1171           (match_operand 2 "const0_operand" "")))
1172    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1173   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1174    && TARGET_SAHF && !TARGET_CMOVE
1175    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1176   "#"
1177   "&& reload_completed"
1178   [(set (match_dup 0)
1179         (unspec:HI
1180           [(compare:CCFP (match_dup 1)(match_dup 2))]
1181         UNSPEC_FNSTSW))
1182    (set (reg:CC FLAGS_REG)
1183         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1184   ""
1185   [(set_attr "type" "multi")
1186    (set_attr "unit" "i387")
1187    (set (attr "mode")
1188      (cond [(match_operand:SF 1 "" "")
1189               (const_string "SF")
1190             (match_operand:DF 1 "" "")
1191               (const_string "DF")
1192            ]
1193            (const_string "XF")))])
1194
1195 (define_insn "*cmpfp_xf"
1196   [(set (match_operand:HI 0 "register_operand" "=a")
1197         (unspec:HI
1198           [(compare:CCFP
1199              (match_operand:XF 1 "register_operand" "f")
1200              (match_operand:XF 2 "register_operand" "f"))]
1201           UNSPEC_FNSTSW))]
1202   "TARGET_80387"
1203   "* return output_fp_compare (insn, operands, 0, 0);"
1204   [(set_attr "type" "multi")
1205    (set_attr "unit" "i387")
1206    (set_attr "mode" "XF")])
1207
1208 (define_insn_and_split "*cmpfp_xf_cc"
1209   [(set (reg:CCFP FLAGS_REG)
1210         (compare:CCFP
1211           (match_operand:XF 1 "register_operand" "f")
1212           (match_operand:XF 2 "register_operand" "f")))
1213    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1214   "TARGET_80387
1215    && TARGET_SAHF && !TARGET_CMOVE"
1216   "#"
1217   "&& reload_completed"
1218   [(set (match_dup 0)
1219         (unspec:HI
1220           [(compare:CCFP (match_dup 1)(match_dup 2))]
1221         UNSPEC_FNSTSW))
1222    (set (reg:CC FLAGS_REG)
1223         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1224   ""
1225   [(set_attr "type" "multi")
1226    (set_attr "unit" "i387")
1227    (set_attr "mode" "XF")])
1228
1229 (define_insn "*cmpfp_<mode>"
1230   [(set (match_operand:HI 0 "register_operand" "=a")
1231         (unspec:HI
1232           [(compare:CCFP
1233              (match_operand:MODEF 1 "register_operand" "f")
1234              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1235           UNSPEC_FNSTSW))]
1236   "TARGET_80387"
1237   "* return output_fp_compare (insn, operands, 0, 0);"
1238   [(set_attr "type" "multi")
1239    (set_attr "unit" "i387")
1240    (set_attr "mode" "<MODE>")])
1241
1242 (define_insn_and_split "*cmpfp_<mode>_cc"
1243   [(set (reg:CCFP FLAGS_REG)
1244         (compare:CCFP
1245           (match_operand:MODEF 1 "register_operand" "f")
1246           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1247    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1248   "TARGET_80387
1249    && TARGET_SAHF && !TARGET_CMOVE"
1250   "#"
1251   "&& reload_completed"
1252   [(set (match_dup 0)
1253         (unspec:HI
1254           [(compare:CCFP (match_dup 1)(match_dup 2))]
1255         UNSPEC_FNSTSW))
1256    (set (reg:CC FLAGS_REG)
1257         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1258   ""
1259   [(set_attr "type" "multi")
1260    (set_attr "unit" "i387")
1261    (set_attr "mode" "<MODE>")])
1262
1263 (define_insn "*cmpfp_u"
1264   [(set (match_operand:HI 0 "register_operand" "=a")
1265         (unspec:HI
1266           [(compare:CCFPU
1267              (match_operand 1 "register_operand" "f")
1268              (match_operand 2 "register_operand" "f"))]
1269           UNSPEC_FNSTSW))]
1270   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1271    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1272   "* return output_fp_compare (insn, operands, 0, 1);"
1273   [(set_attr "type" "multi")
1274    (set_attr "unit" "i387")
1275    (set (attr "mode")
1276      (cond [(match_operand:SF 1 "" "")
1277               (const_string "SF")
1278             (match_operand:DF 1 "" "")
1279               (const_string "DF")
1280            ]
1281            (const_string "XF")))])
1282
1283 (define_insn_and_split "*cmpfp_u_cc"
1284   [(set (reg:CCFPU FLAGS_REG)
1285         (compare:CCFPU
1286           (match_operand 1 "register_operand" "f")
1287           (match_operand 2 "register_operand" "f")))
1288    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1289   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1290    && TARGET_SAHF && !TARGET_CMOVE
1291    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1292   "#"
1293   "&& reload_completed"
1294   [(set (match_dup 0)
1295         (unspec:HI
1296           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1297         UNSPEC_FNSTSW))
1298    (set (reg:CC FLAGS_REG)
1299         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1300   ""
1301   [(set_attr "type" "multi")
1302    (set_attr "unit" "i387")
1303    (set (attr "mode")
1304      (cond [(match_operand:SF 1 "" "")
1305               (const_string "SF")
1306             (match_operand:DF 1 "" "")
1307               (const_string "DF")
1308            ]
1309            (const_string "XF")))])
1310
1311 (define_insn "*cmpfp_<mode>"
1312   [(set (match_operand:HI 0 "register_operand" "=a")
1313         (unspec:HI
1314           [(compare:CCFP
1315              (match_operand 1 "register_operand" "f")
1316              (match_operator 3 "float_operator"
1317                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1318           UNSPEC_FNSTSW))]
1319   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1320    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1321    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1322   "* return output_fp_compare (insn, operands, 0, 0);"
1323   [(set_attr "type" "multi")
1324    (set_attr "unit" "i387")
1325    (set_attr "fp_int_src" "true")
1326    (set_attr "mode" "<MODE>")])
1327
1328 (define_insn_and_split "*cmpfp_<mode>_cc"
1329   [(set (reg:CCFP FLAGS_REG)
1330         (compare:CCFP
1331           (match_operand 1 "register_operand" "f")
1332           (match_operator 3 "float_operator"
1333             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1334    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1335   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1336    && TARGET_SAHF && !TARGET_CMOVE
1337    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1338    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1339   "#"
1340   "&& reload_completed"
1341   [(set (match_dup 0)
1342         (unspec:HI
1343           [(compare:CCFP
1344              (match_dup 1)
1345              (match_op_dup 3 [(match_dup 2)]))]
1346         UNSPEC_FNSTSW))
1347    (set (reg:CC FLAGS_REG)
1348         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1349   ""
1350   [(set_attr "type" "multi")
1351    (set_attr "unit" "i387")
1352    (set_attr "fp_int_src" "true")
1353    (set_attr "mode" "<MODE>")])
1354
1355 ;; FP compares, step 2
1356 ;; Move the fpsw to ax.
1357
1358 (define_insn "x86_fnstsw_1"
1359   [(set (match_operand:HI 0 "register_operand" "=a")
1360         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1361   "TARGET_80387"
1362   "fnstsw\t%0"
1363   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1364    (set_attr "mode" "SI")
1365    (set_attr "unit" "i387")])
1366
1367 ;; FP compares, step 3
1368 ;; Get ax into flags, general case.
1369
1370 (define_insn "x86_sahf_1"
1371   [(set (reg:CC FLAGS_REG)
1372         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1373                    UNSPEC_SAHF))]
1374   "TARGET_SAHF"
1375 {
1376 #ifdef HAVE_AS_IX86_SAHF
1377   return "sahf";
1378 #else
1379   return ASM_BYTE "0x9e";
1380 #endif
1381 }
1382   [(set_attr "length" "1")
1383    (set_attr "athlon_decode" "vector")
1384    (set_attr "amdfam10_decode" "direct")
1385    (set_attr "mode" "SI")])
1386
1387 ;; Pentium Pro can do steps 1 through 3 in one go.
1388 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1389 (define_insn "*cmpfp_i_mixed"
1390   [(set (reg:CCFP FLAGS_REG)
1391         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1392                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1393   "TARGET_MIX_SSE_I387
1394    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1395    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1396   "* return output_fp_compare (insn, operands, 1, 0);"
1397   [(set_attr "type" "fcmp,ssecomi")
1398    (set_attr "prefix" "orig,maybe_vex")
1399    (set (attr "mode")
1400      (if_then_else (match_operand:SF 1 "" "")
1401         (const_string "SF")
1402         (const_string "DF")))
1403    (set (attr "prefix_rep")
1404         (if_then_else (eq_attr "type" "ssecomi")
1405                       (const_string "0")
1406                       (const_string "*")))
1407    (set (attr "prefix_data16")
1408         (cond [(eq_attr "type" "fcmp")
1409                  (const_string "*")
1410                (eq_attr "mode" "DF")
1411                  (const_string "1")
1412               ]
1413               (const_string "0")))
1414    (set_attr "athlon_decode" "vector")
1415    (set_attr "amdfam10_decode" "direct")])
1416
1417 (define_insn "*cmpfp_i_sse"
1418   [(set (reg:CCFP FLAGS_REG)
1419         (compare:CCFP (match_operand 0 "register_operand" "x")
1420                       (match_operand 1 "nonimmediate_operand" "xm")))]
1421   "TARGET_SSE_MATH
1422    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1423    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1424   "* return output_fp_compare (insn, operands, 1, 0);"
1425   [(set_attr "type" "ssecomi")
1426    (set_attr "prefix" "maybe_vex")
1427    (set (attr "mode")
1428      (if_then_else (match_operand:SF 1 "" "")
1429         (const_string "SF")
1430         (const_string "DF")))
1431    (set_attr "prefix_rep" "0")
1432    (set (attr "prefix_data16")
1433         (if_then_else (eq_attr "mode" "DF")
1434                       (const_string "1")
1435                       (const_string "0")))
1436    (set_attr "athlon_decode" "vector")
1437    (set_attr "amdfam10_decode" "direct")])
1438
1439 (define_insn "*cmpfp_i_i387"
1440   [(set (reg:CCFP FLAGS_REG)
1441         (compare:CCFP (match_operand 0 "register_operand" "f")
1442                       (match_operand 1 "register_operand" "f")))]
1443   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1444    && TARGET_CMOVE
1445    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1446    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1447   "* return output_fp_compare (insn, operands, 1, 0);"
1448   [(set_attr "type" "fcmp")
1449    (set (attr "mode")
1450      (cond [(match_operand:SF 1 "" "")
1451               (const_string "SF")
1452             (match_operand:DF 1 "" "")
1453               (const_string "DF")
1454            ]
1455            (const_string "XF")))
1456    (set_attr "athlon_decode" "vector")
1457    (set_attr "amdfam10_decode" "direct")])
1458
1459 (define_insn "*cmpfp_iu_mixed"
1460   [(set (reg:CCFPU FLAGS_REG)
1461         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1462                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1463   "TARGET_MIX_SSE_I387
1464    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1465    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1466   "* return output_fp_compare (insn, operands, 1, 1);"
1467   [(set_attr "type" "fcmp,ssecomi")
1468    (set_attr "prefix" "orig,maybe_vex")
1469    (set (attr "mode")
1470      (if_then_else (match_operand:SF 1 "" "")
1471         (const_string "SF")
1472         (const_string "DF")))
1473    (set (attr "prefix_rep")
1474         (if_then_else (eq_attr "type" "ssecomi")
1475                       (const_string "0")
1476                       (const_string "*")))
1477    (set (attr "prefix_data16")
1478         (cond [(eq_attr "type" "fcmp")
1479                  (const_string "*")
1480                (eq_attr "mode" "DF")
1481                  (const_string "1")
1482               ]
1483               (const_string "0")))
1484    (set_attr "athlon_decode" "vector")
1485    (set_attr "amdfam10_decode" "direct")])
1486
1487 (define_insn "*cmpfp_iu_sse"
1488   [(set (reg:CCFPU FLAGS_REG)
1489         (compare:CCFPU (match_operand 0 "register_operand" "x")
1490                        (match_operand 1 "nonimmediate_operand" "xm")))]
1491   "TARGET_SSE_MATH
1492    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1493    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1494   "* return output_fp_compare (insn, operands, 1, 1);"
1495   [(set_attr "type" "ssecomi")
1496    (set_attr "prefix" "maybe_vex")
1497    (set (attr "mode")
1498      (if_then_else (match_operand:SF 1 "" "")
1499         (const_string "SF")
1500         (const_string "DF")))
1501    (set_attr "prefix_rep" "0")
1502    (set (attr "prefix_data16")
1503         (if_then_else (eq_attr "mode" "DF")
1504                       (const_string "1")
1505                       (const_string "0")))
1506    (set_attr "athlon_decode" "vector")
1507    (set_attr "amdfam10_decode" "direct")])
1508
1509 (define_insn "*cmpfp_iu_387"
1510   [(set (reg:CCFPU FLAGS_REG)
1511         (compare:CCFPU (match_operand 0 "register_operand" "f")
1512                        (match_operand 1 "register_operand" "f")))]
1513   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1514    && TARGET_CMOVE
1515    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1516    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1517   "* return output_fp_compare (insn, operands, 1, 1);"
1518   [(set_attr "type" "fcmp")
1519    (set (attr "mode")
1520      (cond [(match_operand:SF 1 "" "")
1521               (const_string "SF")
1522             (match_operand:DF 1 "" "")
1523               (const_string "DF")
1524            ]
1525            (const_string "XF")))
1526    (set_attr "athlon_decode" "vector")
1527    (set_attr "amdfam10_decode" "direct")])
1528 \f
1529 ;; Move instructions.
1530
1531 ;; General case of fullword move.
1532
1533 (define_expand "movsi"
1534   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1535         (match_operand:SI 1 "general_operand" ""))]
1536   ""
1537   "ix86_expand_move (SImode, operands); DONE;")
1538
1539 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1540 ;; general_operand.
1541 ;;
1542 ;; %%% We don't use a post-inc memory reference because x86 is not a
1543 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1544 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1545 ;; targets without our curiosities, and it is just as easy to represent
1546 ;; this differently.
1547
1548 (define_insn "*pushsi2"
1549   [(set (match_operand:SI 0 "push_operand" "=<")
1550         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1551   "!TARGET_64BIT"
1552   "push{l}\t%1"
1553   [(set_attr "type" "push")
1554    (set_attr "mode" "SI")])
1555
1556 ;; For 64BIT abi we always round up to 8 bytes.
1557 (define_insn "*pushsi2_rex64"
1558   [(set (match_operand:SI 0 "push_operand" "=X")
1559         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1560   "TARGET_64BIT"
1561   "push{q}\t%q1"
1562   [(set_attr "type" "push")
1563    (set_attr "mode" "SI")])
1564
1565 (define_insn "*pushsi2_prologue"
1566   [(set (match_operand:SI 0 "push_operand" "=<")
1567         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1568    (clobber (mem:BLK (scratch)))]
1569   "!TARGET_64BIT"
1570   "push{l}\t%1"
1571   [(set_attr "type" "push")
1572    (set_attr "mode" "SI")])
1573
1574 (define_insn "*popsi1_epilogue"
1575   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1576         (mem:SI (reg:SI SP_REG)))
1577    (set (reg:SI SP_REG)
1578         (plus:SI (reg:SI SP_REG) (const_int 4)))
1579    (clobber (mem:BLK (scratch)))]
1580   "!TARGET_64BIT"
1581   "pop{l}\t%0"
1582   [(set_attr "type" "pop")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "popsi1"
1586   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1587         (mem:SI (reg:SI SP_REG)))
1588    (set (reg:SI SP_REG)
1589         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1590   "!TARGET_64BIT"
1591   "pop{l}\t%0"
1592   [(set_attr "type" "pop")
1593    (set_attr "mode" "SI")])
1594
1595 (define_insn "*movsi_xor"
1596   [(set (match_operand:SI 0 "register_operand" "=r")
1597         (match_operand:SI 1 "const0_operand" ""))
1598    (clobber (reg:CC FLAGS_REG))]
1599   "reload_completed"
1600   "xor{l}\t%0, %0"
1601   [(set_attr "type" "alu1")
1602    (set_attr "mode" "SI")
1603    (set_attr "length_immediate" "0")])
1604
1605 (define_insn "*movsi_or"
1606   [(set (match_operand:SI 0 "register_operand" "=r")
1607         (match_operand:SI 1 "immediate_operand" "i"))
1608    (clobber (reg:CC FLAGS_REG))]
1609   "reload_completed
1610    && operands[1] == constm1_rtx"
1611 {
1612   operands[1] = constm1_rtx;
1613   return "or{l}\t{%1, %0|%0, %1}";
1614 }
1615   [(set_attr "type" "alu1")
1616    (set_attr "mode" "SI")
1617    (set_attr "length_immediate" "1")])
1618
1619 (define_insn "*movsi_1"
1620   [(set (match_operand:SI 0 "nonimmediate_operand"
1621                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1622         (match_operand:SI 1 "general_operand"
1623                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1624   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1625 {
1626   switch (get_attr_type (insn))
1627     {
1628     case TYPE_SSELOG1:
1629       if (get_attr_mode (insn) == MODE_TI)
1630         return "%vpxor\t%0, %d0";
1631       return "%vxorps\t%0, %d0";
1632
1633     case TYPE_SSEMOV:
1634       switch (get_attr_mode (insn))
1635         {
1636         case MODE_TI:
1637           return "%vmovdqa\t{%1, %0|%0, %1}";
1638         case MODE_V4SF:
1639           return "%vmovaps\t{%1, %0|%0, %1}";
1640         case MODE_SI:
1641           return "%vmovd\t{%1, %0|%0, %1}";
1642         case MODE_SF:
1643           return "%vmovss\t{%1, %0|%0, %1}";
1644         default:
1645           gcc_unreachable ();
1646         }
1647
1648     case TYPE_MMX:
1649       return "pxor\t%0, %0";
1650
1651     case TYPE_MMXMOV:
1652       if (get_attr_mode (insn) == MODE_DI)
1653         return "movq\t{%1, %0|%0, %1}";
1654       return "movd\t{%1, %0|%0, %1}";
1655
1656     case TYPE_LEA:
1657       return "lea{l}\t{%1, %0|%0, %1}";
1658
1659     default:
1660       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1661       return "mov{l}\t{%1, %0|%0, %1}";
1662     }
1663 }
1664   [(set (attr "type")
1665      (cond [(eq_attr "alternative" "2")
1666               (const_string "mmx")
1667             (eq_attr "alternative" "3,4,5")
1668               (const_string "mmxmov")
1669             (eq_attr "alternative" "6")
1670               (const_string "sselog1")
1671             (eq_attr "alternative" "7,8,9,10,11")
1672               (const_string "ssemov")
1673             (match_operand:DI 1 "pic_32bit_operand" "")
1674               (const_string "lea")
1675            ]
1676            (const_string "imov")))
1677    (set (attr "prefix")
1678      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1679        (const_string "orig")
1680        (const_string "maybe_vex")))
1681    (set (attr "prefix_data16")
1682      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1683        (const_string "1")
1684        (const_string "*")))
1685    (set (attr "mode")
1686      (cond [(eq_attr "alternative" "2,3")
1687               (const_string "DI")
1688             (eq_attr "alternative" "6,7")
1689               (if_then_else
1690                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1691                 (const_string "V4SF")
1692                 (const_string "TI"))
1693             (and (eq_attr "alternative" "8,9,10,11")
1694                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1695               (const_string "SF")
1696            ]
1697            (const_string "SI")))])
1698
1699 ;; Stores and loads of ax to arbitrary constant address.
1700 ;; We fake an second form of instruction to force reload to load address
1701 ;; into register when rax is not available
1702 (define_insn "*movabssi_1_rex64"
1703   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1704         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1705   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1706   "@
1707    movabs{l}\t{%1, %P0|%P0, %1}
1708    mov{l}\t{%1, %a0|%a0, %1}"
1709   [(set_attr "type" "imov")
1710    (set_attr "modrm" "0,*")
1711    (set_attr "length_address" "8,0")
1712    (set_attr "length_immediate" "0,*")
1713    (set_attr "memory" "store")
1714    (set_attr "mode" "SI")])
1715
1716 (define_insn "*movabssi_2_rex64"
1717   [(set (match_operand:SI 0 "register_operand" "=a,r")
1718         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1719   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1720   "@
1721    movabs{l}\t{%P1, %0|%0, %P1}
1722    mov{l}\t{%a1, %0|%0, %a1}"
1723   [(set_attr "type" "imov")
1724    (set_attr "modrm" "0,*")
1725    (set_attr "length_address" "8,0")
1726    (set_attr "length_immediate" "0")
1727    (set_attr "memory" "load")
1728    (set_attr "mode" "SI")])
1729
1730 (define_insn "*swapsi"
1731   [(set (match_operand:SI 0 "register_operand" "+r")
1732         (match_operand:SI 1 "register_operand" "+r"))
1733    (set (match_dup 1)
1734         (match_dup 0))]
1735   ""
1736   "xchg{l}\t%1, %0"
1737   [(set_attr "type" "imov")
1738    (set_attr "mode" "SI")
1739    (set_attr "pent_pair" "np")
1740    (set_attr "athlon_decode" "vector")
1741    (set_attr "amdfam10_decode" "double")])
1742
1743 (define_expand "movhi"
1744   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1745         (match_operand:HI 1 "general_operand" ""))]
1746   ""
1747   "ix86_expand_move (HImode, operands); DONE;")
1748
1749 (define_insn "*pushhi2"
1750   [(set (match_operand:HI 0 "push_operand" "=X")
1751         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1752   "!TARGET_64BIT"
1753   "push{l}\t%k1"
1754   [(set_attr "type" "push")
1755    (set_attr "mode" "SI")])
1756
1757 ;; For 64BIT abi we always round up to 8 bytes.
1758 (define_insn "*pushhi2_rex64"
1759   [(set (match_operand:HI 0 "push_operand" "=X")
1760         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1761   "TARGET_64BIT"
1762   "push{q}\t%q1"
1763   [(set_attr "type" "push")
1764    (set_attr "mode" "DI")])
1765
1766 (define_insn "*movhi_1"
1767   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1768         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1769   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1770 {
1771   switch (get_attr_type (insn))
1772     {
1773     case TYPE_IMOVX:
1774       /* movzwl is faster than movw on p2 due to partial word stalls,
1775          though not as fast as an aligned movl.  */
1776       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1777     default:
1778       if (get_attr_mode (insn) == MODE_SI)
1779         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1780       else
1781         return "mov{w}\t{%1, %0|%0, %1}";
1782     }
1783 }
1784   [(set (attr "type")
1785      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1786               (const_string "imov")
1787             (and (eq_attr "alternative" "0")
1788                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1789                           (const_int 0))
1790                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1791                           (const_int 0))))
1792               (const_string "imov")
1793             (and (eq_attr "alternative" "1,2")
1794                  (match_operand:HI 1 "aligned_operand" ""))
1795               (const_string "imov")
1796             (and (ne (symbol_ref "TARGET_MOVX")
1797                      (const_int 0))
1798                  (eq_attr "alternative" "0,2"))
1799               (const_string "imovx")
1800            ]
1801            (const_string "imov")))
1802     (set (attr "mode")
1803       (cond [(eq_attr "type" "imovx")
1804                (const_string "SI")
1805              (and (eq_attr "alternative" "1,2")
1806                   (match_operand:HI 1 "aligned_operand" ""))
1807                (const_string "SI")
1808              (and (eq_attr "alternative" "0")
1809                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1810                            (const_int 0))
1811                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1812                            (const_int 0))))
1813                (const_string "SI")
1814             ]
1815             (const_string "HI")))])
1816
1817 ;; Stores and loads of ax to arbitrary constant address.
1818 ;; We fake an second form of instruction to force reload to load address
1819 ;; into register when rax is not available
1820 (define_insn "*movabshi_1_rex64"
1821   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1822         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1823   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1824   "@
1825    movabs{w}\t{%1, %P0|%P0, %1}
1826    mov{w}\t{%1, %a0|%a0, %1}"
1827   [(set_attr "type" "imov")
1828    (set_attr "modrm" "0,*")
1829    (set_attr "length_address" "8,0")
1830    (set_attr "length_immediate" "0,*")
1831    (set_attr "memory" "store")
1832    (set_attr "mode" "HI")])
1833
1834 (define_insn "*movabshi_2_rex64"
1835   [(set (match_operand:HI 0 "register_operand" "=a,r")
1836         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1837   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1838   "@
1839    movabs{w}\t{%P1, %0|%0, %P1}
1840    mov{w}\t{%a1, %0|%0, %a1}"
1841   [(set_attr "type" "imov")
1842    (set_attr "modrm" "0,*")
1843    (set_attr "length_address" "8,0")
1844    (set_attr "length_immediate" "0")
1845    (set_attr "memory" "load")
1846    (set_attr "mode" "HI")])
1847
1848 (define_insn "*swaphi_1"
1849   [(set (match_operand:HI 0 "register_operand" "+r")
1850         (match_operand:HI 1 "register_operand" "+r"))
1851    (set (match_dup 1)
1852         (match_dup 0))]
1853   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1854   "xchg{l}\t%k1, %k0"
1855   [(set_attr "type" "imov")
1856    (set_attr "mode" "SI")
1857    (set_attr "pent_pair" "np")
1858    (set_attr "athlon_decode" "vector")
1859    (set_attr "amdfam10_decode" "double")])
1860
1861 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1862 (define_insn "*swaphi_2"
1863   [(set (match_operand:HI 0 "register_operand" "+r")
1864         (match_operand:HI 1 "register_operand" "+r"))
1865    (set (match_dup 1)
1866         (match_dup 0))]
1867   "TARGET_PARTIAL_REG_STALL"
1868   "xchg{w}\t%1, %0"
1869   [(set_attr "type" "imov")
1870    (set_attr "mode" "HI")
1871    (set_attr "pent_pair" "np")
1872    (set_attr "athlon_decode" "vector")])
1873
1874 (define_expand "movstricthi"
1875   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1876         (match_operand:HI 1 "general_operand" ""))]
1877   ""
1878 {
1879   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1880     FAIL;
1881   /* Don't generate memory->memory moves, go through a register */
1882   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1883     operands[1] = force_reg (HImode, operands[1]);
1884 })
1885
1886 (define_insn "*movstricthi_1"
1887   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1888         (match_operand:HI 1 "general_operand" "rn,m"))]
1889   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1890    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1891   "mov{w}\t{%1, %0|%0, %1}"
1892   [(set_attr "type" "imov")
1893    (set_attr "mode" "HI")])
1894
1895 (define_insn "*movstricthi_xor"
1896   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1897         (match_operand:HI 1 "const0_operand" ""))
1898    (clobber (reg:CC FLAGS_REG))]
1899   "reload_completed"
1900   "xor{w}\t%0, %0"
1901   [(set_attr "type" "alu1")
1902    (set_attr "mode" "HI")
1903    (set_attr "length_immediate" "0")])
1904
1905 (define_expand "movqi"
1906   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1907         (match_operand:QI 1 "general_operand" ""))]
1908   ""
1909   "ix86_expand_move (QImode, operands); DONE;")
1910
1911 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1912 ;; "push a byte".  But actually we use pushl, which has the effect
1913 ;; of rounding the amount pushed up to a word.
1914
1915 (define_insn "*pushqi2"
1916   [(set (match_operand:QI 0 "push_operand" "=X")
1917         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1918   "!TARGET_64BIT"
1919   "push{l}\t%k1"
1920   [(set_attr "type" "push")
1921    (set_attr "mode" "SI")])
1922
1923 ;; For 64BIT abi we always round up to 8 bytes.
1924 (define_insn "*pushqi2_rex64"
1925   [(set (match_operand:QI 0 "push_operand" "=X")
1926         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1927   "TARGET_64BIT"
1928   "push{q}\t%q1"
1929   [(set_attr "type" "push")
1930    (set_attr "mode" "DI")])
1931
1932 ;; Situation is quite tricky about when to choose full sized (SImode) move
1933 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1934 ;; partial register dependency machines (such as AMD Athlon), where QImode
1935 ;; moves issue extra dependency and for partial register stalls machines
1936 ;; that don't use QImode patterns (and QImode move cause stall on the next
1937 ;; instruction).
1938 ;;
1939 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1940 ;; register stall machines with, where we use QImode instructions, since
1941 ;; partial register stall can be caused there.  Then we use movzx.
1942 (define_insn "*movqi_1"
1943   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1944         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1945   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 {
1947   switch (get_attr_type (insn))
1948     {
1949     case TYPE_IMOVX:
1950       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1951       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1952     default:
1953       if (get_attr_mode (insn) == MODE_SI)
1954         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1955       else
1956         return "mov{b}\t{%1, %0|%0, %1}";
1957     }
1958 }
1959   [(set (attr "type")
1960      (cond [(and (eq_attr "alternative" "5")
1961                  (not (match_operand:QI 1 "aligned_operand" "")))
1962               (const_string "imovx")
1963             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1964               (const_string "imov")
1965             (and (eq_attr "alternative" "3")
1966                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1967                           (const_int 0))
1968                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1969                           (const_int 0))))
1970               (const_string "imov")
1971             (eq_attr "alternative" "3,5")
1972               (const_string "imovx")
1973             (and (ne (symbol_ref "TARGET_MOVX")
1974                      (const_int 0))
1975                  (eq_attr "alternative" "2"))
1976               (const_string "imovx")
1977            ]
1978            (const_string "imov")))
1979    (set (attr "mode")
1980       (cond [(eq_attr "alternative" "3,4,5")
1981                (const_string "SI")
1982              (eq_attr "alternative" "6")
1983                (const_string "QI")
1984              (eq_attr "type" "imovx")
1985                (const_string "SI")
1986              (and (eq_attr "type" "imov")
1987                   (and (eq_attr "alternative" "0,1")
1988                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1989                                 (const_int 0))
1990                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1991                                      (const_int 0))
1992                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1993                                      (const_int 0))))))
1994                (const_string "SI")
1995              ;; Avoid partial register stalls when not using QImode arithmetic
1996              (and (eq_attr "type" "imov")
1997                   (and (eq_attr "alternative" "0,1")
1998                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1999                                 (const_int 0))
2000                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2001                                 (const_int 0)))))
2002                (const_string "SI")
2003            ]
2004            (const_string "QI")))])
2005
2006 (define_insn "*swapqi_1"
2007   [(set (match_operand:QI 0 "register_operand" "+r")
2008         (match_operand:QI 1 "register_operand" "+r"))
2009    (set (match_dup 1)
2010         (match_dup 0))]
2011   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2012   "xchg{l}\t%k1, %k0"
2013   [(set_attr "type" "imov")
2014    (set_attr "mode" "SI")
2015    (set_attr "pent_pair" "np")
2016    (set_attr "athlon_decode" "vector")
2017    (set_attr "amdfam10_decode" "vector")])
2018
2019 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2020 (define_insn "*swapqi_2"
2021   [(set (match_operand:QI 0 "register_operand" "+q")
2022         (match_operand:QI 1 "register_operand" "+q"))
2023    (set (match_dup 1)
2024         (match_dup 0))]
2025   "TARGET_PARTIAL_REG_STALL"
2026   "xchg{b}\t%1, %0"
2027   [(set_attr "type" "imov")
2028    (set_attr "mode" "QI")
2029    (set_attr "pent_pair" "np")
2030    (set_attr "athlon_decode" "vector")])
2031
2032 (define_expand "movstrictqi"
2033   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2034         (match_operand:QI 1 "general_operand" ""))]
2035   ""
2036 {
2037   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2038     FAIL;
2039   /* Don't generate memory->memory moves, go through a register.  */
2040   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2041     operands[1] = force_reg (QImode, operands[1]);
2042 })
2043
2044 (define_insn "*movstrictqi_1"
2045   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2046         (match_operand:QI 1 "general_operand" "*qn,m"))]
2047   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2048    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2049   "mov{b}\t{%1, %0|%0, %1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "mode" "QI")])
2052
2053 (define_insn "*movstrictqi_xor"
2054   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2055         (match_operand:QI 1 "const0_operand" ""))
2056    (clobber (reg:CC FLAGS_REG))]
2057   "reload_completed"
2058   "xor{b}\t%0, %0"
2059   [(set_attr "type" "alu1")
2060    (set_attr "mode" "QI")
2061    (set_attr "length_immediate" "0")])
2062
2063 (define_insn "*movsi_extv_1"
2064   [(set (match_operand:SI 0 "register_operand" "=R")
2065         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2066                          (const_int 8)
2067                          (const_int 8)))]
2068   ""
2069   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2070   [(set_attr "type" "imovx")
2071    (set_attr "mode" "SI")])
2072
2073 (define_insn "*movhi_extv_1"
2074   [(set (match_operand:HI 0 "register_operand" "=R")
2075         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2076                          (const_int 8)
2077                          (const_int 8)))]
2078   ""
2079   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2080   [(set_attr "type" "imovx")
2081    (set_attr "mode" "SI")])
2082
2083 (define_insn "*movqi_extv_1"
2084   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2085         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2086                          (const_int 8)
2087                          (const_int 8)))]
2088   "!TARGET_64BIT"
2089 {
2090   switch (get_attr_type (insn))
2091     {
2092     case TYPE_IMOVX:
2093       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2094     default:
2095       return "mov{b}\t{%h1, %0|%0, %h1}";
2096     }
2097 }
2098   [(set (attr "type")
2099      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2100                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2101                              (ne (symbol_ref "TARGET_MOVX")
2102                                  (const_int 0))))
2103         (const_string "imovx")
2104         (const_string "imov")))
2105    (set (attr "mode")
2106      (if_then_else (eq_attr "type" "imovx")
2107         (const_string "SI")
2108         (const_string "QI")))])
2109
2110 (define_insn "*movqi_extv_1_rex64"
2111   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2112         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2113                          (const_int 8)
2114                          (const_int 8)))]
2115   "TARGET_64BIT"
2116 {
2117   switch (get_attr_type (insn))
2118     {
2119     case TYPE_IMOVX:
2120       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2121     default:
2122       return "mov{b}\t{%h1, %0|%0, %h1}";
2123     }
2124 }
2125   [(set (attr "type")
2126      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2127                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2128                              (ne (symbol_ref "TARGET_MOVX")
2129                                  (const_int 0))))
2130         (const_string "imovx")
2131         (const_string "imov")))
2132    (set (attr "mode")
2133      (if_then_else (eq_attr "type" "imovx")
2134         (const_string "SI")
2135         (const_string "QI")))])
2136
2137 ;; Stores and loads of ax to arbitrary constant address.
2138 ;; We fake an second form of instruction to force reload to load address
2139 ;; into register when rax is not available
2140 (define_insn "*movabsqi_1_rex64"
2141   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2142         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2143   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2144   "@
2145    movabs{b}\t{%1, %P0|%P0, %1}
2146    mov{b}\t{%1, %a0|%a0, %1}"
2147   [(set_attr "type" "imov")
2148    (set_attr "modrm" "0,*")
2149    (set_attr "length_address" "8,0")
2150    (set_attr "length_immediate" "0,*")
2151    (set_attr "memory" "store")
2152    (set_attr "mode" "QI")])
2153
2154 (define_insn "*movabsqi_2_rex64"
2155   [(set (match_operand:QI 0 "register_operand" "=a,r")
2156         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2157   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2158   "@
2159    movabs{b}\t{%P1, %0|%0, %P1}
2160    mov{b}\t{%a1, %0|%0, %a1}"
2161   [(set_attr "type" "imov")
2162    (set_attr "modrm" "0,*")
2163    (set_attr "length_address" "8,0")
2164    (set_attr "length_immediate" "0")
2165    (set_attr "memory" "load")
2166    (set_attr "mode" "QI")])
2167
2168 (define_insn "*movdi_extzv_1"
2169   [(set (match_operand:DI 0 "register_operand" "=R")
2170         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2171                          (const_int 8)
2172                          (const_int 8)))]
2173   "TARGET_64BIT"
2174   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2175   [(set_attr "type" "imovx")
2176    (set_attr "mode" "SI")])
2177
2178 (define_insn "*movsi_extzv_1"
2179   [(set (match_operand:SI 0 "register_operand" "=R")
2180         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2181                          (const_int 8)
2182                          (const_int 8)))]
2183   ""
2184   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2185   [(set_attr "type" "imovx")
2186    (set_attr "mode" "SI")])
2187
2188 (define_insn "*movqi_extzv_2"
2189   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2190         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2191                                     (const_int 8)
2192                                     (const_int 8)) 0))]
2193   "!TARGET_64BIT"
2194 {
2195   switch (get_attr_type (insn))
2196     {
2197     case TYPE_IMOVX:
2198       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2199     default:
2200       return "mov{b}\t{%h1, %0|%0, %h1}";
2201     }
2202 }
2203   [(set (attr "type")
2204      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2205                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2206                              (ne (symbol_ref "TARGET_MOVX")
2207                                  (const_int 0))))
2208         (const_string "imovx")
2209         (const_string "imov")))
2210    (set (attr "mode")
2211      (if_then_else (eq_attr "type" "imovx")
2212         (const_string "SI")
2213         (const_string "QI")))])
2214
2215 (define_insn "*movqi_extzv_2_rex64"
2216   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2217         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2218                                     (const_int 8)
2219                                     (const_int 8)) 0))]
2220   "TARGET_64BIT"
2221 {
2222   switch (get_attr_type (insn))
2223     {
2224     case TYPE_IMOVX:
2225       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2226     default:
2227       return "mov{b}\t{%h1, %0|%0, %h1}";
2228     }
2229 }
2230   [(set (attr "type")
2231      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2232                         (ne (symbol_ref "TARGET_MOVX")
2233                             (const_int 0)))
2234         (const_string "imovx")
2235         (const_string "imov")))
2236    (set (attr "mode")
2237      (if_then_else (eq_attr "type" "imovx")
2238         (const_string "SI")
2239         (const_string "QI")))])
2240
2241 (define_insn "movsi_insv_1"
2242   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2243                          (const_int 8)
2244                          (const_int 8))
2245         (match_operand:SI 1 "general_operand" "Qmn"))]
2246   "!TARGET_64BIT"
2247   "mov{b}\t{%b1, %h0|%h0, %b1}"
2248   [(set_attr "type" "imov")
2249    (set_attr "mode" "QI")])
2250
2251 (define_insn "*movsi_insv_1_rex64"
2252   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2253                          (const_int 8)
2254                          (const_int 8))
2255         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2256   "TARGET_64BIT"
2257   "mov{b}\t{%b1, %h0|%h0, %b1}"
2258   [(set_attr "type" "imov")
2259    (set_attr "mode" "QI")])
2260
2261 (define_insn "movdi_insv_1_rex64"
2262   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2263                          (const_int 8)
2264                          (const_int 8))
2265         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2266   "TARGET_64BIT"
2267   "mov{b}\t{%b1, %h0|%h0, %b1}"
2268   [(set_attr "type" "imov")
2269    (set_attr "mode" "QI")])
2270
2271 (define_insn "*movqi_insv_2"
2272   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2273                          (const_int 8)
2274                          (const_int 8))
2275         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2276                      (const_int 8)))]
2277   ""
2278   "mov{b}\t{%h1, %h0|%h0, %h1}"
2279   [(set_attr "type" "imov")
2280    (set_attr "mode" "QI")])
2281
2282 (define_expand "movdi"
2283   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2284         (match_operand:DI 1 "general_operand" ""))]
2285   ""
2286   "ix86_expand_move (DImode, operands); DONE;")
2287
2288 (define_insn "*pushdi"
2289   [(set (match_operand:DI 0 "push_operand" "=<")
2290         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2291   "!TARGET_64BIT"
2292   "#")
2293
2294 (define_insn "*pushdi2_rex64"
2295   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2296         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2297   "TARGET_64BIT"
2298   "@
2299    push{q}\t%1
2300    #"
2301   [(set_attr "type" "push,multi")
2302    (set_attr "mode" "DI")])
2303
2304 ;; Convert impossible pushes of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it.  In case this
2306 ;; fails, push sign extended lower part first and then overwrite
2307 ;; upper part by 32bit move.
2308 (define_peephole2
2309   [(match_scratch:DI 2 "r")
2310    (set (match_operand:DI 0 "push_operand" "")
2311         (match_operand:DI 1 "immediate_operand" ""))]
2312   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2313    && !x86_64_immediate_operand (operands[1], DImode)"
2314   [(set (match_dup 2) (match_dup 1))
2315    (set (match_dup 0) (match_dup 2))]
2316   "")
2317
2318 ;; We need to define this as both peepholer and splitter for case
2319 ;; peephole2 pass is not run.
2320 ;; "&& 1" is needed to keep it from matching the previous pattern.
2321 (define_peephole2
2322   [(set (match_operand:DI 0 "push_operand" "")
2323         (match_operand:DI 1 "immediate_operand" ""))]
2324   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2325    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2326   [(set (match_dup 0) (match_dup 1))
2327    (set (match_dup 2) (match_dup 3))]
2328   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2329    operands[1] = gen_lowpart (DImode, operands[2]);
2330    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2331                                                     GEN_INT (4)));
2332   ")
2333
2334 (define_split
2335   [(set (match_operand:DI 0 "push_operand" "")
2336         (match_operand:DI 1 "immediate_operand" ""))]
2337   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2338                     ? epilogue_completed : reload_completed)
2339    && !symbolic_operand (operands[1], DImode)
2340    && !x86_64_immediate_operand (operands[1], DImode)"
2341   [(set (match_dup 0) (match_dup 1))
2342    (set (match_dup 2) (match_dup 3))]
2343   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2344    operands[1] = gen_lowpart (DImode, operands[2]);
2345    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2346                                                     GEN_INT (4)));
2347   ")
2348
2349 (define_insn "*pushdi2_prologue_rex64"
2350   [(set (match_operand:DI 0 "push_operand" "=<")
2351         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2352    (clobber (mem:BLK (scratch)))]
2353   "TARGET_64BIT"
2354   "push{q}\t%1"
2355   [(set_attr "type" "push")
2356    (set_attr "mode" "DI")])
2357
2358 (define_insn "*popdi1_epilogue_rex64"
2359   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2360         (mem:DI (reg:DI SP_REG)))
2361    (set (reg:DI SP_REG)
2362         (plus:DI (reg:DI SP_REG) (const_int 8)))
2363    (clobber (mem:BLK (scratch)))]
2364   "TARGET_64BIT"
2365   "pop{q}\t%0"
2366   [(set_attr "type" "pop")
2367    (set_attr "mode" "DI")])
2368
2369 (define_insn "popdi1"
2370   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2371         (mem:DI (reg:DI SP_REG)))
2372    (set (reg:DI SP_REG)
2373         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2374   "TARGET_64BIT"
2375   "pop{q}\t%0"
2376   [(set_attr "type" "pop")
2377    (set_attr "mode" "DI")])
2378
2379 (define_insn "*movdi_xor_rex64"
2380   [(set (match_operand:DI 0 "register_operand" "=r")
2381         (match_operand:DI 1 "const0_operand" ""))
2382    (clobber (reg:CC FLAGS_REG))]
2383   "TARGET_64BIT
2384    && reload_completed"
2385   "xor{l}\t%k0, %k0";
2386   [(set_attr "type" "alu1")
2387    (set_attr "mode" "SI")
2388    (set_attr "length_immediate" "0")])
2389
2390 (define_insn "*movdi_or_rex64"
2391   [(set (match_operand:DI 0 "register_operand" "=r")
2392         (match_operand:DI 1 "const_int_operand" "i"))
2393    (clobber (reg:CC FLAGS_REG))]
2394   "TARGET_64BIT
2395    && reload_completed
2396    && operands[1] == constm1_rtx"
2397 {
2398   operands[1] = constm1_rtx;
2399   return "or{q}\t{%1, %0|%0, %1}";
2400 }
2401   [(set_attr "type" "alu1")
2402    (set_attr "mode" "DI")
2403    (set_attr "length_immediate" "1")])
2404
2405 (define_insn "*movdi_2"
2406   [(set (match_operand:DI 0 "nonimmediate_operand"
2407                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2408         (match_operand:DI 1 "general_operand"
2409                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2410   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2411   "@
2412    #
2413    #
2414    pxor\t%0, %0
2415    movq\t{%1, %0|%0, %1}
2416    movq\t{%1, %0|%0, %1}
2417    %vpxor\t%0, %d0
2418    %vmovq\t{%1, %0|%0, %1}
2419    %vmovdqa\t{%1, %0|%0, %1}
2420    %vmovq\t{%1, %0|%0, %1}
2421    xorps\t%0, %0
2422    movlps\t{%1, %0|%0, %1}
2423    movaps\t{%1, %0|%0, %1}
2424    movlps\t{%1, %0|%0, %1}"
2425   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2426    (set (attr "prefix")
2427      (if_then_else (eq_attr "alternative" "5,6,7,8")
2428        (const_string "vex")
2429        (const_string "orig")))
2430    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2431
2432 (define_split
2433   [(set (match_operand:DI 0 "push_operand" "")
2434         (match_operand:DI 1 "general_operand" ""))]
2435   "!TARGET_64BIT && reload_completed
2436    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2437   [(const_int 0)]
2438   "ix86_split_long_move (operands); DONE;")
2439
2440 ;; %%% This multiword shite has got to go.
2441 (define_split
2442   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2443         (match_operand:DI 1 "general_operand" ""))]
2444   "!TARGET_64BIT && reload_completed
2445    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2446    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2447   [(const_int 0)]
2448   "ix86_split_long_move (operands); DONE;")
2449
2450 (define_insn "*movdi_1_rex64"
2451   [(set (match_operand:DI 0 "nonimmediate_operand"
2452           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2453         (match_operand:DI 1 "general_operand"
2454           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2455   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456 {
2457   switch (get_attr_type (insn))
2458     {
2459     case TYPE_SSECVT:
2460       if (SSE_REG_P (operands[0]))
2461         return "movq2dq\t{%1, %0|%0, %1}";
2462       else
2463         return "movdq2q\t{%1, %0|%0, %1}";
2464
2465     case TYPE_SSEMOV:
2466       if (TARGET_AVX)
2467         {
2468           if (get_attr_mode (insn) == MODE_TI)
2469             return "vmovdqa\t{%1, %0|%0, %1}";
2470           else
2471             return "vmovq\t{%1, %0|%0, %1}";
2472         }
2473
2474       if (get_attr_mode (insn) == MODE_TI)
2475         return "movdqa\t{%1, %0|%0, %1}";
2476       /* FALLTHRU */
2477
2478     case TYPE_MMXMOV:
2479       /* Moves from and into integer register is done using movd
2480          opcode with REX prefix.  */
2481       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2482         return "movd\t{%1, %0|%0, %1}";
2483       return "movq\t{%1, %0|%0, %1}";
2484
2485     case TYPE_SSELOG1:
2486       return "%vpxor\t%0, %d0";
2487
2488     case TYPE_MMX:
2489       return "pxor\t%0, %0";
2490
2491     case TYPE_MULTI:
2492       return "#";
2493
2494     case TYPE_LEA:
2495       return "lea{q}\t{%a1, %0|%0, %a1}";
2496
2497     default:
2498       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2499       if (get_attr_mode (insn) == MODE_SI)
2500         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2501       else if (which_alternative == 2)
2502         return "movabs{q}\t{%1, %0|%0, %1}";
2503       else
2504         return "mov{q}\t{%1, %0|%0, %1}";
2505     }
2506 }
2507   [(set (attr "type")
2508      (cond [(eq_attr "alternative" "5")
2509               (const_string "mmx")
2510             (eq_attr "alternative" "6,7,8,9,10")
2511               (const_string "mmxmov")
2512             (eq_attr "alternative" "11")
2513               (const_string "sselog1")
2514             (eq_attr "alternative" "12,13,14,15,16")
2515               (const_string "ssemov")
2516             (eq_attr "alternative" "17,18")
2517               (const_string "ssecvt")
2518             (eq_attr "alternative" "4")
2519               (const_string "multi")
2520             (match_operand:DI 1 "pic_32bit_operand" "")
2521               (const_string "lea")
2522            ]
2523            (const_string "imov")))
2524    (set (attr "modrm")
2525      (if_then_else
2526        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2527          (const_string "0")
2528          (const_string "*")))
2529    (set (attr "length_immediate")
2530      (if_then_else
2531        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2532          (const_string "8")
2533          (const_string "*")))
2534    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2535    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2536    (set (attr "prefix")
2537      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2538        (const_string "maybe_vex")
2539        (const_string "orig")))
2540    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2541
2542 ;; Stores and loads of ax to arbitrary constant address.
2543 ;; We fake an second form of instruction to force reload to load address
2544 ;; into register when rax is not available
2545 (define_insn "*movabsdi_1_rex64"
2546   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2547         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2548   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2549   "@
2550    movabs{q}\t{%1, %P0|%P0, %1}
2551    mov{q}\t{%1, %a0|%a0, %1}"
2552   [(set_attr "type" "imov")
2553    (set_attr "modrm" "0,*")
2554    (set_attr "length_address" "8,0")
2555    (set_attr "length_immediate" "0,*")
2556    (set_attr "memory" "store")
2557    (set_attr "mode" "DI")])
2558
2559 (define_insn "*movabsdi_2_rex64"
2560   [(set (match_operand:DI 0 "register_operand" "=a,r")
2561         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2562   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2563   "@
2564    movabs{q}\t{%P1, %0|%0, %P1}
2565    mov{q}\t{%a1, %0|%0, %a1}"
2566   [(set_attr "type" "imov")
2567    (set_attr "modrm" "0,*")
2568    (set_attr "length_address" "8,0")
2569    (set_attr "length_immediate" "0")
2570    (set_attr "memory" "load")
2571    (set_attr "mode" "DI")])
2572
2573 ;; Convert impossible stores of immediate to existing instructions.
2574 ;; First try to get scratch register and go through it.  In case this
2575 ;; fails, move by 32bit parts.
2576 (define_peephole2
2577   [(match_scratch:DI 2 "r")
2578    (set (match_operand:DI 0 "memory_operand" "")
2579         (match_operand:DI 1 "immediate_operand" ""))]
2580   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2581    && !x86_64_immediate_operand (operands[1], DImode)"
2582   [(set (match_dup 2) (match_dup 1))
2583    (set (match_dup 0) (match_dup 2))]
2584   "")
2585
2586 ;; We need to define this as both peepholer and splitter for case
2587 ;; peephole2 pass is not run.
2588 ;; "&& 1" is needed to keep it from matching the previous pattern.
2589 (define_peephole2
2590   [(set (match_operand:DI 0 "memory_operand" "")
2591         (match_operand:DI 1 "immediate_operand" ""))]
2592   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2593    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2594   [(set (match_dup 2) (match_dup 3))
2595    (set (match_dup 4) (match_dup 5))]
2596   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2597
2598 (define_split
2599   [(set (match_operand:DI 0 "memory_operand" "")
2600         (match_operand:DI 1 "immediate_operand" ""))]
2601   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2602                     ? epilogue_completed : reload_completed)
2603    && !symbolic_operand (operands[1], DImode)
2604    && !x86_64_immediate_operand (operands[1], DImode)"
2605   [(set (match_dup 2) (match_dup 3))
2606    (set (match_dup 4) (match_dup 5))]
2607   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2608
2609 (define_insn "*swapdi_rex64"
2610   [(set (match_operand:DI 0 "register_operand" "+r")
2611         (match_operand:DI 1 "register_operand" "+r"))
2612    (set (match_dup 1)
2613         (match_dup 0))]
2614   "TARGET_64BIT"
2615   "xchg{q}\t%1, %0"
2616   [(set_attr "type" "imov")
2617    (set_attr "mode" "DI")
2618    (set_attr "pent_pair" "np")
2619    (set_attr "athlon_decode" "vector")
2620    (set_attr "amdfam10_decode" "double")])
2621
2622 (define_expand "movoi"
2623   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2624         (match_operand:OI 1 "general_operand" ""))]
2625   "TARGET_AVX"
2626   "ix86_expand_move (OImode, operands); DONE;")
2627
2628 (define_insn "*movoi_internal"
2629   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2630         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2631   "TARGET_AVX
2632    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2633 {
2634   switch (which_alternative)
2635     {
2636     case 0:
2637       return "vxorps\t%0, %0, %0";
2638     case 1:
2639     case 2:
2640       if (misaligned_operand (operands[0], OImode)
2641           || misaligned_operand (operands[1], OImode))
2642         return "vmovdqu\t{%1, %0|%0, %1}";
2643       else
2644         return "vmovdqa\t{%1, %0|%0, %1}";
2645     default:
2646       gcc_unreachable ();
2647     }
2648 }
2649   [(set_attr "type" "sselog1,ssemov,ssemov")
2650    (set_attr "prefix" "vex")
2651    (set_attr "mode" "OI")])
2652
2653 (define_expand "movti"
2654   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2655         (match_operand:TI 1 "nonimmediate_operand" ""))]
2656   "TARGET_SSE || TARGET_64BIT"
2657 {
2658   if (TARGET_64BIT)
2659     ix86_expand_move (TImode, operands);
2660   else if (push_operand (operands[0], TImode))
2661     ix86_expand_push (TImode, operands[1]);
2662   else
2663     ix86_expand_vector_move (TImode, operands);
2664   DONE;
2665 })
2666
2667 (define_insn "*movti_internal"
2668   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2669         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2670   "TARGET_SSE && !TARGET_64BIT
2671    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2672 {
2673   switch (which_alternative)
2674     {
2675     case 0:
2676       if (get_attr_mode (insn) == MODE_V4SF)
2677         return "%vxorps\t%0, %d0";
2678       else
2679         return "%vpxor\t%0, %d0";
2680     case 1:
2681     case 2:
2682       /* TDmode values are passed as TImode on the stack.  Moving them
2683          to stack may result in unaligned memory access.  */
2684       if (misaligned_operand (operands[0], TImode)
2685           || misaligned_operand (operands[1], TImode))
2686         {
2687           if (get_attr_mode (insn) == MODE_V4SF)
2688             return "%vmovups\t{%1, %0|%0, %1}";
2689          else
2690            return "%vmovdqu\t{%1, %0|%0, %1}";
2691         }
2692       else
2693         {
2694           if (get_attr_mode (insn) == MODE_V4SF)
2695             return "%vmovaps\t{%1, %0|%0, %1}";
2696          else
2697            return "%vmovdqa\t{%1, %0|%0, %1}";
2698         }
2699     default:
2700       gcc_unreachable ();
2701     }
2702 }
2703   [(set_attr "type" "sselog1,ssemov,ssemov")
2704    (set_attr "prefix" "maybe_vex")
2705    (set (attr "mode")
2706         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2707                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2708                  (const_string "V4SF")
2709                (and (eq_attr "alternative" "2")
2710                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2711                         (const_int 0)))
2712                  (const_string "V4SF")]
2713               (const_string "TI")))])
2714
2715 (define_insn "*movti_rex64"
2716   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2717         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2718   "TARGET_64BIT
2719    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2720 {
2721   switch (which_alternative)
2722     {
2723     case 0:
2724     case 1:
2725       return "#";
2726     case 2:
2727       if (get_attr_mode (insn) == MODE_V4SF)
2728         return "%vxorps\t%0, %d0";
2729       else
2730         return "%vpxor\t%0, %d0";
2731     case 3:
2732     case 4:
2733       /* TDmode values are passed as TImode on the stack.  Moving them
2734          to stack may result in unaligned memory access.  */
2735       if (misaligned_operand (operands[0], TImode)
2736           || misaligned_operand (operands[1], TImode))
2737         {
2738           if (get_attr_mode (insn) == MODE_V4SF)
2739             return "%vmovups\t{%1, %0|%0, %1}";
2740          else
2741            return "%vmovdqu\t{%1, %0|%0, %1}";
2742         }
2743       else
2744         {
2745           if (get_attr_mode (insn) == MODE_V4SF)
2746             return "%vmovaps\t{%1, %0|%0, %1}";
2747          else
2748            return "%vmovdqa\t{%1, %0|%0, %1}";
2749         }
2750     default:
2751       gcc_unreachable ();
2752     }
2753 }
2754   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2755    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2756    (set (attr "mode")
2757         (cond [(eq_attr "alternative" "2,3")
2758                  (if_then_else
2759                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2760                        (const_int 0))
2761                    (const_string "V4SF")
2762                    (const_string "TI"))
2763                (eq_attr "alternative" "4")
2764                  (if_then_else
2765                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2766                             (const_int 0))
2767                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2768                             (const_int 0)))
2769                    (const_string "V4SF")
2770                    (const_string "TI"))]
2771                (const_string "DI")))])
2772
2773 (define_split
2774   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2775         (match_operand:TI 1 "general_operand" ""))]
2776   "reload_completed && !SSE_REG_P (operands[0])
2777    && !SSE_REG_P (operands[1])"
2778   [(const_int 0)]
2779   "ix86_split_long_move (operands); DONE;")
2780
2781 ;; This expands to what emit_move_complex would generate if we didn't
2782 ;; have a movti pattern.  Having this avoids problems with reload on
2783 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2784 ;; to have around all the time.
2785 (define_expand "movcdi"
2786   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2787         (match_operand:CDI 1 "general_operand" ""))]
2788   ""
2789 {
2790   if (push_operand (operands[0], CDImode))
2791     emit_move_complex_push (CDImode, operands[0], operands[1]);
2792   else
2793     emit_move_complex_parts (operands[0], operands[1]);
2794   DONE;
2795 })
2796
2797 (define_expand "movsf"
2798   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2799         (match_operand:SF 1 "general_operand" ""))]
2800   ""
2801   "ix86_expand_move (SFmode, operands); DONE;")
2802
2803 (define_insn "*pushsf"
2804   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2805         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2806   "!TARGET_64BIT"
2807 {
2808   /* Anything else should be already split before reg-stack.  */
2809   gcc_assert (which_alternative == 1);
2810   return "push{l}\t%1";
2811 }
2812   [(set_attr "type" "multi,push,multi")
2813    (set_attr "unit" "i387,*,*")
2814    (set_attr "mode" "SF,SI,SF")])
2815
2816 (define_insn "*pushsf_rex64"
2817   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2818         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2819   "TARGET_64BIT"
2820 {
2821   /* Anything else should be already split before reg-stack.  */
2822   gcc_assert (which_alternative == 1);
2823   return "push{q}\t%q1";
2824 }
2825   [(set_attr "type" "multi,push,multi")
2826    (set_attr "unit" "i387,*,*")
2827    (set_attr "mode" "SF,DI,SF")])
2828
2829 (define_split
2830   [(set (match_operand:SF 0 "push_operand" "")
2831         (match_operand:SF 1 "memory_operand" ""))]
2832   "reload_completed
2833    && MEM_P (operands[1])
2834    && (operands[2] = find_constant_src (insn))"
2835   [(set (match_dup 0)
2836         (match_dup 2))])
2837
2838 ;; %%% Kill this when call knows how to work this out.
2839 (define_split
2840   [(set (match_operand:SF 0 "push_operand" "")
2841         (match_operand:SF 1 "any_fp_register_operand" ""))]
2842   "!TARGET_64BIT"
2843   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2844    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2845
2846 (define_split
2847   [(set (match_operand:SF 0 "push_operand" "")
2848         (match_operand:SF 1 "any_fp_register_operand" ""))]
2849   "TARGET_64BIT"
2850   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2851    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2852
2853 (define_insn "*movsf_1"
2854   [(set (match_operand:SF 0 "nonimmediate_operand"
2855           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2856         (match_operand:SF 1 "general_operand"
2857           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2858   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2859    && (reload_in_progress || reload_completed
2860        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2861        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2862            && standard_80387_constant_p (operands[1]))
2863        || GET_CODE (operands[1]) != CONST_DOUBLE
2864        || memory_operand (operands[0], SFmode))"
2865 {
2866   switch (which_alternative)
2867     {
2868     case 0:
2869     case 1:
2870       return output_387_reg_move (insn, operands);
2871
2872     case 2:
2873       return standard_80387_constant_opcode (operands[1]);
2874
2875     case 3:
2876     case 4:
2877       return "mov{l}\t{%1, %0|%0, %1}";
2878     case 5:
2879       if (get_attr_mode (insn) == MODE_TI)
2880         return "%vpxor\t%0, %d0";
2881       else
2882         return "%vxorps\t%0, %d0";
2883     case 6:
2884       if (get_attr_mode (insn) == MODE_V4SF)
2885         return "%vmovaps\t{%1, %0|%0, %1}";
2886       else
2887         return "%vmovss\t{%1, %d0|%d0, %1}";
2888     case 7:
2889       if (TARGET_AVX)
2890         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2891                                    : "vmovss\t{%1, %0|%0, %1}";
2892       else
2893         return "movss\t{%1, %0|%0, %1}";
2894     case 8:
2895       return "%vmovss\t{%1, %0|%0, %1}";
2896
2897     case 9: case 10: case 14: case 15:
2898       return "movd\t{%1, %0|%0, %1}";
2899     case 12: case 13:
2900       return "%vmovd\t{%1, %0|%0, %1}";
2901
2902     case 11:
2903       return "movq\t{%1, %0|%0, %1}";
2904
2905     default:
2906       gcc_unreachable ();
2907     }
2908 }
2909   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2910    (set (attr "prefix")
2911      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2912        (const_string "maybe_vex")
2913        (const_string "orig")))
2914    (set (attr "mode")
2915         (cond [(eq_attr "alternative" "3,4,9,10")
2916                  (const_string "SI")
2917                (eq_attr "alternative" "5")
2918                  (if_then_else
2919                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2920                                  (const_int 0))
2921                              (ne (symbol_ref "TARGET_SSE2")
2922                                  (const_int 0)))
2923                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2924                             (const_int 0)))
2925                    (const_string "TI")
2926                    (const_string "V4SF"))
2927                /* For architectures resolving dependencies on
2928                   whole SSE registers use APS move to break dependency
2929                   chains, otherwise use short move to avoid extra work.
2930
2931                   Do the same for architectures resolving dependencies on
2932                   the parts.  While in DF mode it is better to always handle
2933                   just register parts, the SF mode is different due to lack
2934                   of instructions to load just part of the register.  It is
2935                   better to maintain the whole registers in single format
2936                   to avoid problems on using packed logical operations.  */
2937                (eq_attr "alternative" "6")
2938                  (if_then_else
2939                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2940                             (const_int 0))
2941                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2942                             (const_int 0)))
2943                    (const_string "V4SF")
2944                    (const_string "SF"))
2945                (eq_attr "alternative" "11")
2946                  (const_string "DI")]
2947                (const_string "SF")))])
2948
2949 (define_insn "*swapsf"
2950   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2951         (match_operand:SF 1 "fp_register_operand" "+f"))
2952    (set (match_dup 1)
2953         (match_dup 0))]
2954   "reload_completed || TARGET_80387"
2955 {
2956   if (STACK_TOP_P (operands[0]))
2957     return "fxch\t%1";
2958   else
2959     return "fxch\t%0";
2960 }
2961   [(set_attr "type" "fxch")
2962    (set_attr "mode" "SF")])
2963
2964 (define_expand "movdf"
2965   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2966         (match_operand:DF 1 "general_operand" ""))]
2967   ""
2968   "ix86_expand_move (DFmode, operands); DONE;")
2969
2970 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2971 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2972 ;; On the average, pushdf using integers can be still shorter.  Allow this
2973 ;; pattern for optimize_size too.
2974
2975 (define_insn "*pushdf_nointeger"
2976   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2977         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2978   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2979 {
2980   /* This insn should be already split before reg-stack.  */
2981   gcc_unreachable ();
2982 }
2983   [(set_attr "type" "multi")
2984    (set_attr "unit" "i387,*,*,*")
2985    (set_attr "mode" "DF,SI,SI,DF")])
2986
2987 (define_insn "*pushdf_integer"
2988   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2989         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2990   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2991 {
2992   /* This insn should be already split before reg-stack.  */
2993   gcc_unreachable ();
2994 }
2995   [(set_attr "type" "multi")
2996    (set_attr "unit" "i387,*,*")
2997    (set_attr "mode" "DF,SI,DF")])
2998
2999 ;; %%% Kill this when call knows how to work this out.
3000 (define_split
3001   [(set (match_operand:DF 0 "push_operand" "")
3002         (match_operand:DF 1 "any_fp_register_operand" ""))]
3003   "reload_completed"
3004   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3005    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3006   "")
3007
3008 (define_split
3009   [(set (match_operand:DF 0 "push_operand" "")
3010         (match_operand:DF 1 "general_operand" ""))]
3011   "reload_completed"
3012   [(const_int 0)]
3013   "ix86_split_long_move (operands); DONE;")
3014
3015 ;; Moving is usually shorter when only FP registers are used. This separate
3016 ;; movdf pattern avoids the use of integer registers for FP operations
3017 ;; when optimizing for size.
3018
3019 (define_insn "*movdf_nointeger"
3020   [(set (match_operand:DF 0 "nonimmediate_operand"
3021                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3022         (match_operand:DF 1 "general_operand"
3023                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3024   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3025    && ((optimize_function_for_size_p (cfun)
3026        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3027    && (reload_in_progress || reload_completed
3028        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3029        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3030            && optimize_function_for_size_p (cfun)
3031            && !memory_operand (operands[0], DFmode)
3032            && standard_80387_constant_p (operands[1]))
3033        || GET_CODE (operands[1]) != CONST_DOUBLE
3034        || ((optimize_function_for_size_p (cfun)
3035             || !TARGET_MEMORY_MISMATCH_STALL
3036             || reload_in_progress || reload_completed)
3037            && memory_operand (operands[0], DFmode)))"
3038 {
3039   switch (which_alternative)
3040     {
3041     case 0:
3042     case 1:
3043       return output_387_reg_move (insn, operands);
3044
3045     case 2:
3046       return standard_80387_constant_opcode (operands[1]);
3047
3048     case 3:
3049     case 4:
3050       return "#";
3051     case 5:
3052       switch (get_attr_mode (insn))
3053         {
3054         case MODE_V4SF:
3055           return "%vxorps\t%0, %d0";
3056         case MODE_V2DF:
3057           return "%vxorpd\t%0, %d0";
3058         case MODE_TI:
3059           return "%vpxor\t%0, %d0";
3060         default:
3061           gcc_unreachable ();
3062         }
3063     case 6:
3064     case 7:
3065     case 8:
3066       switch (get_attr_mode (insn))
3067         {
3068         case MODE_V4SF:
3069           return "%vmovaps\t{%1, %0|%0, %1}";
3070         case MODE_V2DF:
3071           return "%vmovapd\t{%1, %0|%0, %1}";
3072         case MODE_TI:
3073           return "%vmovdqa\t{%1, %0|%0, %1}";
3074         case MODE_DI:
3075           return "%vmovq\t{%1, %0|%0, %1}";
3076         case MODE_DF:
3077           if (TARGET_AVX)
3078             {
3079               if (REG_P (operands[0]) && REG_P (operands[1]))
3080                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3081               else
3082                 return "vmovsd\t{%1, %0|%0, %1}";
3083             }
3084           else
3085             return "movsd\t{%1, %0|%0, %1}";
3086         case MODE_V1DF:
3087           if (TARGET_AVX)
3088             {
3089               if (REG_P (operands[0]))
3090                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3091               else
3092                 return "vmovlpd\t{%1, %0|%0, %1}";
3093             }
3094           else
3095             return "movlpd\t{%1, %0|%0, %1}";
3096         case MODE_V2SF:
3097           if (TARGET_AVX)
3098             {
3099               if (REG_P (operands[0]))
3100                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3101               else
3102                 return "vmovlps\t{%1, %0|%0, %1}";
3103             }
3104           else
3105             return "movlps\t{%1, %0|%0, %1}";
3106         default:
3107           gcc_unreachable ();
3108         }
3109
3110     default:
3111       gcc_unreachable ();
3112     }
3113 }
3114   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3115    (set (attr "prefix")
3116      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3117        (const_string "orig")
3118        (const_string "maybe_vex")))
3119    (set (attr "prefix_data16")
3120      (if_then_else (eq_attr "mode" "V1DF")
3121        (const_string "1")
3122        (const_string "*")))
3123    (set (attr "mode")
3124         (cond [(eq_attr "alternative" "0,1,2")
3125                  (const_string "DF")
3126                (eq_attr "alternative" "3,4")
3127                  (const_string "SI")
3128
3129                /* For SSE1, we have many fewer alternatives.  */
3130                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3131                  (cond [(eq_attr "alternative" "5,6")
3132                           (const_string "V4SF")
3133                        ]
3134                    (const_string "V2SF"))
3135
3136                /* xorps is one byte shorter.  */
3137                (eq_attr "alternative" "5")
3138                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3139                             (const_int 0))
3140                           (const_string "V4SF")
3141                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3142                             (const_int 0))
3143                           (const_string "TI")
3144                        ]
3145                        (const_string "V2DF"))
3146
3147                /* For architectures resolving dependencies on
3148                   whole SSE registers use APD move to break dependency
3149                   chains, otherwise use short move to avoid extra work.
3150
3151                   movaps encodes one byte shorter.  */
3152                (eq_attr "alternative" "6")
3153                  (cond
3154                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3155                         (const_int 0))
3156                       (const_string "V4SF")
3157                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3158                         (const_int 0))
3159                       (const_string "V2DF")
3160                    ]
3161                    (const_string "DF"))
3162                /* For architectures resolving dependencies on register
3163                   parts we may avoid extra work to zero out upper part
3164                   of register.  */
3165                (eq_attr "alternative" "7")
3166                  (if_then_else
3167                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3168                        (const_int 0))
3169                    (const_string "V1DF")
3170                    (const_string "DF"))
3171               ]
3172               (const_string "DF")))])
3173
3174 (define_insn "*movdf_integer_rex64"
3175   [(set (match_operand:DF 0 "nonimmediate_operand"
3176                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3177         (match_operand:DF 1 "general_operand"
3178                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3179   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3180    && (reload_in_progress || reload_completed
3181        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3182        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3183            && optimize_function_for_size_p (cfun)
3184            && standard_80387_constant_p (operands[1]))
3185        || GET_CODE (operands[1]) != CONST_DOUBLE
3186        || memory_operand (operands[0], DFmode))"
3187 {
3188   switch (which_alternative)
3189     {
3190     case 0:
3191     case 1:
3192       return output_387_reg_move (insn, operands);
3193
3194     case 2:
3195       return standard_80387_constant_opcode (operands[1]);
3196
3197     case 3:
3198     case 4:
3199       return "#";
3200
3201     case 5:
3202       switch (get_attr_mode (insn))
3203         {
3204         case MODE_V4SF:
3205           return "%vxorps\t%0, %d0";
3206         case MODE_V2DF:
3207           return "%vxorpd\t%0, %d0";
3208         case MODE_TI:
3209           return "%vpxor\t%0, %d0";
3210         default:
3211           gcc_unreachable ();
3212         }
3213     case 6:
3214     case 7:
3215     case 8:
3216       switch (get_attr_mode (insn))
3217         {
3218         case MODE_V4SF:
3219           return "%vmovaps\t{%1, %0|%0, %1}";
3220         case MODE_V2DF:
3221           return "%vmovapd\t{%1, %0|%0, %1}";
3222         case MODE_TI:
3223           return "%vmovdqa\t{%1, %0|%0, %1}";
3224         case MODE_DI:
3225           return "%vmovq\t{%1, %0|%0, %1}";
3226         case MODE_DF:
3227           if (TARGET_AVX)
3228             {
3229               if (REG_P (operands[0]) && REG_P (operands[1]))
3230                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3231               else
3232                 return "vmovsd\t{%1, %0|%0, %1}";
3233             }
3234           else
3235             return "movsd\t{%1, %0|%0, %1}";
3236         case MODE_V1DF:
3237           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3238         case MODE_V2SF:
3239           return "%vmovlps\t{%1, %d0|%d0, %1}";
3240         default:
3241           gcc_unreachable ();
3242         }
3243
3244     case 9:
3245     case 10:
3246     return "%vmovd\t{%1, %0|%0, %1}";
3247
3248     default:
3249       gcc_unreachable();
3250     }
3251 }
3252   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3253    (set (attr "prefix")
3254      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3255        (const_string "orig")
3256        (const_string "maybe_vex")))
3257    (set (attr "prefix_data16")
3258      (if_then_else (eq_attr "mode" "V1DF")
3259        (const_string "1")
3260        (const_string "*")))
3261    (set (attr "mode")
3262         (cond [(eq_attr "alternative" "0,1,2")
3263                  (const_string "DF")
3264                (eq_attr "alternative" "3,4,9,10")
3265                  (const_string "DI")
3266
3267                /* For SSE1, we have many fewer alternatives.  */
3268                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3269                  (cond [(eq_attr "alternative" "5,6")
3270                           (const_string "V4SF")
3271                        ]
3272                    (const_string "V2SF"))
3273
3274                /* xorps is one byte shorter.  */
3275                (eq_attr "alternative" "5")
3276                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3277                             (const_int 0))
3278                           (const_string "V4SF")
3279                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3280                             (const_int 0))
3281                           (const_string "TI")
3282                        ]
3283                        (const_string "V2DF"))
3284
3285                /* For architectures resolving dependencies on
3286                   whole SSE registers use APD move to break dependency
3287                   chains, otherwise use short move to avoid extra work.
3288
3289                   movaps encodes one byte shorter.  */
3290                (eq_attr "alternative" "6")
3291                  (cond
3292                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3293                         (const_int 0))
3294                       (const_string "V4SF")
3295                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3296                         (const_int 0))
3297                       (const_string "V2DF")
3298                    ]
3299                    (const_string "DF"))
3300                /* For architectures resolving dependencies on register
3301                   parts we may avoid extra work to zero out upper part
3302                   of register.  */
3303                (eq_attr "alternative" "7")
3304                  (if_then_else
3305                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3306                        (const_int 0))
3307                    (const_string "V1DF")
3308                    (const_string "DF"))
3309               ]
3310               (const_string "DF")))])
3311
3312 (define_insn "*movdf_integer"
3313   [(set (match_operand:DF 0 "nonimmediate_operand"
3314                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3315         (match_operand:DF 1 "general_operand"
3316                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3317   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3318    && optimize_function_for_speed_p (cfun)
3319    && TARGET_INTEGER_DFMODE_MOVES
3320    && (reload_in_progress || reload_completed
3321        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3322        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3323            && optimize_function_for_size_p (cfun)
3324            && standard_80387_constant_p (operands[1]))
3325        || GET_CODE (operands[1]) != CONST_DOUBLE
3326        || memory_operand (operands[0], DFmode))"
3327 {
3328   switch (which_alternative)
3329     {
3330     case 0:
3331     case 1:
3332       return output_387_reg_move (insn, operands);
3333
3334     case 2:
3335       return standard_80387_constant_opcode (operands[1]);
3336
3337     case 3:
3338     case 4:
3339       return "#";
3340
3341     case 5:
3342       switch (get_attr_mode (insn))
3343         {
3344         case MODE_V4SF:
3345           return "xorps\t%0, %0";
3346         case MODE_V2DF:
3347           return "xorpd\t%0, %0";
3348         case MODE_TI:
3349           return "pxor\t%0, %0";
3350         default:
3351           gcc_unreachable ();
3352         }
3353     case 6:
3354     case 7:
3355     case 8:
3356       switch (get_attr_mode (insn))
3357         {
3358         case MODE_V4SF:
3359           return "movaps\t{%1, %0|%0, %1}";
3360         case MODE_V2DF:
3361           return "movapd\t{%1, %0|%0, %1}";
3362         case MODE_TI:
3363           return "movdqa\t{%1, %0|%0, %1}";
3364         case MODE_DI:
3365           return "movq\t{%1, %0|%0, %1}";
3366         case MODE_DF:
3367           return "movsd\t{%1, %0|%0, %1}";
3368         case MODE_V1DF:
3369           return "movlpd\t{%1, %0|%0, %1}";
3370         case MODE_V2SF:
3371           return "movlps\t{%1, %0|%0, %1}";
3372         default:
3373           gcc_unreachable ();
3374         }
3375
3376     default:
3377       gcc_unreachable();
3378     }
3379 }
3380   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3381    (set (attr "prefix_data16")
3382      (if_then_else (eq_attr "mode" "V1DF")
3383        (const_string "1")
3384        (const_string "*")))
3385    (set (attr "mode")
3386         (cond [(eq_attr "alternative" "0,1,2")
3387                  (const_string "DF")
3388                (eq_attr "alternative" "3,4")
3389                  (const_string "SI")
3390
3391                /* For SSE1, we have many fewer alternatives.  */
3392                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3393                  (cond [(eq_attr "alternative" "5,6")
3394                           (const_string "V4SF")
3395                        ]
3396                    (const_string "V2SF"))
3397
3398                /* xorps is one byte shorter.  */
3399                (eq_attr "alternative" "5")
3400                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3401                             (const_int 0))
3402                           (const_string "V4SF")
3403                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3404                             (const_int 0))
3405                           (const_string "TI")
3406                        ]
3407                        (const_string "V2DF"))
3408
3409                /* For architectures resolving dependencies on
3410                   whole SSE registers use APD move to break dependency
3411                   chains, otherwise use short move to avoid extra work.
3412
3413                   movaps encodes one byte shorter.  */
3414                (eq_attr "alternative" "6")
3415                  (cond
3416                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3417                         (const_int 0))
3418                       (const_string "V4SF")
3419                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3420                         (const_int 0))
3421                       (const_string "V2DF")
3422                    ]
3423                    (const_string "DF"))
3424                /* For architectures resolving dependencies on register
3425                   parts we may avoid extra work to zero out upper part
3426                   of register.  */
3427                (eq_attr "alternative" "7")
3428                  (if_then_else
3429                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3430                        (const_int 0))
3431                    (const_string "V1DF")
3432                    (const_string "DF"))
3433               ]
3434               (const_string "DF")))])
3435
3436 (define_split
3437   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3438         (match_operand:DF 1 "general_operand" ""))]
3439   "reload_completed
3440    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3441    && ! (ANY_FP_REG_P (operands[0]) ||
3442          (GET_CODE (operands[0]) == SUBREG
3443           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3444    && ! (ANY_FP_REG_P (operands[1]) ||
3445          (GET_CODE (operands[1]) == SUBREG
3446           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3447   [(const_int 0)]
3448   "ix86_split_long_move (operands); DONE;")
3449
3450 (define_insn "*swapdf"
3451   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3452         (match_operand:DF 1 "fp_register_operand" "+f"))
3453    (set (match_dup 1)
3454         (match_dup 0))]
3455   "reload_completed || TARGET_80387"
3456 {
3457   if (STACK_TOP_P (operands[0]))
3458     return "fxch\t%1";
3459   else
3460     return "fxch\t%0";
3461 }
3462   [(set_attr "type" "fxch")
3463    (set_attr "mode" "DF")])
3464
3465 (define_expand "movxf"
3466   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3467         (match_operand:XF 1 "general_operand" ""))]
3468   ""
3469   "ix86_expand_move (XFmode, operands); DONE;")
3470
3471 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3472 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3473 ;; Pushing using integer instructions is longer except for constants
3474 ;; and direct memory references.
3475 ;; (assuming that any given constant is pushed only once, but this ought to be
3476 ;;  handled elsewhere).
3477
3478 (define_insn "*pushxf_nointeger"
3479   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3480         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3481   "optimize_function_for_size_p (cfun)"
3482 {
3483   /* This insn should be already split before reg-stack.  */
3484   gcc_unreachable ();
3485 }
3486   [(set_attr "type" "multi")
3487    (set_attr "unit" "i387,*,*")
3488    (set_attr "mode" "XF,SI,SI")])
3489
3490 (define_insn "*pushxf_integer"
3491   [(set (match_operand:XF 0 "push_operand" "=<,<")
3492         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3493   "optimize_function_for_speed_p (cfun)"
3494 {
3495   /* This insn should be already split before reg-stack.  */
3496   gcc_unreachable ();
3497 }
3498   [(set_attr "type" "multi")
3499    (set_attr "unit" "i387,*")
3500    (set_attr "mode" "XF,SI")])
3501
3502 (define_split
3503   [(set (match_operand 0 "push_operand" "")
3504         (match_operand 1 "general_operand" ""))]
3505   "reload_completed
3506    && (GET_MODE (operands[0]) == XFmode
3507        || GET_MODE (operands[0]) == DFmode)
3508    && !ANY_FP_REG_P (operands[1])"
3509   [(const_int 0)]
3510   "ix86_split_long_move (operands); DONE;")
3511
3512 (define_split
3513   [(set (match_operand:XF 0 "push_operand" "")
3514         (match_operand:XF 1 "any_fp_register_operand" ""))]
3515   ""
3516   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3517    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3518   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3519
3520 ;; Do not use integer registers when optimizing for size
3521 (define_insn "*movxf_nointeger"
3522   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3523         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3524   "optimize_function_for_size_p (cfun)
3525    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3526    && (reload_in_progress || reload_completed
3527        || standard_80387_constant_p (operands[1])
3528        || GET_CODE (operands[1]) != CONST_DOUBLE
3529        || memory_operand (operands[0], XFmode))"
3530 {
3531   switch (which_alternative)
3532     {
3533     case 0:
3534     case 1:
3535       return output_387_reg_move (insn, operands);
3536
3537     case 2:
3538       return standard_80387_constant_opcode (operands[1]);
3539
3540     case 3: case 4:
3541       return "#";
3542     default:
3543       gcc_unreachable ();
3544     }
3545 }
3546   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3547    (set_attr "mode" "XF,XF,XF,SI,SI")])
3548
3549 (define_insn "*movxf_integer"
3550   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3551         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3552   "optimize_function_for_speed_p (cfun)
3553    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3554    && (reload_in_progress || reload_completed
3555        || GET_CODE (operands[1]) != CONST_DOUBLE
3556        || memory_operand (operands[0], XFmode))"
3557 {
3558   switch (which_alternative)
3559     {
3560     case 0:
3561     case 1:
3562       return output_387_reg_move (insn, operands);
3563
3564     case 2:
3565       return standard_80387_constant_opcode (operands[1]);
3566
3567     case 3: case 4:
3568       return "#";
3569
3570     default:
3571       gcc_unreachable ();
3572     }
3573 }
3574   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3575    (set_attr "mode" "XF,XF,XF,SI,SI")])
3576
3577 (define_expand "movtf"
3578   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3579         (match_operand:TF 1 "nonimmediate_operand" ""))]
3580   "TARGET_SSE2"
3581 {
3582   ix86_expand_move (TFmode, operands);
3583   DONE;
3584 })
3585
3586 (define_insn "*movtf_internal"
3587   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3588         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3589   "TARGET_SSE2
3590    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3591 {
3592   switch (which_alternative)
3593     {
3594     case 0:
3595     case 1:
3596       if (get_attr_mode (insn) == MODE_V4SF)
3597         return "%vmovaps\t{%1, %0|%0, %1}";
3598       else
3599         return "%vmovdqa\t{%1, %0|%0, %1}";
3600     case 2:
3601       if (get_attr_mode (insn) == MODE_V4SF)
3602         return "%vxorps\t%0, %d0";
3603       else
3604         return "%vpxor\t%0, %d0";
3605     case 3:
3606     case 4:
3607         return "#";
3608     default:
3609       gcc_unreachable ();
3610     }
3611 }
3612   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3613    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3614    (set (attr "mode")
3615         (cond [(eq_attr "alternative" "0,2")
3616                  (if_then_else
3617                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3618                        (const_int 0))
3619                    (const_string "V4SF")
3620                    (const_string "TI"))
3621                (eq_attr "alternative" "1")
3622                  (if_then_else
3623                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3624                             (const_int 0))
3625                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3626                             (const_int 0)))
3627                    (const_string "V4SF")
3628                    (const_string "TI"))]
3629                (const_string "DI")))])
3630
3631 (define_insn "*pushtf_sse"
3632   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3633         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3634   "TARGET_SSE2"
3635 {
3636   /* This insn should be already split before reg-stack.  */
3637   gcc_unreachable ();
3638 }
3639   [(set_attr "type" "multi")
3640    (set_attr "unit" "sse,*,*")
3641    (set_attr "mode" "TF,SI,SI")])
3642
3643 (define_split
3644   [(set (match_operand:TF 0 "push_operand" "")
3645         (match_operand:TF 1 "general_operand" ""))]
3646   "TARGET_SSE2 && reload_completed
3647    && !SSE_REG_P (operands[1])"
3648   [(const_int 0)]
3649   "ix86_split_long_move (operands); DONE;")
3650
3651 (define_split
3652   [(set (match_operand:TF 0 "push_operand" "")
3653         (match_operand:TF 1 "any_fp_register_operand" ""))]
3654   "TARGET_SSE2"
3655   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3656    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3657   "")
3658
3659 (define_split
3660   [(set (match_operand 0 "nonimmediate_operand" "")
3661         (match_operand 1 "general_operand" ""))]
3662   "reload_completed
3663    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3664    && GET_MODE (operands[0]) == XFmode
3665    && ! (ANY_FP_REG_P (operands[0]) ||
3666          (GET_CODE (operands[0]) == SUBREG
3667           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3668    && ! (ANY_FP_REG_P (operands[1]) ||
3669          (GET_CODE (operands[1]) == SUBREG
3670           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3671   [(const_int 0)]
3672   "ix86_split_long_move (operands); DONE;")
3673
3674 (define_split
3675   [(set (match_operand 0 "register_operand" "")
3676         (match_operand 1 "memory_operand" ""))]
3677   "reload_completed
3678    && MEM_P (operands[1])
3679    && (GET_MODE (operands[0]) == TFmode
3680        || GET_MODE (operands[0]) == XFmode
3681        || GET_MODE (operands[0]) == SFmode
3682        || GET_MODE (operands[0]) == DFmode)
3683    && (operands[2] = find_constant_src (insn))"
3684   [(set (match_dup 0) (match_dup 2))]
3685 {
3686   rtx c = operands[2];
3687   rtx r = operands[0];
3688
3689   if (GET_CODE (r) == SUBREG)
3690     r = SUBREG_REG (r);
3691
3692   if (SSE_REG_P (r))
3693     {
3694       if (!standard_sse_constant_p (c))
3695         FAIL;
3696     }
3697   else if (FP_REG_P (r))
3698     {
3699       if (!standard_80387_constant_p (c))
3700         FAIL;
3701     }
3702   else if (MMX_REG_P (r))
3703     FAIL;
3704 })
3705
3706 (define_split
3707   [(set (match_operand 0 "register_operand" "")
3708         (float_extend (match_operand 1 "memory_operand" "")))]
3709   "reload_completed
3710    && MEM_P (operands[1])
3711    && (GET_MODE (operands[0]) == TFmode
3712        || GET_MODE (operands[0]) == XFmode
3713        || GET_MODE (operands[0]) == SFmode
3714        || GET_MODE (operands[0]) == DFmode)
3715    && (operands[2] = find_constant_src (insn))"
3716   [(set (match_dup 0) (match_dup 2))]
3717 {
3718   rtx c = operands[2];
3719   rtx r = operands[0];
3720
3721   if (GET_CODE (r) == SUBREG)
3722     r = SUBREG_REG (r);
3723
3724   if (SSE_REG_P (r))
3725     {
3726       if (!standard_sse_constant_p (c))
3727         FAIL;
3728     }
3729   else if (FP_REG_P (r))
3730     {
3731       if (!standard_80387_constant_p (c))
3732         FAIL;
3733     }
3734   else if (MMX_REG_P (r))
3735     FAIL;
3736 })
3737
3738 (define_insn "swapxf"
3739   [(set (match_operand:XF 0 "register_operand" "+f")
3740         (match_operand:XF 1 "register_operand" "+f"))
3741    (set (match_dup 1)
3742         (match_dup 0))]
3743   "TARGET_80387"
3744 {
3745   if (STACK_TOP_P (operands[0]))
3746     return "fxch\t%1";
3747   else
3748     return "fxch\t%0";
3749 }
3750   [(set_attr "type" "fxch")
3751    (set_attr "mode" "XF")])
3752
3753 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3754 (define_split
3755   [(set (match_operand:X87MODEF 0 "register_operand" "")
3756         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3757   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3758    && (standard_80387_constant_p (operands[1]) == 8
3759        || standard_80387_constant_p (operands[1]) == 9)"
3760   [(set (match_dup 0)(match_dup 1))
3761    (set (match_dup 0)
3762         (neg:X87MODEF (match_dup 0)))]
3763 {
3764   REAL_VALUE_TYPE r;
3765
3766   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3767   if (real_isnegzero (&r))
3768     operands[1] = CONST0_RTX (<MODE>mode);
3769   else
3770     operands[1] = CONST1_RTX (<MODE>mode);
3771 })
3772
3773 (define_split
3774   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3775         (match_operand:TF 1 "general_operand" ""))]
3776   "reload_completed
3777    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3778   [(const_int 0)]
3779   "ix86_split_long_move (operands); DONE;")
3780 \f
3781 ;; Zero extension instructions
3782
3783 (define_expand "zero_extendhisi2"
3784   [(set (match_operand:SI 0 "register_operand" "")
3785      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3786   ""
3787 {
3788   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3789     {
3790       operands[1] = force_reg (HImode, operands[1]);
3791       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3792       DONE;
3793     }
3794 })
3795
3796 (define_insn "zero_extendhisi2_and"
3797   [(set (match_operand:SI 0 "register_operand" "=r")
3798      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3799    (clobber (reg:CC FLAGS_REG))]
3800   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3801   "#"
3802   [(set_attr "type" "alu1")
3803    (set_attr "mode" "SI")])
3804
3805 (define_split
3806   [(set (match_operand:SI 0 "register_operand" "")
3807         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3808    (clobber (reg:CC FLAGS_REG))]
3809   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3810    && optimize_function_for_speed_p (cfun)"
3811   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3812               (clobber (reg:CC FLAGS_REG))])]
3813   "")
3814
3815 (define_insn "*zero_extendhisi2_movzwl"
3816   [(set (match_operand:SI 0 "register_operand" "=r")
3817      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3818   "!TARGET_ZERO_EXTEND_WITH_AND
3819    || optimize_function_for_size_p (cfun)"
3820   "movz{wl|x}\t{%1, %0|%0, %1}"
3821   [(set_attr "type" "imovx")
3822    (set_attr "mode" "SI")])
3823
3824 (define_expand "zero_extendqihi2"
3825   [(parallel
3826     [(set (match_operand:HI 0 "register_operand" "")
3827        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3828      (clobber (reg:CC FLAGS_REG))])]
3829   ""
3830   "")
3831
3832 (define_insn "*zero_extendqihi2_and"
3833   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3834      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3835    (clobber (reg:CC FLAGS_REG))]
3836   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3837   "#"
3838   [(set_attr "type" "alu1")
3839    (set_attr "mode" "HI")])
3840
3841 (define_insn "*zero_extendqihi2_movzbw_and"
3842   [(set (match_operand:HI 0 "register_operand" "=r,r")
3843      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3844    (clobber (reg:CC FLAGS_REG))]
3845   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3846   "#"
3847   [(set_attr "type" "imovx,alu1")
3848    (set_attr "mode" "HI")])
3849
3850 ; zero extend to SImode here to avoid partial register stalls
3851 (define_insn "*zero_extendqihi2_movzbl"
3852   [(set (match_operand:HI 0 "register_operand" "=r")
3853      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3854   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3855    && reload_completed"
3856   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3857   [(set_attr "type" "imovx")
3858    (set_attr "mode" "SI")])
3859
3860 ;; For the movzbw case strip only the clobber
3861 (define_split
3862   [(set (match_operand:HI 0 "register_operand" "")
3863         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3864    (clobber (reg:CC FLAGS_REG))]
3865   "reload_completed
3866    && (!TARGET_ZERO_EXTEND_WITH_AND
3867        || optimize_function_for_size_p (cfun))
3868    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3869   [(set (match_operand:HI 0 "register_operand" "")
3870         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3871
3872 ;; When source and destination does not overlap, clear destination
3873 ;; first and then do the movb
3874 (define_split
3875   [(set (match_operand:HI 0 "register_operand" "")
3876         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3877    (clobber (reg:CC FLAGS_REG))]
3878   "reload_completed
3879    && ANY_QI_REG_P (operands[0])
3880    && (TARGET_ZERO_EXTEND_WITH_AND
3881        && optimize_function_for_speed_p (cfun))
3882    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3883   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3884 {
3885   operands[2] = gen_lowpart (QImode, operands[0]);
3886   ix86_expand_clear (operands[0]);
3887 })
3888
3889 ;; Rest is handled by single and.
3890 (define_split
3891   [(set (match_operand:HI 0 "register_operand" "")
3892         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3893    (clobber (reg:CC FLAGS_REG))]
3894   "reload_completed
3895    && true_regnum (operands[0]) == true_regnum (operands[1])"
3896   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3897               (clobber (reg:CC FLAGS_REG))])]
3898   "")
3899
3900 (define_expand "zero_extendqisi2"
3901   [(parallel
3902     [(set (match_operand:SI 0 "register_operand" "")
3903        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3904      (clobber (reg:CC FLAGS_REG))])]
3905   ""
3906   "")
3907
3908 (define_insn "*zero_extendqisi2_and"
3909   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3910      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3911    (clobber (reg:CC FLAGS_REG))]
3912   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3913   "#"
3914   [(set_attr "type" "alu1")
3915    (set_attr "mode" "SI")])
3916
3917 (define_insn "*zero_extendqisi2_movzbl_and"
3918   [(set (match_operand:SI 0 "register_operand" "=r,r")
3919      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3920    (clobber (reg:CC FLAGS_REG))]
3921   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3922   "#"
3923   [(set_attr "type" "imovx,alu1")
3924    (set_attr "mode" "SI")])
3925
3926 (define_insn "*zero_extendqisi2_movzbl"
3927   [(set (match_operand:SI 0 "register_operand" "=r")
3928      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3929   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3930    && reload_completed"
3931   "movz{bl|x}\t{%1, %0|%0, %1}"
3932   [(set_attr "type" "imovx")
3933    (set_attr "mode" "SI")])
3934
3935 ;; For the movzbl case strip only the clobber
3936 (define_split
3937   [(set (match_operand:SI 0 "register_operand" "")
3938         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3939    (clobber (reg:CC FLAGS_REG))]
3940   "reload_completed
3941    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3942    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3943   [(set (match_dup 0)
3944         (zero_extend:SI (match_dup 1)))])
3945
3946 ;; When source and destination does not overlap, clear destination
3947 ;; first and then do the movb
3948 (define_split
3949   [(set (match_operand:SI 0 "register_operand" "")
3950         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3951    (clobber (reg:CC FLAGS_REG))]
3952   "reload_completed
3953    && ANY_QI_REG_P (operands[0])
3954    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3955    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3956    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3957   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3958 {
3959   operands[2] = gen_lowpart (QImode, operands[0]);
3960   ix86_expand_clear (operands[0]);
3961 })
3962
3963 ;; Rest is handled by single and.
3964 (define_split
3965   [(set (match_operand:SI 0 "register_operand" "")
3966         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3967    (clobber (reg:CC FLAGS_REG))]
3968   "reload_completed
3969    && true_regnum (operands[0]) == true_regnum (operands[1])"
3970   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3971               (clobber (reg:CC FLAGS_REG))])]
3972   "")
3973
3974 ;; %%% Kill me once multi-word ops are sane.
3975 (define_expand "zero_extendsidi2"
3976   [(set (match_operand:DI 0 "register_operand" "")
3977      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3978   ""
3979 {
3980   if (!TARGET_64BIT)
3981     {
3982       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3983       DONE;
3984     }
3985 })
3986
3987 (define_insn "zero_extendsidi2_32"
3988   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3989         (zero_extend:DI
3990          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3991    (clobber (reg:CC FLAGS_REG))]
3992   "!TARGET_64BIT"
3993   "@
3994    #
3995    #
3996    #
3997    movd\t{%1, %0|%0, %1}
3998    movd\t{%1, %0|%0, %1}
3999    %vmovd\t{%1, %0|%0, %1}
4000    %vmovd\t{%1, %0|%0, %1}"
4001   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4002    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4003    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4004
4005 (define_insn "zero_extendsidi2_rex64"
4006   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4007      (zero_extend:DI
4008        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4009   "TARGET_64BIT"
4010   "@
4011    mov\t{%k1, %k0|%k0, %k1}
4012    #
4013    movd\t{%1, %0|%0, %1}
4014    movd\t{%1, %0|%0, %1}
4015    %vmovd\t{%1, %0|%0, %1}
4016    %vmovd\t{%1, %0|%0, %1}"
4017   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4018    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4019    (set_attr "prefix_0f" "0,*,*,*,*,*")
4020    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4021
4022 (define_split
4023   [(set (match_operand:DI 0 "memory_operand" "")
4024      (zero_extend:DI (match_dup 0)))]
4025   "TARGET_64BIT"
4026   [(set (match_dup 4) (const_int 0))]
4027   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4028
4029 (define_split
4030   [(set (match_operand:DI 0 "register_operand" "")
4031         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4032    (clobber (reg:CC FLAGS_REG))]
4033   "!TARGET_64BIT && reload_completed
4034    && true_regnum (operands[0]) == true_regnum (operands[1])"
4035   [(set (match_dup 4) (const_int 0))]
4036   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4037
4038 (define_split
4039   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4040         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4041    (clobber (reg:CC FLAGS_REG))]
4042   "!TARGET_64BIT && reload_completed
4043    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4044   [(set (match_dup 3) (match_dup 1))
4045    (set (match_dup 4) (const_int 0))]
4046   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4047
4048 (define_insn "zero_extendhidi2"
4049   [(set (match_operand:DI 0 "register_operand" "=r")
4050      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4051   "TARGET_64BIT"
4052   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4053   [(set_attr "type" "imovx")
4054    (set_attr "mode" "SI")])
4055
4056 (define_insn "zero_extendqidi2"
4057   [(set (match_operand:DI 0 "register_operand" "=r")
4058      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4059   "TARGET_64BIT"
4060   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4061   [(set_attr "type" "imovx")
4062    (set_attr "mode" "SI")])
4063 \f
4064 ;; Sign extension instructions
4065
4066 (define_expand "extendsidi2"
4067   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4068                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4069               (clobber (reg:CC FLAGS_REG))
4070               (clobber (match_scratch:SI 2 ""))])]
4071   ""
4072 {
4073   if (TARGET_64BIT)
4074     {
4075       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4076       DONE;
4077     }
4078 })
4079
4080 (define_insn "*extendsidi2_1"
4081   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4082         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4083    (clobber (reg:CC FLAGS_REG))
4084    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4085   "!TARGET_64BIT"
4086   "#")
4087
4088 (define_insn "extendsidi2_rex64"
4089   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4090         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4091   "TARGET_64BIT"
4092   "@
4093    {cltq|cdqe}
4094    movs{lq|x}\t{%1, %0|%0, %1}"
4095   [(set_attr "type" "imovx")
4096    (set_attr "mode" "DI")
4097    (set_attr "prefix_0f" "0")
4098    (set_attr "modrm" "0,1")])
4099
4100 (define_insn "extendhidi2"
4101   [(set (match_operand:DI 0 "register_operand" "=r")
4102         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4103   "TARGET_64BIT"
4104   "movs{wq|x}\t{%1, %0|%0, %1}"
4105   [(set_attr "type" "imovx")
4106    (set_attr "mode" "DI")])
4107
4108 (define_insn "extendqidi2"
4109   [(set (match_operand:DI 0 "register_operand" "=r")
4110         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4111   "TARGET_64BIT"
4112   "movs{bq|x}\t{%1, %0|%0, %1}"
4113    [(set_attr "type" "imovx")
4114     (set_attr "mode" "DI")])
4115
4116 ;; Extend to memory case when source register does die.
4117 (define_split
4118   [(set (match_operand:DI 0 "memory_operand" "")
4119         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4120    (clobber (reg:CC FLAGS_REG))
4121    (clobber (match_operand:SI 2 "register_operand" ""))]
4122   "(reload_completed
4123     && dead_or_set_p (insn, operands[1])
4124     && !reg_mentioned_p (operands[1], operands[0]))"
4125   [(set (match_dup 3) (match_dup 1))
4126    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4127               (clobber (reg:CC FLAGS_REG))])
4128    (set (match_dup 4) (match_dup 1))]
4129   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4130
4131 ;; Extend to memory case when source register does not die.
4132 (define_split
4133   [(set (match_operand:DI 0 "memory_operand" "")
4134         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4135    (clobber (reg:CC FLAGS_REG))
4136    (clobber (match_operand:SI 2 "register_operand" ""))]
4137   "reload_completed"
4138   [(const_int 0)]
4139 {
4140   split_di (&operands[0], 1, &operands[3], &operands[4]);
4141
4142   emit_move_insn (operands[3], operands[1]);
4143
4144   /* Generate a cltd if possible and doing so it profitable.  */
4145   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4146       && true_regnum (operands[1]) == AX_REG
4147       && true_regnum (operands[2]) == DX_REG)
4148     {
4149       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4150     }
4151   else
4152     {
4153       emit_move_insn (operands[2], operands[1]);
4154       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4155     }
4156   emit_move_insn (operands[4], operands[2]);
4157   DONE;
4158 })
4159
4160 ;; Extend to register case.  Optimize case where source and destination
4161 ;; registers match and cases where we can use cltd.
4162 (define_split
4163   [(set (match_operand:DI 0 "register_operand" "")
4164         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4165    (clobber (reg:CC FLAGS_REG))
4166    (clobber (match_scratch:SI 2 ""))]
4167   "reload_completed"
4168   [(const_int 0)]
4169 {
4170   split_di (&operands[0], 1, &operands[3], &operands[4]);
4171
4172   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4173     emit_move_insn (operands[3], operands[1]);
4174
4175   /* Generate a cltd if possible and doing so it profitable.  */
4176   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4177       && true_regnum (operands[3]) == AX_REG)
4178     {
4179       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4180       DONE;
4181     }
4182
4183   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4184     emit_move_insn (operands[4], operands[1]);
4185
4186   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4187   DONE;
4188 })
4189
4190 (define_insn "extendhisi2"
4191   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4192         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4193   ""
4194 {
4195   switch (get_attr_prefix_0f (insn))
4196     {
4197     case 0:
4198       return "{cwtl|cwde}";
4199     default:
4200       return "movs{wl|x}\t{%1, %0|%0, %1}";
4201     }
4202 }
4203   [(set_attr "type" "imovx")
4204    (set_attr "mode" "SI")
4205    (set (attr "prefix_0f")
4206      ;; movsx is short decodable while cwtl is vector decoded.
4207      (if_then_else (and (eq_attr "cpu" "!k6")
4208                         (eq_attr "alternative" "0"))
4209         (const_string "0")
4210         (const_string "1")))
4211    (set (attr "modrm")
4212      (if_then_else (eq_attr "prefix_0f" "0")
4213         (const_string "0")
4214         (const_string "1")))])
4215
4216 (define_insn "*extendhisi2_zext"
4217   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4218         (zero_extend:DI
4219           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4220   "TARGET_64BIT"
4221 {
4222   switch (get_attr_prefix_0f (insn))
4223     {
4224     case 0:
4225       return "{cwtl|cwde}";
4226     default:
4227       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4228     }
4229 }
4230   [(set_attr "type" "imovx")
4231    (set_attr "mode" "SI")
4232    (set (attr "prefix_0f")
4233      ;; movsx is short decodable while cwtl is vector decoded.
4234      (if_then_else (and (eq_attr "cpu" "!k6")
4235                         (eq_attr "alternative" "0"))
4236         (const_string "0")
4237         (const_string "1")))
4238    (set (attr "modrm")
4239      (if_then_else (eq_attr "prefix_0f" "0")
4240         (const_string "0")
4241         (const_string "1")))])
4242
4243 (define_insn "extendqihi2"
4244   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4245         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4246   ""
4247 {
4248   switch (get_attr_prefix_0f (insn))
4249     {
4250     case 0:
4251       return "{cbtw|cbw}";
4252     default:
4253       return "movs{bw|x}\t{%1, %0|%0, %1}";
4254     }
4255 }
4256   [(set_attr "type" "imovx")
4257    (set_attr "mode" "HI")
4258    (set (attr "prefix_0f")
4259      ;; movsx is short decodable while cwtl is vector decoded.
4260      (if_then_else (and (eq_attr "cpu" "!k6")
4261                         (eq_attr "alternative" "0"))
4262         (const_string "0")
4263         (const_string "1")))
4264    (set (attr "modrm")
4265      (if_then_else (eq_attr "prefix_0f" "0")
4266         (const_string "0")
4267         (const_string "1")))])
4268
4269 (define_insn "extendqisi2"
4270   [(set (match_operand:SI 0 "register_operand" "=r")
4271         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4272   ""
4273   "movs{bl|x}\t{%1, %0|%0, %1}"
4274    [(set_attr "type" "imovx")
4275     (set_attr "mode" "SI")])
4276
4277 (define_insn "*extendqisi2_zext"
4278   [(set (match_operand:DI 0 "register_operand" "=r")
4279         (zero_extend:DI
4280           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4281   "TARGET_64BIT"
4282   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4283    [(set_attr "type" "imovx")
4284     (set_attr "mode" "SI")])
4285 \f
4286 ;; Conversions between float and double.
4287
4288 ;; These are all no-ops in the model used for the 80387.  So just
4289 ;; emit moves.
4290
4291 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4292 (define_insn "*dummy_extendsfdf2"
4293   [(set (match_operand:DF 0 "push_operand" "=<")
4294         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4295   "0"
4296   "#")
4297
4298 (define_split
4299   [(set (match_operand:DF 0 "push_operand" "")
4300         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4301   ""
4302   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4303    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4304
4305 (define_insn "*dummy_extendsfxf2"
4306   [(set (match_operand:XF 0 "push_operand" "=<")
4307         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4308   "0"
4309   "#")
4310
4311 (define_split
4312   [(set (match_operand:XF 0 "push_operand" "")
4313         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4314   ""
4315   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4316    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4317   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4318
4319 (define_split
4320   [(set (match_operand:XF 0 "push_operand" "")
4321         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4322   ""
4323   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4324    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4325   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4326
4327 (define_expand "extendsfdf2"
4328   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4329         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4330   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4331 {
4332   /* ??? Needed for compress_float_constant since all fp constants
4333      are LEGITIMATE_CONSTANT_P.  */
4334   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4335     {
4336       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4337           && standard_80387_constant_p (operands[1]) > 0)
4338         {
4339           operands[1] = simplify_const_unary_operation
4340             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4341           emit_move_insn_1 (operands[0], operands[1]);
4342           DONE;
4343         }
4344       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4345     }
4346 })
4347
4348 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4349    cvtss2sd:
4350       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4351       cvtps2pd xmm2,xmm1
4352    We do the conversion post reload to avoid producing of 128bit spills
4353    that might lead to ICE on 32bit target.  The sequence unlikely combine
4354    anyway.  */
4355 (define_split
4356   [(set (match_operand:DF 0 "register_operand" "")
4357         (float_extend:DF
4358           (match_operand:SF 1 "nonimmediate_operand" "")))]
4359   "TARGET_USE_VECTOR_FP_CONVERTS
4360    && optimize_insn_for_speed_p ()
4361    && reload_completed && SSE_REG_P (operands[0])"
4362    [(set (match_dup 2)
4363          (float_extend:V2DF
4364            (vec_select:V2SF
4365              (match_dup 3)
4366              (parallel [(const_int 0) (const_int 1)]))))]
4367 {
4368   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4369   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4370   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4371      Try to avoid move when unpacking can be done in source.  */
4372   if (REG_P (operands[1]))
4373     {
4374       /* If it is unsafe to overwrite upper half of source, we need
4375          to move to destination and unpack there.  */
4376       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4377            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4378           && true_regnum (operands[0]) != true_regnum (operands[1]))
4379         {
4380           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4381           emit_move_insn (tmp, operands[1]);
4382         }
4383       else
4384         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4385       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4386                                              operands[3]));
4387     }
4388   else
4389     emit_insn (gen_vec_setv4sf_0 (operands[3],
4390                                   CONST0_RTX (V4SFmode), operands[1]));
4391 })
4392
4393 (define_insn "*extendsfdf2_mixed"
4394   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4395         (float_extend:DF
4396           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4397   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4398 {
4399   switch (which_alternative)
4400     {
4401     case 0:
4402     case 1:
4403       return output_387_reg_move (insn, operands);
4404
4405     case 2:
4406       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4407
4408     default:
4409       gcc_unreachable ();
4410     }
4411 }
4412   [(set_attr "type" "fmov,fmov,ssecvt")
4413    (set_attr "prefix" "orig,orig,maybe_vex")
4414    (set_attr "mode" "SF,XF,DF")])
4415
4416 (define_insn "*extendsfdf2_sse"
4417   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4418         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4419   "TARGET_SSE2 && TARGET_SSE_MATH"
4420   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4421   [(set_attr "type" "ssecvt")
4422    (set_attr "prefix" "maybe_vex")
4423    (set_attr "mode" "DF")])
4424
4425 (define_insn "*extendsfdf2_i387"
4426   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4427         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4428   "TARGET_80387"
4429   "* return output_387_reg_move (insn, operands);"
4430   [(set_attr "type" "fmov")
4431    (set_attr "mode" "SF,XF")])
4432
4433 (define_expand "extend<mode>xf2"
4434   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4435         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4436   "TARGET_80387"
4437 {
4438   /* ??? Needed for compress_float_constant since all fp constants
4439      are LEGITIMATE_CONSTANT_P.  */
4440   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4441     {
4442       if (standard_80387_constant_p (operands[1]) > 0)
4443         {
4444           operands[1] = simplify_const_unary_operation
4445             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4446           emit_move_insn_1 (operands[0], operands[1]);
4447           DONE;
4448         }
4449       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4450     }
4451 })
4452
4453 (define_insn "*extend<mode>xf2_i387"
4454   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4455         (float_extend:XF
4456           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4457   "TARGET_80387"
4458   "* return output_387_reg_move (insn, operands);"
4459   [(set_attr "type" "fmov")
4460    (set_attr "mode" "<MODE>,XF")])
4461
4462 ;; %%% This seems bad bad news.
4463 ;; This cannot output into an f-reg because there is no way to be sure
4464 ;; of truncating in that case.  Otherwise this is just like a simple move
4465 ;; insn.  So we pretend we can output to a reg in order to get better
4466 ;; register preferencing, but we really use a stack slot.
4467
4468 ;; Conversion from DFmode to SFmode.
4469
4470 (define_expand "truncdfsf2"
4471   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4472         (float_truncate:SF
4473           (match_operand:DF 1 "nonimmediate_operand" "")))]
4474   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4475 {
4476   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4477     ;
4478   else if (flag_unsafe_math_optimizations)
4479     ;
4480   else
4481     {
4482       enum ix86_stack_slot slot = (virtuals_instantiated
4483                                    ? SLOT_TEMP
4484                                    : SLOT_VIRTUAL);
4485       rtx temp = assign_386_stack_local (SFmode, slot);
4486       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4487       DONE;
4488     }
4489 })
4490
4491 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4492    cvtsd2ss:
4493       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4494       cvtpd2ps xmm2,xmm1
4495    We do the conversion post reload to avoid producing of 128bit spills
4496    that might lead to ICE on 32bit target.  The sequence unlikely combine
4497    anyway.  */
4498 (define_split
4499   [(set (match_operand:SF 0 "register_operand" "")
4500         (float_truncate:SF
4501           (match_operand:DF 1 "nonimmediate_operand" "")))]
4502   "TARGET_USE_VECTOR_FP_CONVERTS
4503    && optimize_insn_for_speed_p ()
4504    && reload_completed && SSE_REG_P (operands[0])"
4505    [(set (match_dup 2)
4506          (vec_concat:V4SF
4507            (float_truncate:V2SF
4508              (match_dup 4))
4509            (match_dup 3)))]
4510 {
4511   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4512   operands[3] = CONST0_RTX (V2SFmode);
4513   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4514   /* Use movsd for loading from memory, unpcklpd for registers.
4515      Try to avoid move when unpacking can be done in source, or SSE3
4516      movddup is available.  */
4517   if (REG_P (operands[1]))
4518     {
4519       if (!TARGET_SSE3
4520           && true_regnum (operands[0]) != true_regnum (operands[1])
4521           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4522               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4523         {
4524           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4525           emit_move_insn (tmp, operands[1]);
4526           operands[1] = tmp;
4527         }
4528       else if (!TARGET_SSE3)
4529         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4530       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4531     }
4532   else
4533     emit_insn (gen_sse2_loadlpd (operands[4],
4534                                  CONST0_RTX (V2DFmode), operands[1]));
4535 })
4536
4537 (define_expand "truncdfsf2_with_temp"
4538   [(parallel [(set (match_operand:SF 0 "" "")
4539                    (float_truncate:SF (match_operand:DF 1 "" "")))
4540               (clobber (match_operand:SF 2 "" ""))])]
4541   "")
4542
4543 (define_insn "*truncdfsf_fast_mixed"
4544   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4545         (float_truncate:SF
4546           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4547   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4548 {
4549   switch (which_alternative)
4550     {
4551     case 0:
4552       return output_387_reg_move (insn, operands);
4553     case 1:
4554       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4555     default:
4556       gcc_unreachable ();
4557     }
4558 }
4559   [(set_attr "type" "fmov,ssecvt")
4560    (set_attr "prefix" "orig,maybe_vex")
4561    (set_attr "mode" "SF")])
4562
4563 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4564 ;; because nothing we do here is unsafe.
4565 (define_insn "*truncdfsf_fast_sse"
4566   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4567         (float_truncate:SF
4568           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4569   "TARGET_SSE2 && TARGET_SSE_MATH"
4570   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4571   [(set_attr "type" "ssecvt")
4572    (set_attr "prefix" "maybe_vex")
4573    (set_attr "mode" "SF")])
4574
4575 (define_insn "*truncdfsf_fast_i387"
4576   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4577         (float_truncate:SF
4578           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4579   "TARGET_80387 && flag_unsafe_math_optimizations"
4580   "* return output_387_reg_move (insn, operands);"
4581   [(set_attr "type" "fmov")
4582    (set_attr "mode" "SF")])
4583
4584 (define_insn "*truncdfsf_mixed"
4585   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4586         (float_truncate:SF
4587           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4588    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4589   "TARGET_MIX_SSE_I387"
4590 {
4591   switch (which_alternative)
4592     {
4593     case 0:
4594       return output_387_reg_move (insn, operands);
4595     case 1:
4596       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4597
4598     default:
4599       return "#";
4600     }
4601 }
4602   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4603    (set_attr "unit" "*,*,i387,i387,i387")
4604    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4605    (set_attr "mode" "SF")])
4606
4607 (define_insn "*truncdfsf_i387"
4608   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4609         (float_truncate:SF
4610           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4611    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4612   "TARGET_80387"
4613 {
4614   switch (which_alternative)
4615     {
4616     case 0:
4617       return output_387_reg_move (insn, operands);
4618
4619     default:
4620       return "#";
4621     }
4622 }
4623   [(set_attr "type" "fmov,multi,multi,multi")
4624    (set_attr "unit" "*,i387,i387,i387")
4625    (set_attr "mode" "SF")])
4626
4627 (define_insn "*truncdfsf2_i387_1"
4628   [(set (match_operand:SF 0 "memory_operand" "=m")
4629         (float_truncate:SF
4630           (match_operand:DF 1 "register_operand" "f")))]
4631   "TARGET_80387
4632    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4633    && !TARGET_MIX_SSE_I387"
4634   "* return output_387_reg_move (insn, operands);"
4635   [(set_attr "type" "fmov")
4636    (set_attr "mode" "SF")])
4637
4638 (define_split
4639   [(set (match_operand:SF 0 "register_operand" "")
4640         (float_truncate:SF
4641          (match_operand:DF 1 "fp_register_operand" "")))
4642    (clobber (match_operand 2 "" ""))]
4643   "reload_completed"
4644   [(set (match_dup 2) (match_dup 1))
4645    (set (match_dup 0) (match_dup 2))]
4646 {
4647   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4648 })
4649
4650 ;; Conversion from XFmode to {SF,DF}mode
4651
4652 (define_expand "truncxf<mode>2"
4653   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4654                    (float_truncate:MODEF
4655                      (match_operand:XF 1 "register_operand" "")))
4656               (clobber (match_dup 2))])]
4657   "TARGET_80387"
4658 {
4659   if (flag_unsafe_math_optimizations)
4660     {
4661       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4662       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4663       if (reg != operands[0])
4664         emit_move_insn (operands[0], reg);
4665       DONE;
4666     }
4667   else
4668     {
4669      enum ix86_stack_slot slot = (virtuals_instantiated
4670                                   ? SLOT_TEMP
4671                                   : SLOT_VIRTUAL);
4672       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4673     }
4674 })
4675
4676 (define_insn "*truncxfsf2_mixed"
4677   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4678         (float_truncate:SF
4679           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4680    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4681   "TARGET_80387"
4682 {
4683   gcc_assert (!which_alternative);
4684   return output_387_reg_move (insn, operands);
4685 }
4686   [(set_attr "type" "fmov,multi,multi,multi")
4687    (set_attr "unit" "*,i387,i387,i387")
4688    (set_attr "mode" "SF")])
4689
4690 (define_insn "*truncxfdf2_mixed"
4691   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4692         (float_truncate:DF
4693           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4694    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4695   "TARGET_80387"
4696 {
4697   gcc_assert (!which_alternative);
4698   return output_387_reg_move (insn, operands);
4699 }
4700   [(set_attr "type" "fmov,multi,multi,multi")
4701    (set_attr "unit" "*,i387,i387,i387")
4702    (set_attr "mode" "DF")])
4703
4704 (define_insn "truncxf<mode>2_i387_noop"
4705   [(set (match_operand:MODEF 0 "register_operand" "=f")
4706         (float_truncate:MODEF
4707           (match_operand:XF 1 "register_operand" "f")))]
4708   "TARGET_80387 && flag_unsafe_math_optimizations"
4709   "* return output_387_reg_move (insn, operands);"
4710   [(set_attr "type" "fmov")
4711    (set_attr "mode" "<MODE>")])
4712
4713 (define_insn "*truncxf<mode>2_i387"
4714   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4715         (float_truncate:MODEF
4716           (match_operand:XF 1 "register_operand" "f")))]
4717   "TARGET_80387"
4718   "* return output_387_reg_move (insn, operands);"
4719   [(set_attr "type" "fmov")
4720    (set_attr "mode" "<MODE>")])
4721
4722 (define_split
4723   [(set (match_operand:MODEF 0 "register_operand" "")
4724         (float_truncate:MODEF
4725           (match_operand:XF 1 "register_operand" "")))
4726    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4727   "TARGET_80387 && reload_completed"
4728   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4729    (set (match_dup 0) (match_dup 2))]
4730   "")
4731
4732 (define_split
4733   [(set (match_operand:MODEF 0 "memory_operand" "")
4734         (float_truncate:MODEF
4735           (match_operand:XF 1 "register_operand" "")))
4736    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4737   "TARGET_80387"
4738   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4739   "")
4740 \f
4741 ;; Signed conversion to DImode.
4742
4743 (define_expand "fix_truncxfdi2"
4744   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4746               (clobber (reg:CC FLAGS_REG))])]
4747   "TARGET_80387"
4748 {
4749   if (TARGET_FISTTP)
4750    {
4751      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4752      DONE;
4753    }
4754 })
4755
4756 (define_expand "fix_trunc<mode>di2"
4757   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4758                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4759               (clobber (reg:CC FLAGS_REG))])]
4760   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4761 {
4762   if (TARGET_FISTTP
4763       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4764    {
4765      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4766      DONE;
4767    }
4768   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4769    {
4770      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4771      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4772      if (out != operands[0])
4773         emit_move_insn (operands[0], out);
4774      DONE;
4775    }
4776 })
4777
4778 ;; Signed conversion to SImode.
4779
4780 (define_expand "fix_truncxfsi2"
4781   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4782                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4783               (clobber (reg:CC FLAGS_REG))])]
4784   "TARGET_80387"
4785 {
4786   if (TARGET_FISTTP)
4787    {
4788      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4789      DONE;
4790    }
4791 })
4792
4793 (define_expand "fix_trunc<mode>si2"
4794   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4795                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4796               (clobber (reg:CC FLAGS_REG))])]
4797   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4798 {
4799   if (TARGET_FISTTP
4800       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4801    {
4802      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4803      DONE;
4804    }
4805   if (SSE_FLOAT_MODE_P (<MODE>mode))
4806    {
4807      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4808      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4809      if (out != operands[0])
4810         emit_move_insn (operands[0], out);
4811      DONE;
4812    }
4813 })
4814
4815 ;; Signed conversion to HImode.
4816
4817 (define_expand "fix_trunc<mode>hi2"
4818   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4819                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4820               (clobber (reg:CC FLAGS_REG))])]
4821   "TARGET_80387
4822    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4823 {
4824   if (TARGET_FISTTP)
4825    {
4826      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4827      DONE;
4828    }
4829 })
4830
4831 ;; Unsigned conversion to SImode.
4832
4833 (define_expand "fixuns_trunc<mode>si2"
4834   [(parallel
4835     [(set (match_operand:SI 0 "register_operand" "")
4836           (unsigned_fix:SI
4837             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4838      (use (match_dup 2))
4839      (clobber (match_scratch:<ssevecmode> 3 ""))
4840      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4841   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4842 {
4843   enum machine_mode mode = <MODE>mode;
4844   enum machine_mode vecmode = <ssevecmode>mode;
4845   REAL_VALUE_TYPE TWO31r;
4846   rtx two31;
4847
4848   if (optimize_insn_for_size_p ())
4849     FAIL;
4850
4851   real_ldexp (&TWO31r, &dconst1, 31);
4852   two31 = const_double_from_real_value (TWO31r, mode);
4853   two31 = ix86_build_const_vector (mode, true, two31);
4854   operands[2] = force_reg (vecmode, two31);
4855 })
4856
4857 (define_insn_and_split "*fixuns_trunc<mode>_1"
4858   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4859         (unsigned_fix:SI
4860           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4861    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4862    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4863    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4864   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4865    && optimize_function_for_speed_p (cfun)"
4866   "#"
4867   "&& reload_completed"
4868   [(const_int 0)]
4869 {
4870   ix86_split_convert_uns_si_sse (operands);
4871   DONE;
4872 })
4873
4874 ;; Unsigned conversion to HImode.
4875 ;; Without these patterns, we'll try the unsigned SI conversion which
4876 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4877
4878 (define_expand "fixuns_trunc<mode>hi2"
4879   [(set (match_dup 2)
4880         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4881    (set (match_operand:HI 0 "nonimmediate_operand" "")
4882         (subreg:HI (match_dup 2) 0))]
4883   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4884   "operands[2] = gen_reg_rtx (SImode);")
4885
4886 ;; When SSE is available, it is always faster to use it!
4887 (define_insn "fix_trunc<mode>di_sse"
4888   [(set (match_operand:DI 0 "register_operand" "=r,r")
4889         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4890   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4891    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4892   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4893   [(set_attr "type" "sseicvt")
4894    (set_attr "prefix" "maybe_vex")
4895    (set_attr "prefix_rex" "1")
4896    (set_attr "mode" "<MODE>")
4897    (set_attr "athlon_decode" "double,vector")
4898    (set_attr "amdfam10_decode" "double,double")])
4899
4900 (define_insn "fix_trunc<mode>si_sse"
4901   [(set (match_operand:SI 0 "register_operand" "=r,r")
4902         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4903   "SSE_FLOAT_MODE_P (<MODE>mode)
4904    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4905   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4906   [(set_attr "type" "sseicvt")
4907    (set_attr "prefix" "maybe_vex")
4908    (set_attr "mode" "<MODE>")
4909    (set_attr "athlon_decode" "double,vector")
4910    (set_attr "amdfam10_decode" "double,double")])
4911
4912 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4913 (define_peephole2
4914   [(set (match_operand:MODEF 0 "register_operand" "")
4915         (match_operand:MODEF 1 "memory_operand" ""))
4916    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4917         (fix:SSEMODEI24 (match_dup 0)))]
4918   "TARGET_SHORTEN_X87_SSE
4919    && peep2_reg_dead_p (2, operands[0])"
4920   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4921   "")
4922
4923 ;; Avoid vector decoded forms of the instruction.
4924 (define_peephole2
4925   [(match_scratch:DF 2 "Y2")
4926    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4927         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4928   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4929   [(set (match_dup 2) (match_dup 1))
4930    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4931   "")
4932
4933 (define_peephole2
4934   [(match_scratch:SF 2 "x")
4935    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4936         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4937   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4938   [(set (match_dup 2) (match_dup 1))
4939    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4940   "")
4941
4942 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4943   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4944         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4945   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4946    && TARGET_FISTTP
4947    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4948          && (TARGET_64BIT || <MODE>mode != DImode))
4949         && TARGET_SSE_MATH)
4950    && can_create_pseudo_p ()"
4951   "#"
4952   "&& 1"
4953   [(const_int 0)]
4954 {
4955   if (memory_operand (operands[0], VOIDmode))
4956     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4957   else
4958     {
4959       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4960       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4961                                                             operands[1],
4962                                                             operands[2]));
4963     }
4964   DONE;
4965 }
4966   [(set_attr "type" "fisttp")
4967    (set_attr "mode" "<MODE>")])
4968
4969 (define_insn "fix_trunc<mode>_i387_fisttp"
4970   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4971         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4972    (clobber (match_scratch:XF 2 "=&1f"))]
4973   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4974    && TARGET_FISTTP
4975    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4976          && (TARGET_64BIT || <MODE>mode != DImode))
4977         && TARGET_SSE_MATH)"
4978   "* return output_fix_trunc (insn, operands, 1);"
4979   [(set_attr "type" "fisttp")
4980    (set_attr "mode" "<MODE>")])
4981
4982 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4983   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4984         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4985    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4986    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4987   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4988    && TARGET_FISTTP
4989    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4990         && (TARGET_64BIT || <MODE>mode != DImode))
4991         && TARGET_SSE_MATH)"
4992   "#"
4993   [(set_attr "type" "fisttp")
4994    (set_attr "mode" "<MODE>")])
4995
4996 (define_split
4997   [(set (match_operand:X87MODEI 0 "register_operand" "")
4998         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4999    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5000    (clobber (match_scratch 3 ""))]
5001   "reload_completed"
5002   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5003               (clobber (match_dup 3))])
5004    (set (match_dup 0) (match_dup 2))]
5005   "")
5006
5007 (define_split
5008   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5009         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5010    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5011    (clobber (match_scratch 3 ""))]
5012   "reload_completed"
5013   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5014               (clobber (match_dup 3))])]
5015   "")
5016
5017 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5018 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5019 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5020 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5021 ;; function in i386.c.
5022 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5023   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5024         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5025    (clobber (reg:CC FLAGS_REG))]
5026   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5027    && !TARGET_FISTTP
5028    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5029          && (TARGET_64BIT || <MODE>mode != DImode))
5030    && can_create_pseudo_p ()"
5031   "#"
5032   "&& 1"
5033   [(const_int 0)]
5034 {
5035   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5036
5037   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5038   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5039   if (memory_operand (operands[0], VOIDmode))
5040     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5041                                          operands[2], operands[3]));
5042   else
5043     {
5044       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5045       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5046                                                      operands[2], operands[3],
5047                                                      operands[4]));
5048     }
5049   DONE;
5050 }
5051   [(set_attr "type" "fistp")
5052    (set_attr "i387_cw" "trunc")
5053    (set_attr "mode" "<MODE>")])
5054
5055 (define_insn "fix_truncdi_i387"
5056   [(set (match_operand:DI 0 "memory_operand" "=m")
5057         (fix:DI (match_operand 1 "register_operand" "f")))
5058    (use (match_operand:HI 2 "memory_operand" "m"))
5059    (use (match_operand:HI 3 "memory_operand" "m"))
5060    (clobber (match_scratch:XF 4 "=&1f"))]
5061   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5062    && !TARGET_FISTTP
5063    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5064   "* return output_fix_trunc (insn, operands, 0);"
5065   [(set_attr "type" "fistp")
5066    (set_attr "i387_cw" "trunc")
5067    (set_attr "mode" "DI")])
5068
5069 (define_insn "fix_truncdi_i387_with_temp"
5070   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5071         (fix:DI (match_operand 1 "register_operand" "f,f")))
5072    (use (match_operand:HI 2 "memory_operand" "m,m"))
5073    (use (match_operand:HI 3 "memory_operand" "m,m"))
5074    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5075    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5076   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5077    && !TARGET_FISTTP
5078    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5079   "#"
5080   [(set_attr "type" "fistp")
5081    (set_attr "i387_cw" "trunc")
5082    (set_attr "mode" "DI")])
5083
5084 (define_split
5085   [(set (match_operand:DI 0 "register_operand" "")
5086         (fix:DI (match_operand 1 "register_operand" "")))
5087    (use (match_operand:HI 2 "memory_operand" ""))
5088    (use (match_operand:HI 3 "memory_operand" ""))
5089    (clobber (match_operand:DI 4 "memory_operand" ""))
5090    (clobber (match_scratch 5 ""))]
5091   "reload_completed"
5092   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5093               (use (match_dup 2))
5094               (use (match_dup 3))
5095               (clobber (match_dup 5))])
5096    (set (match_dup 0) (match_dup 4))]
5097   "")
5098
5099 (define_split
5100   [(set (match_operand:DI 0 "memory_operand" "")
5101         (fix:DI (match_operand 1 "register_operand" "")))
5102    (use (match_operand:HI 2 "memory_operand" ""))
5103    (use (match_operand:HI 3 "memory_operand" ""))
5104    (clobber (match_operand:DI 4 "memory_operand" ""))
5105    (clobber (match_scratch 5 ""))]
5106   "reload_completed"
5107   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5108               (use (match_dup 2))
5109               (use (match_dup 3))
5110               (clobber (match_dup 5))])]
5111   "")
5112
5113 (define_insn "fix_trunc<mode>_i387"
5114   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5115         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5116    (use (match_operand:HI 2 "memory_operand" "m"))
5117    (use (match_operand:HI 3 "memory_operand" "m"))]
5118   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5119    && !TARGET_FISTTP
5120    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5121   "* return output_fix_trunc (insn, operands, 0);"
5122   [(set_attr "type" "fistp")
5123    (set_attr "i387_cw" "trunc")
5124    (set_attr "mode" "<MODE>")])
5125
5126 (define_insn "fix_trunc<mode>_i387_with_temp"
5127   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5128         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5129    (use (match_operand:HI 2 "memory_operand" "m,m"))
5130    (use (match_operand:HI 3 "memory_operand" "m,m"))
5131    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5132   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5133    && !TARGET_FISTTP
5134    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5135   "#"
5136   [(set_attr "type" "fistp")
5137    (set_attr "i387_cw" "trunc")
5138    (set_attr "mode" "<MODE>")])
5139
5140 (define_split
5141   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5142         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5143    (use (match_operand:HI 2 "memory_operand" ""))
5144    (use (match_operand:HI 3 "memory_operand" ""))
5145    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5146   "reload_completed"
5147   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5148               (use (match_dup 2))
5149               (use (match_dup 3))])
5150    (set (match_dup 0) (match_dup 4))]
5151   "")
5152
5153 (define_split
5154   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5155         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5156    (use (match_operand:HI 2 "memory_operand" ""))
5157    (use (match_operand:HI 3 "memory_operand" ""))
5158    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5159   "reload_completed"
5160   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5161               (use (match_dup 2))
5162               (use (match_dup 3))])]
5163   "")
5164
5165 (define_insn "x86_fnstcw_1"
5166   [(set (match_operand:HI 0 "memory_operand" "=m")
5167         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5168   "TARGET_80387"
5169   "fnstcw\t%0"
5170   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5171    (set_attr "mode" "HI")
5172    (set_attr "unit" "i387")])
5173
5174 (define_insn "x86_fldcw_1"
5175   [(set (reg:HI FPCR_REG)
5176         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5177   "TARGET_80387"
5178   "fldcw\t%0"
5179   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5180    (set_attr "mode" "HI")
5181    (set_attr "unit" "i387")
5182    (set_attr "athlon_decode" "vector")
5183    (set_attr "amdfam10_decode" "vector")])
5184 \f
5185 ;; Conversion between fixed point and floating point.
5186
5187 ;; Even though we only accept memory inputs, the backend _really_
5188 ;; wants to be able to do this between registers.
5189
5190 (define_expand "floathi<mode>2"
5191   [(set (match_operand:X87MODEF 0 "register_operand" "")
5192         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5193   "TARGET_80387
5194    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5195        || TARGET_MIX_SSE_I387)"
5196   "")
5197
5198 ;; Pre-reload splitter to add memory clobber to the pattern.
5199 (define_insn_and_split "*floathi<mode>2_1"
5200   [(set (match_operand:X87MODEF 0 "register_operand" "")
5201         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5202   "TARGET_80387
5203    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5204        || TARGET_MIX_SSE_I387)
5205    && can_create_pseudo_p ()"
5206   "#"
5207   "&& 1"
5208   [(parallel [(set (match_dup 0)
5209               (float:X87MODEF (match_dup 1)))
5210    (clobber (match_dup 2))])]
5211   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5212
5213 (define_insn "*floathi<mode>2_i387_with_temp"
5214   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5215         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5216   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5217   "TARGET_80387
5218    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5219        || TARGET_MIX_SSE_I387)"
5220   "#"
5221   [(set_attr "type" "fmov,multi")
5222    (set_attr "mode" "<MODE>")
5223    (set_attr "unit" "*,i387")
5224    (set_attr "fp_int_src" "true")])
5225
5226 (define_insn "*floathi<mode>2_i387"
5227   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5228         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5229   "TARGET_80387
5230    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5231        || TARGET_MIX_SSE_I387)"
5232   "fild%Z1\t%1"
5233   [(set_attr "type" "fmov")
5234    (set_attr "mode" "<MODE>")
5235    (set_attr "fp_int_src" "true")])
5236
5237 (define_split
5238   [(set (match_operand:X87MODEF 0 "register_operand" "")
5239         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5240    (clobber (match_operand:HI 2 "memory_operand" ""))]
5241   "TARGET_80387
5242    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5243        || TARGET_MIX_SSE_I387)
5244    && reload_completed"
5245   [(set (match_dup 2) (match_dup 1))
5246    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5247   "")
5248
5249 (define_split
5250   [(set (match_operand:X87MODEF 0 "register_operand" "")
5251         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5252    (clobber (match_operand:HI 2 "memory_operand" ""))]
5253    "TARGET_80387
5254     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5255         || TARGET_MIX_SSE_I387)
5256     && reload_completed"
5257   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5258   "")
5259
5260 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5261   [(set (match_operand:X87MODEF 0 "register_operand" "")
5262         (float:X87MODEF
5263           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5264   "TARGET_80387
5265    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5267 {
5268   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5269         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5270       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5271     {
5272       rtx reg = gen_reg_rtx (XFmode);
5273       rtx insn;
5274
5275       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5276
5277       if (<X87MODEF:MODE>mode == SFmode)
5278         insn = gen_truncxfsf2 (operands[0], reg);
5279       else if (<X87MODEF:MODE>mode == DFmode)
5280         insn = gen_truncxfdf2 (operands[0], reg);
5281       else
5282         gcc_unreachable ();
5283
5284       emit_insn (insn);
5285       DONE;
5286     }
5287 })
5288
5289 ;; Pre-reload splitter to add memory clobber to the pattern.
5290 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5291   [(set (match_operand:X87MODEF 0 "register_operand" "")
5292         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5293   "((TARGET_80387
5294      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5295      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5296            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5297          || TARGET_MIX_SSE_I387))
5298     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5299         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5300         && ((<SSEMODEI24:MODE>mode == SImode
5301              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5302              && optimize_function_for_speed_p (cfun)
5303              && flag_trapping_math)
5304             || !(TARGET_INTER_UNIT_CONVERSIONS
5305                  || optimize_function_for_size_p (cfun)))))
5306    && can_create_pseudo_p ()"
5307   "#"
5308   "&& 1"
5309   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5310               (clobber (match_dup 2))])]
5311 {
5312   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5313
5314   /* Avoid store forwarding (partial memory) stall penalty
5315      by passing DImode value through XMM registers.  */
5316   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5317       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5318       && optimize_function_for_speed_p (cfun))
5319     {
5320       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5321                                                             operands[1],
5322                                                             operands[2]));
5323       DONE;
5324     }
5325 })
5326
5327 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5328   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5329         (float:MODEF
5330           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5331    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5332   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5333    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5334   "#"
5335   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5336    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5337    (set_attr "unit" "*,i387,*,*,*")
5338    (set_attr "athlon_decode" "*,*,double,direct,double")
5339    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5340    (set_attr "fp_int_src" "true")])
5341
5342 (define_insn "*floatsi<mode>2_vector_mixed"
5343   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5344         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5345   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5346    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5347   "@
5348    fild%Z1\t%1
5349    #"
5350   [(set_attr "type" "fmov,sseicvt")
5351    (set_attr "mode" "<MODE>,<ssevecmode>")
5352    (set_attr "unit" "i387,*")
5353    (set_attr "athlon_decode" "*,direct")
5354    (set_attr "amdfam10_decode" "*,double")
5355    (set_attr "fp_int_src" "true")])
5356
5357 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5358   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5359         (float:MODEF
5360           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5361   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5362   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5364   "#"
5365   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5366    (set_attr "mode" "<MODEF:MODE>")
5367    (set_attr "unit" "*,i387,*,*")
5368    (set_attr "athlon_decode" "*,*,double,direct")
5369    (set_attr "amdfam10_decode" "*,*,vector,double")
5370    (set_attr "fp_int_src" "true")])
5371
5372 (define_split
5373   [(set (match_operand:MODEF 0 "register_operand" "")
5374         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5375    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5376   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5377    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5378    && TARGET_INTER_UNIT_CONVERSIONS
5379    && reload_completed
5380    && (SSE_REG_P (operands[0])
5381        || (GET_CODE (operands[0]) == SUBREG
5382            && SSE_REG_P (operands[0])))"
5383   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5384   "")
5385
5386 (define_split
5387   [(set (match_operand:MODEF 0 "register_operand" "")
5388         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5389    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5390   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5391    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5392    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5393    && reload_completed
5394    && (SSE_REG_P (operands[0])
5395        || (GET_CODE (operands[0]) == SUBREG
5396            && SSE_REG_P (operands[0])))"
5397   [(set (match_dup 2) (match_dup 1))
5398    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5399   "")
5400
5401 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5402   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5403         (float:MODEF
5404           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5405   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5406    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5407    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5408   "@
5409    fild%Z1\t%1
5410    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5411    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5412   [(set_attr "type" "fmov,sseicvt,sseicvt")
5413    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5414    (set_attr "mode" "<MODEF:MODE>")
5415    (set (attr "prefix_rex")
5416      (if_then_else
5417        (and (eq_attr "prefix" "maybe_vex")
5418             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5419        (const_string "1")
5420        (const_string "*")))
5421    (set_attr "unit" "i387,*,*")
5422    (set_attr "athlon_decode" "*,double,direct")
5423    (set_attr "amdfam10_decode" "*,vector,double")
5424    (set_attr "fp_int_src" "true")])
5425
5426 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5427   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5428         (float:MODEF
5429           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5430   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5431    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5432    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5433   "@
5434    fild%Z1\t%1
5435    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5436   [(set_attr "type" "fmov,sseicvt")
5437    (set_attr "prefix" "orig,maybe_vex")
5438    (set_attr "mode" "<MODEF:MODE>")
5439    (set (attr "prefix_rex")
5440      (if_then_else
5441        (and (eq_attr "prefix" "maybe_vex")
5442             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5443        (const_string "1")
5444        (const_string "*")))
5445    (set_attr "athlon_decode" "*,direct")
5446    (set_attr "amdfam10_decode" "*,double")
5447    (set_attr "fp_int_src" "true")])
5448
5449 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5450   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5451         (float:MODEF
5452           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5453    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5454   "TARGET_SSE2 && TARGET_SSE_MATH
5455    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5456   "#"
5457   [(set_attr "type" "sseicvt")
5458    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5459    (set_attr "athlon_decode" "double,direct,double")
5460    (set_attr "amdfam10_decode" "vector,double,double")
5461    (set_attr "fp_int_src" "true")])
5462
5463 (define_insn "*floatsi<mode>2_vector_sse"
5464   [(set (match_operand:MODEF 0 "register_operand" "=x")
5465         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5466   "TARGET_SSE2 && TARGET_SSE_MATH
5467    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5468   "#"
5469   [(set_attr "type" "sseicvt")
5470    (set_attr "mode" "<MODE>")
5471    (set_attr "athlon_decode" "direct")
5472    (set_attr "amdfam10_decode" "double")
5473    (set_attr "fp_int_src" "true")])
5474
5475 (define_split
5476   [(set (match_operand:MODEF 0 "register_operand" "")
5477         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5478    (clobber (match_operand:SI 2 "memory_operand" ""))]
5479   "TARGET_SSE2 && TARGET_SSE_MATH
5480    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5481    && reload_completed
5482    && (SSE_REG_P (operands[0])
5483        || (GET_CODE (operands[0]) == SUBREG
5484            && SSE_REG_P (operands[0])))"
5485   [(const_int 0)]
5486 {
5487   rtx op1 = operands[1];
5488
5489   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5490                                      <MODE>mode, 0);
5491   if (GET_CODE (op1) == SUBREG)
5492     op1 = SUBREG_REG (op1);
5493
5494   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5495     {
5496       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5497       emit_insn (gen_sse2_loadld (operands[4],
5498                                   CONST0_RTX (V4SImode), operands[1]));
5499     }
5500   /* We can ignore possible trapping value in the
5501      high part of SSE register for non-trapping math. */
5502   else if (SSE_REG_P (op1) && !flag_trapping_math)
5503     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5504   else
5505     {
5506       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5507       emit_move_insn (operands[2], operands[1]);
5508       emit_insn (gen_sse2_loadld (operands[4],
5509                                   CONST0_RTX (V4SImode), operands[2]));
5510     }
5511   emit_insn
5512     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5513   DONE;
5514 })
5515
5516 (define_split
5517   [(set (match_operand:MODEF 0 "register_operand" "")
5518         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5519    (clobber (match_operand:SI 2 "memory_operand" ""))]
5520   "TARGET_SSE2 && TARGET_SSE_MATH
5521    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5522    && reload_completed
5523    && (SSE_REG_P (operands[0])
5524        || (GET_CODE (operands[0]) == SUBREG
5525            && SSE_REG_P (operands[0])))"
5526   [(const_int 0)]
5527 {
5528   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5529                                      <MODE>mode, 0);
5530   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5531
5532   emit_insn (gen_sse2_loadld (operands[4],
5533                               CONST0_RTX (V4SImode), operands[1]));
5534   emit_insn
5535     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5536   DONE;
5537 })
5538
5539 (define_split
5540   [(set (match_operand:MODEF 0 "register_operand" "")
5541         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5542   "TARGET_SSE2 && TARGET_SSE_MATH
5543    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5544    && reload_completed
5545    && (SSE_REG_P (operands[0])
5546        || (GET_CODE (operands[0]) == SUBREG
5547            && SSE_REG_P (operands[0])))"
5548   [(const_int 0)]
5549 {
5550   rtx op1 = operands[1];
5551
5552   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5553                                      <MODE>mode, 0);
5554   if (GET_CODE (op1) == SUBREG)
5555     op1 = SUBREG_REG (op1);
5556
5557   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5558     {
5559       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5560       emit_insn (gen_sse2_loadld (operands[4],
5561                                   CONST0_RTX (V4SImode), operands[1]));
5562     }
5563   /* We can ignore possible trapping value in the
5564      high part of SSE register for non-trapping math. */
5565   else if (SSE_REG_P (op1) && !flag_trapping_math)
5566     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5567   else
5568     gcc_unreachable ();
5569   emit_insn
5570     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5571   DONE;
5572 })
5573
5574 (define_split
5575   [(set (match_operand:MODEF 0 "register_operand" "")
5576         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5577   "TARGET_SSE2 && TARGET_SSE_MATH
5578    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5579    && reload_completed
5580    && (SSE_REG_P (operands[0])
5581        || (GET_CODE (operands[0]) == SUBREG
5582            && SSE_REG_P (operands[0])))"
5583   [(const_int 0)]
5584 {
5585   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5586                                      <MODE>mode, 0);
5587   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5588
5589   emit_insn (gen_sse2_loadld (operands[4],
5590                               CONST0_RTX (V4SImode), operands[1]));
5591   emit_insn
5592     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5593   DONE;
5594 })
5595
5596 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5597   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5598         (float:MODEF
5599           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5600   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5601   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5602    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5603   "#"
5604   [(set_attr "type" "sseicvt")
5605    (set_attr "mode" "<MODEF:MODE>")
5606    (set_attr "athlon_decode" "double,direct")
5607    (set_attr "amdfam10_decode" "vector,double")
5608    (set_attr "fp_int_src" "true")])
5609
5610 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5611   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5612         (float:MODEF
5613           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5614   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5615    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5616    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5617   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5618   [(set_attr "type" "sseicvt")
5619    (set_attr "prefix" "maybe_vex")
5620    (set_attr "mode" "<MODEF:MODE>")
5621    (set (attr "prefix_rex")
5622      (if_then_else
5623        (and (eq_attr "prefix" "maybe_vex")
5624             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5625        (const_string "1")
5626        (const_string "*")))
5627    (set_attr "athlon_decode" "double,direct")
5628    (set_attr "amdfam10_decode" "vector,double")
5629    (set_attr "fp_int_src" "true")])
5630
5631 (define_split
5632   [(set (match_operand:MODEF 0 "register_operand" "")
5633         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5634    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5635   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5636    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5637    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5638    && reload_completed
5639    && (SSE_REG_P (operands[0])
5640        || (GET_CODE (operands[0]) == SUBREG
5641            && SSE_REG_P (operands[0])))"
5642   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5643   "")
5644
5645 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5646   [(set (match_operand:MODEF 0 "register_operand" "=x")
5647         (float:MODEF
5648           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5649   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5650    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5651    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5652   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5653   [(set_attr "type" "sseicvt")
5654    (set_attr "prefix" "maybe_vex")
5655    (set_attr "mode" "<MODEF:MODE>")
5656    (set (attr "prefix_rex")
5657      (if_then_else
5658        (and (eq_attr "prefix" "maybe_vex")
5659             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5660        (const_string "1")
5661        (const_string "*")))
5662    (set_attr "athlon_decode" "direct")
5663    (set_attr "amdfam10_decode" "double")
5664    (set_attr "fp_int_src" "true")])
5665
5666 (define_split
5667   [(set (match_operand:MODEF 0 "register_operand" "")
5668         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5669    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5670   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5671    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5672    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5673    && reload_completed
5674    && (SSE_REG_P (operands[0])
5675        || (GET_CODE (operands[0]) == SUBREG
5676            && SSE_REG_P (operands[0])))"
5677   [(set (match_dup 2) (match_dup 1))
5678    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5679   "")
5680
5681 (define_split
5682   [(set (match_operand:MODEF 0 "register_operand" "")
5683         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5684    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5685   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5686    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5687    && reload_completed
5688    && (SSE_REG_P (operands[0])
5689        || (GET_CODE (operands[0]) == SUBREG
5690            && SSE_REG_P (operands[0])))"
5691   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5692   "")
5693
5694 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5695   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5696         (float:X87MODEF
5697           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5698   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5699   "TARGET_80387
5700    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5701   "@
5702    fild%Z1\t%1
5703    #"
5704   [(set_attr "type" "fmov,multi")
5705    (set_attr "mode" "<X87MODEF:MODE>")
5706    (set_attr "unit" "*,i387")
5707    (set_attr "fp_int_src" "true")])
5708
5709 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5710   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5711         (float:X87MODEF
5712           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5713   "TARGET_80387
5714    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5715   "fild%Z1\t%1"
5716   [(set_attr "type" "fmov")
5717    (set_attr "mode" "<X87MODEF:MODE>")
5718    (set_attr "fp_int_src" "true")])
5719
5720 (define_split
5721   [(set (match_operand:X87MODEF 0 "register_operand" "")
5722         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5723    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5724   "TARGET_80387
5725    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5726    && reload_completed
5727    && FP_REG_P (operands[0])"
5728   [(set (match_dup 2) (match_dup 1))
5729    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5730   "")
5731
5732 (define_split
5733   [(set (match_operand:X87MODEF 0 "register_operand" "")
5734         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5735    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5736   "TARGET_80387
5737    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5738    && reload_completed
5739    && FP_REG_P (operands[0])"
5740   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5741   "")
5742
5743 ;; Avoid store forwarding (partial memory) stall penalty
5744 ;; by passing DImode value through XMM registers.  */
5745
5746 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5747   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5748         (float:X87MODEF
5749           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5750    (clobber (match_scratch:V4SI 3 "=X,x"))
5751    (clobber (match_scratch:V4SI 4 "=X,x"))
5752    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5753   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5754    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5755    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5756   "#"
5757   [(set_attr "type" "multi")
5758    (set_attr "mode" "<X87MODEF:MODE>")
5759    (set_attr "unit" "i387")
5760    (set_attr "fp_int_src" "true")])
5761
5762 (define_split
5763   [(set (match_operand:X87MODEF 0 "register_operand" "")
5764         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5765    (clobber (match_scratch:V4SI 3 ""))
5766    (clobber (match_scratch:V4SI 4 ""))
5767    (clobber (match_operand:DI 2 "memory_operand" ""))]
5768   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5769    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5770    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5771    && reload_completed
5772    && FP_REG_P (operands[0])"
5773   [(set (match_dup 2) (match_dup 3))
5774    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5775 {
5776   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5777      Assemble the 64-bit DImode value in an xmm register.  */
5778   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5779                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5780   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5781                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5782   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5783                                          operands[4]));
5784
5785   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5786 })
5787
5788 (define_split
5789   [(set (match_operand:X87MODEF 0 "register_operand" "")
5790         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5791    (clobber (match_scratch:V4SI 3 ""))
5792    (clobber (match_scratch:V4SI 4 ""))
5793    (clobber (match_operand:DI 2 "memory_operand" ""))]
5794   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5795    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5796    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5797    && reload_completed
5798    && FP_REG_P (operands[0])"
5799   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5800   "")
5801
5802 ;; Avoid store forwarding (partial memory) stall penalty by extending
5803 ;; SImode value to DImode through XMM register instead of pushing two
5804 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5805 ;; targets benefit from this optimization. Also note that fild
5806 ;; loads from memory only.
5807
5808 (define_insn "*floatunssi<mode>2_1"
5809   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5810         (unsigned_float:X87MODEF
5811           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5812    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5813    (clobber (match_scratch:SI 3 "=X,x"))]
5814   "!TARGET_64BIT
5815    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5816    && TARGET_SSE"
5817   "#"
5818   [(set_attr "type" "multi")
5819    (set_attr "mode" "<MODE>")])
5820
5821 (define_split
5822   [(set (match_operand:X87MODEF 0 "register_operand" "")
5823         (unsigned_float:X87MODEF
5824           (match_operand:SI 1 "register_operand" "")))
5825    (clobber (match_operand:DI 2 "memory_operand" ""))
5826    (clobber (match_scratch:SI 3 ""))]
5827   "!TARGET_64BIT
5828    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5829    && TARGET_SSE
5830    && reload_completed"
5831   [(set (match_dup 2) (match_dup 1))
5832    (set (match_dup 0)
5833         (float:X87MODEF (match_dup 2)))]
5834   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5835
5836 (define_split
5837   [(set (match_operand:X87MODEF 0 "register_operand" "")
5838         (unsigned_float:X87MODEF
5839           (match_operand:SI 1 "memory_operand" "")))
5840    (clobber (match_operand:DI 2 "memory_operand" ""))
5841    (clobber (match_scratch:SI 3 ""))]
5842   "!TARGET_64BIT
5843    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5844    && TARGET_SSE
5845    && reload_completed"
5846   [(set (match_dup 2) (match_dup 3))
5847    (set (match_dup 0)
5848         (float:X87MODEF (match_dup 2)))]
5849 {
5850   emit_move_insn (operands[3], operands[1]);
5851   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5852 })
5853
5854 (define_expand "floatunssi<mode>2"
5855   [(parallel
5856      [(set (match_operand:X87MODEF 0 "register_operand" "")
5857            (unsigned_float:X87MODEF
5858              (match_operand:SI 1 "nonimmediate_operand" "")))
5859       (clobber (match_dup 2))
5860       (clobber (match_scratch:SI 3 ""))])]
5861   "!TARGET_64BIT
5862    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5863         && TARGET_SSE)
5864        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5865 {
5866   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5867     {
5868       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5869       DONE;
5870     }
5871   else
5872     {
5873       enum ix86_stack_slot slot = (virtuals_instantiated
5874                                    ? SLOT_TEMP
5875                                    : SLOT_VIRTUAL);
5876       operands[2] = assign_386_stack_local (DImode, slot);
5877     }
5878 })
5879
5880 (define_expand "floatunsdisf2"
5881   [(use (match_operand:SF 0 "register_operand" ""))
5882    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5883   "TARGET_64BIT && TARGET_SSE_MATH"
5884   "x86_emit_floatuns (operands); DONE;")
5885
5886 (define_expand "floatunsdidf2"
5887   [(use (match_operand:DF 0 "register_operand" ""))
5888    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5889   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5890    && TARGET_SSE2 && TARGET_SSE_MATH"
5891 {
5892   if (TARGET_64BIT)
5893     x86_emit_floatuns (operands);
5894   else
5895     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5896   DONE;
5897 })
5898 \f
5899 ;; Add instructions
5900
5901 (define_expand "add<mode>3"
5902   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5903         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5904                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5905   ""
5906   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5907
5908 (define_insn_and_split "*add<dwi>3_doubleword"
5909   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5910         (plus:<DWI>
5911           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5912           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5913    (clobber (reg:CC FLAGS_REG))]
5914   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5915   "#"
5916   "reload_completed"
5917   [(parallel [(set (reg:CC FLAGS_REG)
5918                    (unspec:CC [(match_dup 1) (match_dup 2)]
5919                               UNSPEC_ADD_CARRY))
5920               (set (match_dup 0)
5921                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5922    (parallel [(set (match_dup 3)
5923                    (plus:DWIH
5924                      (match_dup 4)
5925                      (plus:DWIH
5926                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5927                        (match_dup 5))))
5928               (clobber (reg:CC FLAGS_REG))])]
5929   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5930
5931 (define_insn "*add<mode>3_cc"
5932   [(set (reg:CC FLAGS_REG)
5933         (unspec:CC
5934           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5935            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5936           UNSPEC_ADD_CARRY))
5937    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5938         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5939   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5940   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5941   [(set_attr "type" "alu")
5942    (set_attr "mode" "<MODE>")])
5943
5944 (define_insn "addqi3_cc"
5945   [(set (reg:CC FLAGS_REG)
5946         (unspec:CC
5947           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5948            (match_operand:QI 2 "general_operand" "qn,qm")]
5949           UNSPEC_ADD_CARRY))
5950    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5951         (plus:QI (match_dup 1) (match_dup 2)))]
5952   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5953   "add{b}\t{%2, %0|%0, %2}"
5954   [(set_attr "type" "alu")
5955    (set_attr "mode" "QI")])
5956
5957 (define_insn "*lea_1"
5958   [(set (match_operand:DWIH 0 "register_operand" "=r")
5959         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5960   ""
5961   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5962   [(set_attr "type" "lea")
5963    (set_attr "mode" "<MODE>")])
5964
5965 (define_insn "*lea_2"
5966   [(set (match_operand:SI 0 "register_operand" "=r")
5967         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5968   "TARGET_64BIT"
5969   "lea{l}\t{%a1, %0|%0, %a1}"
5970   [(set_attr "type" "lea")
5971    (set_attr "mode" "SI")])
5972
5973 (define_insn "*lea_2_zext"
5974   [(set (match_operand:DI 0 "register_operand" "=r")
5975         (zero_extend:DI
5976           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5977   "TARGET_64BIT"
5978   "lea{l}\t{%a1, %k0|%k0, %a1}"
5979   [(set_attr "type" "lea")
5980    (set_attr "mode" "SI")])
5981
5982 (define_insn "*add<mode>_1"
5983   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5984         (plus:SWI48
5985           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5986           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5987    (clobber (reg:CC FLAGS_REG))]
5988   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5989 {
5990   switch (get_attr_type (insn))
5991     {
5992     case TYPE_LEA:
5993       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5994       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5995
5996     case TYPE_INCDEC:
5997       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5998       if (operands[2] == const1_rtx)
5999         return "inc{<imodesuffix>}\t%0";
6000       else
6001         {
6002           gcc_assert (operands[2] == constm1_rtx);
6003           return "dec{<imodesuffix>}\t%0";
6004         }
6005
6006     default:
6007       /* Use add as much as possible to replace lea for AGU optimization. */
6008       if (which_alternative == 2 && TARGET_OPT_AGU)
6009         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6010         
6011       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6012
6013       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6014          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6015       if (CONST_INT_P (operands[2])
6016           /* Avoid overflows.  */
6017           && (<MODE>mode != DImode
6018               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6019           && (INTVAL (operands[2]) == 128
6020               || (INTVAL (operands[2]) < 0
6021                   && INTVAL (operands[2]) != -128)))
6022         {
6023           operands[2] = GEN_INT (-INTVAL (operands[2]));
6024           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6025         }
6026       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6027     }
6028 }
6029   [(set (attr "type")
6030      (cond [(and (eq_attr "alternative" "2") 
6031                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6032               (const_string "lea")
6033             (eq_attr "alternative" "3")
6034               (const_string "lea")
6035             ; Current assemblers are broken and do not allow @GOTOFF in
6036             ; ought but a memory context.
6037             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6038               (const_string "lea")
6039             (match_operand:SWI48 2 "incdec_operand" "")
6040               (const_string "incdec")
6041            ]
6042            (const_string "alu")))
6043    (set (attr "length_immediate")
6044       (if_then_else
6045         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6046         (const_string "1")
6047         (const_string "*")))
6048    (set_attr "mode" "<MODE>")])
6049
6050 ;; It may seem that nonimmediate operand is proper one for operand 1.
6051 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6052 ;; we take care in ix86_binary_operator_ok to not allow two memory
6053 ;; operands so proper swapping will be done in reload.  This allow
6054 ;; patterns constructed from addsi_1 to match.
6055
6056 (define_insn "*addsi_1_zext"
6057   [(set (match_operand:DI 0 "register_operand" "=r,r")
6058         (zero_extend:DI
6059           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6060                    (match_operand:SI 2 "general_operand" "g,li"))))
6061    (clobber (reg:CC FLAGS_REG))]
6062   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6063 {
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_LEA:
6067       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6068       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6069
6070     case TYPE_INCDEC:
6071       if (operands[2] == const1_rtx)
6072         return "inc{l}\t%k0";
6073       else
6074         {
6075           gcc_assert (operands[2] == constm1_rtx);
6076           return "dec{l}\t%k0";
6077         }
6078
6079     default:
6080       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6081          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6082       if (CONST_INT_P (operands[2])
6083           && (INTVAL (operands[2]) == 128
6084               || (INTVAL (operands[2]) < 0
6085                   && INTVAL (operands[2]) != -128)))
6086         {
6087           operands[2] = GEN_INT (-INTVAL (operands[2]));
6088           return "sub{l}\t{%2, %k0|%k0, %2}";
6089         }
6090       return "add{l}\t{%2, %k0|%k0, %2}";
6091     }
6092 }
6093   [(set (attr "type")
6094      (cond [(eq_attr "alternative" "1")
6095               (const_string "lea")
6096             ; Current assemblers are broken and do not allow @GOTOFF in
6097             ; ought but a memory context.
6098             (match_operand:SI 2 "pic_symbolic_operand" "")
6099               (const_string "lea")
6100             (match_operand:SI 2 "incdec_operand" "")
6101               (const_string "incdec")
6102            ]
6103            (const_string "alu")))
6104    (set (attr "length_immediate")
6105       (if_then_else
6106         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6107         (const_string "1")
6108         (const_string "*")))
6109    (set_attr "mode" "SI")])
6110
6111 (define_insn "*addhi_1"
6112   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6113         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6114                  (match_operand:HI 2 "general_operand" "rn,rm")))
6115    (clobber (reg:CC FLAGS_REG))]
6116   "TARGET_PARTIAL_REG_STALL
6117    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6118 {
6119   switch (get_attr_type (insn))
6120     {
6121     case TYPE_INCDEC:
6122       if (operands[2] == const1_rtx)
6123         return "inc{w}\t%0";
6124       else
6125         {
6126           gcc_assert (operands[2] == constm1_rtx);
6127           return "dec{w}\t%0";
6128         }
6129
6130     default:
6131       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6132          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6133       if (CONST_INT_P (operands[2])
6134           && (INTVAL (operands[2]) == 128
6135               || (INTVAL (operands[2]) < 0
6136                   && INTVAL (operands[2]) != -128)))
6137         {
6138           operands[2] = GEN_INT (-INTVAL (operands[2]));
6139           return "sub{w}\t{%2, %0|%0, %2}";
6140         }
6141       return "add{w}\t{%2, %0|%0, %2}";
6142     }
6143 }
6144   [(set (attr "type")
6145      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6146         (const_string "incdec")
6147         (const_string "alu")))
6148    (set (attr "length_immediate")
6149       (if_then_else
6150         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6151         (const_string "1")
6152         (const_string "*")))
6153    (set_attr "mode" "HI")])
6154
6155 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6156 ;; type optimizations enabled by define-splits.  This is not important
6157 ;; for PII, and in fact harmful because of partial register stalls.
6158
6159 (define_insn "*addhi_1_lea"
6160   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6161         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6162                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6163    (clobber (reg:CC FLAGS_REG))]
6164   "!TARGET_PARTIAL_REG_STALL
6165    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6166 {
6167   switch (get_attr_type (insn))
6168     {
6169     case TYPE_LEA:
6170       return "#";
6171     case TYPE_INCDEC:
6172       if (operands[2] == const1_rtx)
6173         return "inc{w}\t%0";
6174       else
6175         {
6176           gcc_assert (operands[2] == constm1_rtx);
6177           return "dec{w}\t%0";
6178         }
6179
6180     default:
6181       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6182          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6183       if (CONST_INT_P (operands[2])
6184           && (INTVAL (operands[2]) == 128
6185               || (INTVAL (operands[2]) < 0
6186                   && INTVAL (operands[2]) != -128)))
6187         {
6188           operands[2] = GEN_INT (-INTVAL (operands[2]));
6189           return "sub{w}\t{%2, %0|%0, %2}";
6190         }
6191       return "add{w}\t{%2, %0|%0, %2}";
6192     }
6193 }
6194   [(set (attr "type")
6195      (if_then_else (eq_attr "alternative" "2")
6196         (const_string "lea")
6197         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6198            (const_string "incdec")
6199            (const_string "alu"))))
6200    (set (attr "length_immediate")
6201       (if_then_else
6202         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6203         (const_string "1")
6204         (const_string "*")))
6205    (set_attr "mode" "HI,HI,SI")])
6206
6207 (define_insn "*addqi_1"
6208   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6209         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6210                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6211    (clobber (reg:CC FLAGS_REG))]
6212   "TARGET_PARTIAL_REG_STALL
6213    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6214 {
6215   int widen = (which_alternative == 2);
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == const1_rtx)
6220         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx);
6224           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6225         }
6226
6227     default:
6228       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6229          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6230       if (CONST_INT_P (operands[2])
6231           && (INTVAL (operands[2]) == 128
6232               || (INTVAL (operands[2]) < 0
6233                   && INTVAL (operands[2]) != -128)))
6234         {
6235           operands[2] = GEN_INT (-INTVAL (operands[2]));
6236           if (widen)
6237             return "sub{l}\t{%2, %k0|%k0, %2}";
6238           else
6239             return "sub{b}\t{%2, %0|%0, %2}";
6240         }
6241       if (widen)
6242         return "add{l}\t{%k2, %k0|%k0, %k2}";
6243       else
6244         return "add{b}\t{%2, %0|%0, %2}";
6245     }
6246 }
6247   [(set (attr "type")
6248      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6249         (const_string "incdec")
6250         (const_string "alu")))
6251    (set (attr "length_immediate")
6252       (if_then_else
6253         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6254         (const_string "1")
6255         (const_string "*")))
6256    (set_attr "mode" "QI,QI,SI")])
6257
6258 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6259 (define_insn "*addqi_1_lea"
6260   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6261         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6262                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6263    (clobber (reg:CC FLAGS_REG))]
6264   "!TARGET_PARTIAL_REG_STALL
6265    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6266 {
6267   int widen = (which_alternative == 2);
6268   switch (get_attr_type (insn))
6269     {
6270     case TYPE_LEA:
6271       return "#";
6272     case TYPE_INCDEC:
6273       if (operands[2] == const1_rtx)
6274         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6275       else
6276         {
6277           gcc_assert (operands[2] == constm1_rtx);
6278           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6279         }
6280
6281     default:
6282       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6283          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6284       if (CONST_INT_P (operands[2])
6285           && (INTVAL (operands[2]) == 128
6286               || (INTVAL (operands[2]) < 0
6287                   && INTVAL (operands[2]) != -128)))
6288         {
6289           operands[2] = GEN_INT (-INTVAL (operands[2]));
6290           if (widen)
6291             return "sub{l}\t{%2, %k0|%k0, %2}";
6292           else
6293             return "sub{b}\t{%2, %0|%0, %2}";
6294         }
6295       if (widen)
6296         return "add{l}\t{%k2, %k0|%k0, %k2}";
6297       else
6298         return "add{b}\t{%2, %0|%0, %2}";
6299     }
6300 }
6301   [(set (attr "type")
6302      (if_then_else (eq_attr "alternative" "3")
6303         (const_string "lea")
6304         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6305            (const_string "incdec")
6306            (const_string "alu"))))
6307    (set (attr "length_immediate")
6308       (if_then_else
6309         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6310         (const_string "1")
6311         (const_string "*")))
6312    (set_attr "mode" "QI,QI,SI,SI")])
6313
6314 (define_insn "*addqi_1_slp"
6315   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6316         (plus:QI (match_dup 0)
6317                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6318    (clobber (reg:CC FLAGS_REG))]
6319   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6320    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6321 {
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[1] == const1_rtx)
6326         return "inc{b}\t%0";
6327       else
6328         {
6329           gcc_assert (operands[1] == constm1_rtx);
6330           return "dec{b}\t%0";
6331         }
6332
6333     default:
6334       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6335       if (CONST_INT_P (operands[1])
6336           && INTVAL (operands[1]) < 0)
6337         {
6338           operands[1] = GEN_INT (-INTVAL (operands[1]));
6339           return "sub{b}\t{%1, %0|%0, %1}";
6340         }
6341       return "add{b}\t{%1, %0|%0, %1}";
6342     }
6343 }
6344   [(set (attr "type")
6345      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6346         (const_string "incdec")
6347         (const_string "alu1")))
6348    (set (attr "memory")
6349      (if_then_else (match_operand 1 "memory_operand" "")
6350         (const_string "load")
6351         (const_string "none")))
6352    (set_attr "mode" "QI")])
6353
6354 (define_insn "*add<mode>_2"
6355   [(set (reg FLAGS_REG)
6356         (compare
6357           (plus:SWI48
6358             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6359             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6360           (const_int 0)))
6361    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6362         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6363   "ix86_match_ccmode (insn, CCGOCmode)
6364    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6365    /* Current assemblers are broken and do not allow @GOTOFF in
6366       ought but a memory context.  */
6367    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6368 {
6369   switch (get_attr_type (insn))
6370     {
6371     case TYPE_INCDEC:
6372       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373       if (operands[2] == const1_rtx)
6374         return "inc{<imodesuffix>}\t%0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx);
6378           return "dec{<imodesuffix>}\t%0";
6379         }
6380
6381     default:
6382       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6383       /* ???? In DImode, we ought to handle there the 32bit case too
6384          - do we need new constraint?  */
6385       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6386          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6387       if (CONST_INT_P (operands[2])
6388           /* Avoid overflows.  */
6389           && (<MODE>mode != DImode
6390               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6391           && (INTVAL (operands[2]) == 128
6392               || (INTVAL (operands[2]) < 0
6393                   && INTVAL (operands[2]) != -128)))
6394         {
6395           operands[2] = GEN_INT (-INTVAL (operands[2]));
6396           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6397         }
6398       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6399     }
6400 }
6401   [(set (attr "type")
6402      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6403         (const_string "incdec")
6404         (const_string "alu")))
6405    (set (attr "length_immediate")
6406       (if_then_else
6407         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6408         (const_string "1")
6409         (const_string "*")))
6410    (set_attr "mode" "<MODE>")])
6411
6412 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6413 (define_insn "*addsi_2_zext"
6414   [(set (reg FLAGS_REG)
6415         (compare
6416           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6417                    (match_operand:SI 2 "general_operand" "g"))
6418           (const_int 0)))
6419    (set (match_operand:DI 0 "register_operand" "=r")
6420         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6421   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6422    && ix86_binary_operator_ok (PLUS, SImode, operands)
6423    /* Current assemblers are broken and do not allow @GOTOFF in
6424       ought but a memory context.  */
6425    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6426 {
6427   switch (get_attr_type (insn))
6428     {
6429     case TYPE_INCDEC:
6430       if (operands[2] == const1_rtx)
6431         return "inc{l}\t%k0";
6432       else
6433         {
6434           gcc_assert (operands[2] == constm1_rtx);
6435           return "dec{l}\t%k0";
6436         }
6437
6438     default:
6439       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6440          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6441       if (CONST_INT_P (operands[2])
6442           && (INTVAL (operands[2]) == 128
6443               || (INTVAL (operands[2]) < 0
6444                   && INTVAL (operands[2]) != -128)))
6445         {
6446           operands[2] = GEN_INT (-INTVAL (operands[2]));
6447           return "sub{l}\t{%2, %k0|%k0, %2}";
6448         }
6449       return "add{l}\t{%2, %k0|%k0, %2}";
6450     }
6451 }
6452   [(set (attr "type")
6453      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6454         (const_string "incdec")
6455         (const_string "alu")))
6456    (set (attr "length_immediate")
6457       (if_then_else
6458         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6459         (const_string "1")
6460         (const_string "*")))
6461    (set_attr "mode" "SI")])
6462
6463 (define_insn "*addhi_2"
6464   [(set (reg FLAGS_REG)
6465         (compare
6466           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6467                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6468           (const_int 0)))
6469    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6470         (plus:HI (match_dup 1) (match_dup 2)))]
6471   "ix86_match_ccmode (insn, CCGOCmode)
6472    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6473 {
6474   switch (get_attr_type (insn))
6475     {
6476     case TYPE_INCDEC:
6477       if (operands[2] == const1_rtx)
6478         return "inc{w}\t%0";
6479       else
6480         {
6481           gcc_assert (operands[2] == constm1_rtx);
6482           return "dec{w}\t%0";
6483         }
6484
6485     default:
6486       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6487          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6488       if (CONST_INT_P (operands[2])
6489           && (INTVAL (operands[2]) == 128
6490               || (INTVAL (operands[2]) < 0
6491                   && INTVAL (operands[2]) != -128)))
6492         {
6493           operands[2] = GEN_INT (-INTVAL (operands[2]));
6494           return "sub{w}\t{%2, %0|%0, %2}";
6495         }
6496       return "add{w}\t{%2, %0|%0, %2}";
6497     }
6498 }
6499   [(set (attr "type")
6500      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6501         (const_string "incdec")
6502         (const_string "alu")))
6503    (set (attr "length_immediate")
6504       (if_then_else
6505         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6506         (const_string "1")
6507         (const_string "*")))
6508    (set_attr "mode" "HI")])
6509
6510 (define_insn "*addqi_2"
6511   [(set (reg FLAGS_REG)
6512         (compare
6513           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6514                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6515           (const_int 0)))
6516    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6517         (plus:QI (match_dup 1) (match_dup 2)))]
6518   "ix86_match_ccmode (insn, CCGOCmode)
6519    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6520 {
6521   switch (get_attr_type (insn))
6522     {
6523     case TYPE_INCDEC:
6524       if (operands[2] == const1_rtx)
6525         return "inc{b}\t%0";
6526       else
6527         {
6528           gcc_assert (operands[2] == constm1_rtx
6529                       || (CONST_INT_P (operands[2])
6530                           && INTVAL (operands[2]) == 255));
6531           return "dec{b}\t%0";
6532         }
6533
6534     default:
6535       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6536       if (CONST_INT_P (operands[2])
6537           && INTVAL (operands[2]) < 0)
6538         {
6539           operands[2] = GEN_INT (-INTVAL (operands[2]));
6540           return "sub{b}\t{%2, %0|%0, %2}";
6541         }
6542       return "add{b}\t{%2, %0|%0, %2}";
6543     }
6544 }
6545   [(set (attr "type")
6546      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6547         (const_string "incdec")
6548         (const_string "alu")))
6549    (set_attr "mode" "QI")])
6550
6551 (define_insn "*add<mode>_3"
6552   [(set (reg FLAGS_REG)
6553         (compare
6554           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6555           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6556    (clobber (match_scratch:SWI48 0 "=r"))]
6557   "ix86_match_ccmode (insn, CCZmode)
6558    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6559    /* Current assemblers are broken and do not allow @GOTOFF in
6560       ought but a memory context.  */
6561    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6562 {
6563   switch (get_attr_type (insn))
6564     {
6565     case TYPE_INCDEC:
6566       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6567       if (operands[2] == const1_rtx)
6568         return "inc{<imodesuffix>}\t%0";
6569       else
6570         {
6571           gcc_assert (operands[2] == constm1_rtx);
6572           return "dec{<imodesuffix>}\t%0";
6573         }
6574
6575     default:
6576       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6577       /* ???? In DImode, we ought to handle there the 32bit case too
6578          - do we need new constraint?  */
6579       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6580          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6581       if (CONST_INT_P (operands[2])
6582           /* Avoid overflows.  */
6583           && (<MODE>mode != DImode
6584               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6585           && (INTVAL (operands[2]) == 128
6586               || (INTVAL (operands[2]) < 0
6587                   && INTVAL (operands[2]) != -128)))
6588         {
6589           operands[2] = GEN_INT (-INTVAL (operands[2]));
6590           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6591         }
6592       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6593     }
6594 }
6595   [(set (attr "type")
6596      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6597         (const_string "incdec")
6598         (const_string "alu")))
6599    (set (attr "length_immediate")
6600       (if_then_else
6601         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6602         (const_string "1")
6603         (const_string "*")))
6604    (set_attr "mode" "<MODE>")])
6605
6606 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6607 (define_insn "*addsi_3_zext"
6608   [(set (reg FLAGS_REG)
6609         (compare
6610           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6611           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6612    (set (match_operand:DI 0 "register_operand" "=r")
6613         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6614   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6615    && ix86_binary_operator_ok (PLUS, SImode, operands)
6616    /* Current assemblers are broken and do not allow @GOTOFF in
6617       ought but a memory context.  */
6618    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6619 {
6620   switch (get_attr_type (insn))
6621     {
6622     case TYPE_INCDEC:
6623       if (operands[2] == const1_rtx)
6624         return "inc{l}\t%k0";
6625       else
6626         {
6627           gcc_assert (operands[2] == constm1_rtx);
6628           return "dec{l}\t%k0";
6629         }
6630
6631     default:
6632       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6633          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6634       if (CONST_INT_P (operands[2])
6635           && (INTVAL (operands[2]) == 128
6636               || (INTVAL (operands[2]) < 0
6637                   && INTVAL (operands[2]) != -128)))
6638         {
6639           operands[2] = GEN_INT (-INTVAL (operands[2]));
6640           return "sub{l}\t{%2, %k0|%k0, %2}";
6641         }
6642       return "add{l}\t{%2, %k0|%k0, %2}";
6643     }
6644 }
6645   [(set (attr "type")
6646      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6647         (const_string "incdec")
6648         (const_string "alu")))
6649    (set (attr "length_immediate")
6650       (if_then_else
6651         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6652         (const_string "1")
6653         (const_string "*")))
6654    (set_attr "mode" "SI")])
6655
6656 (define_insn "*addhi_3"
6657   [(set (reg FLAGS_REG)
6658         (compare
6659           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6660           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6661    (clobber (match_scratch:HI 0 "=r"))]
6662   "ix86_match_ccmode (insn, CCZmode)
6663    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6664 {
6665   switch (get_attr_type (insn))
6666     {
6667     case TYPE_INCDEC:
6668       if (operands[2] == const1_rtx)
6669         return "inc{w}\t%0";
6670       else
6671         {
6672           gcc_assert (operands[2] == constm1_rtx);
6673           return "dec{w}\t%0";
6674         }
6675
6676     default:
6677       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6678          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6679       if (CONST_INT_P (operands[2])
6680           && (INTVAL (operands[2]) == 128
6681               || (INTVAL (operands[2]) < 0
6682                   && INTVAL (operands[2]) != -128)))
6683         {
6684           operands[2] = GEN_INT (-INTVAL (operands[2]));
6685           return "sub{w}\t{%2, %0|%0, %2}";
6686         }
6687       return "add{w}\t{%2, %0|%0, %2}";
6688     }
6689 }
6690   [(set (attr "type")
6691      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6692         (const_string "incdec")
6693         (const_string "alu")))
6694    (set (attr "length_immediate")
6695       (if_then_else
6696         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6697         (const_string "1")
6698         (const_string "*")))
6699    (set_attr "mode" "HI")])
6700
6701 (define_insn "*addqi_3"
6702   [(set (reg FLAGS_REG)
6703         (compare
6704           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6705           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6706    (clobber (match_scratch:QI 0 "=q"))]
6707   "ix86_match_ccmode (insn, CCZmode)
6708    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 {
6710   switch (get_attr_type (insn))
6711     {
6712     case TYPE_INCDEC:
6713       if (operands[2] == const1_rtx)
6714         return "inc{b}\t%0";
6715       else
6716         {
6717           gcc_assert (operands[2] == constm1_rtx
6718                       || (CONST_INT_P (operands[2])
6719                           && INTVAL (operands[2]) == 255));
6720           return "dec{b}\t%0";
6721         }
6722
6723     default:
6724       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6725       if (CONST_INT_P (operands[2])
6726           && INTVAL (operands[2]) < 0)
6727         {
6728           operands[2] = GEN_INT (-INTVAL (operands[2]));
6729           return "sub{b}\t{%2, %0|%0, %2}";
6730         }
6731       return "add{b}\t{%2, %0|%0, %2}";
6732     }
6733 }
6734   [(set (attr "type")
6735      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6736         (const_string "incdec")
6737         (const_string "alu")))
6738    (set_attr "mode" "QI")])
6739
6740 ; For comparisons against 1, -1 and 128, we may generate better code
6741 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6742 ; is matched then.  We can't accept general immediate, because for
6743 ; case of overflows,  the result is messed up.
6744 ; This pattern also don't hold of 0x8000000000000000, since the value
6745 ; overflows when negated.
6746 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6747 ; only for comparisons not depending on it.
6748
6749 (define_insn "*adddi_4"
6750   [(set (reg FLAGS_REG)
6751         (compare
6752           (match_operand:DI 1 "nonimmediate_operand" "0")
6753           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6754    (clobber (match_scratch:DI 0 "=rm"))]
6755   "TARGET_64BIT
6756    && ix86_match_ccmode (insn, CCGCmode)"
6757 {
6758   switch (get_attr_type (insn))
6759     {
6760     case TYPE_INCDEC:
6761       if (operands[2] == constm1_rtx)
6762         return "inc{q}\t%0";
6763       else
6764         {
6765           gcc_assert (operands[2] == const1_rtx);
6766           return "dec{q}\t%0";
6767         }
6768
6769     default:
6770       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6771       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6772          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6773       if ((INTVAL (operands[2]) == -128
6774            || (INTVAL (operands[2]) > 0
6775                && INTVAL (operands[2]) != 128))
6776           /* Avoid overflows.  */
6777           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6778         return "sub{q}\t{%2, %0|%0, %2}";
6779       operands[2] = GEN_INT (-INTVAL (operands[2]));
6780       return "add{q}\t{%2, %0|%0, %2}";
6781     }
6782 }
6783   [(set (attr "type")
6784      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6785         (const_string "incdec")
6786         (const_string "alu")))
6787    (set (attr "length_immediate")
6788       (if_then_else
6789         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6790         (const_string "1")
6791         (const_string "*")))
6792    (set_attr "mode" "DI")])
6793
6794 ; For comparisons against 1, -1 and 128, we may generate better code
6795 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6796 ; is matched then.  We can't accept general immediate, because for
6797 ; case of overflows,  the result is messed up.
6798 ; This pattern also don't hold of 0x80000000, since the value overflows
6799 ; when negated.
6800 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6801 ; only for comparisons not depending on it.
6802
6803 (define_insn "*addsi_4"
6804   [(set (reg FLAGS_REG)
6805         (compare
6806           (match_operand:SI 1 "nonimmediate_operand" "0")
6807           (match_operand:SI 2 "const_int_operand" "n")))
6808    (clobber (match_scratch:SI 0 "=rm"))]
6809   "ix86_match_ccmode (insn, CCGCmode)
6810    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6811 {
6812   switch (get_attr_type (insn))
6813     {
6814     case TYPE_INCDEC:
6815       if (operands[2] == constm1_rtx)
6816         return "inc{l}\t%0";
6817       else
6818         {
6819           gcc_assert (operands[2] == const1_rtx);
6820           return "dec{l}\t%0";
6821         }
6822
6823     default:
6824       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6825       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6826          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6827       if ((INTVAL (operands[2]) == -128
6828            || (INTVAL (operands[2]) > 0
6829                && INTVAL (operands[2]) != 128)))
6830         return "sub{l}\t{%2, %0|%0, %2}";
6831       operands[2] = GEN_INT (-INTVAL (operands[2]));
6832       return "add{l}\t{%2, %0|%0, %2}";
6833     }
6834 }
6835   [(set (attr "type")
6836      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6837         (const_string "incdec")
6838         (const_string "alu")))
6839    (set (attr "length_immediate")
6840       (if_then_else
6841         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6842         (const_string "1")
6843         (const_string "*")))
6844    (set_attr "mode" "SI")])
6845
6846 ; See comments above addsi_4 for details.
6847
6848 (define_insn "*addhi_4"
6849   [(set (reg FLAGS_REG)
6850         (compare
6851           (match_operand:HI 1 "nonimmediate_operand" "0")
6852           (match_operand:HI 2 "const_int_operand" "n")))
6853    (clobber (match_scratch:HI 0 "=rm"))]
6854   "ix86_match_ccmode (insn, CCGCmode)
6855    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6856 {
6857   switch (get_attr_type (insn))
6858     {
6859     case TYPE_INCDEC:
6860       if (operands[2] == constm1_rtx)
6861         return "inc{w}\t%0";
6862       else
6863         {
6864           gcc_assert (operands[2] == const1_rtx);
6865           return "dec{w}\t%0";
6866         }
6867
6868     default:
6869       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6870       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6871          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6872       if ((INTVAL (operands[2]) == -128
6873            || (INTVAL (operands[2]) > 0
6874                && INTVAL (operands[2]) != 128)))
6875         return "sub{w}\t{%2, %0|%0, %2}";
6876       operands[2] = GEN_INT (-INTVAL (operands[2]));
6877       return "add{w}\t{%2, %0|%0, %2}";
6878     }
6879 }
6880   [(set (attr "type")
6881      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6882         (const_string "incdec")
6883         (const_string "alu")))
6884    (set (attr "length_immediate")
6885       (if_then_else
6886         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6887         (const_string "1")
6888         (const_string "*")))
6889    (set_attr "mode" "HI")])
6890
6891 ; See comments above addsi_4 for details.
6892
6893 (define_insn "*addqi_4"
6894   [(set (reg FLAGS_REG)
6895         (compare
6896           (match_operand:QI 1 "nonimmediate_operand" "0")
6897           (match_operand:QI 2 "const_int_operand" "n")))
6898    (clobber (match_scratch:QI 0 "=qm"))]
6899   "ix86_match_ccmode (insn, CCGCmode)
6900    && (INTVAL (operands[2]) & 0xff) != 0x80"
6901 {
6902   switch (get_attr_type (insn))
6903     {
6904     case TYPE_INCDEC:
6905       if (operands[2] == constm1_rtx
6906           || (CONST_INT_P (operands[2])
6907               && INTVAL (operands[2]) == 255))
6908         return "inc{b}\t%0";
6909       else
6910         {
6911           gcc_assert (operands[2] == const1_rtx);
6912           return "dec{b}\t%0";
6913         }
6914
6915     default:
6916       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6917       if (INTVAL (operands[2]) < 0)
6918         {
6919           operands[2] = GEN_INT (-INTVAL (operands[2]));
6920           return "add{b}\t{%2, %0|%0, %2}";
6921         }
6922       return "sub{b}\t{%2, %0|%0, %2}";
6923     }
6924 }
6925   [(set (attr "type")
6926      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6927         (const_string "incdec")
6928         (const_string "alu")))
6929    (set_attr "mode" "QI")])
6930
6931 (define_insn "*add<mode>_5"
6932   [(set (reg FLAGS_REG)
6933         (compare
6934           (plus:SWI48
6935             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6936             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6937           (const_int 0)))
6938    (clobber (match_scratch:SWI48 0 "=r"))]
6939   "ix86_match_ccmode (insn, CCGOCmode)
6940    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6941    /* Current assemblers are broken and do not allow @GOTOFF in
6942       ought but a memory context.  */
6943    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6944 {
6945   switch (get_attr_type (insn))
6946     {
6947     case TYPE_INCDEC:
6948       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6949       if (operands[2] == const1_rtx)
6950         return "inc{<imodesuffix>}\t%0";
6951       else
6952         {
6953           gcc_assert (operands[2] == constm1_rtx);
6954           return "dec{<imodesuffix>}\t%0";
6955         }
6956
6957     default:
6958       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6959       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6960          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6961       if (CONST_INT_P (operands[2])
6962           /* Avoid overflows.  */
6963           && (<MODE>mode != DImode
6964               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6965           && (INTVAL (operands[2]) == 128
6966               || (INTVAL (operands[2]) < 0
6967                   && INTVAL (operands[2]) != -128)))
6968         {
6969           operands[2] = GEN_INT (-INTVAL (operands[2]));
6970           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6971         }
6972       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6973     }
6974 }
6975   [(set (attr "type")
6976      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6977         (const_string "incdec")
6978         (const_string "alu")))
6979    (set (attr "length_immediate")
6980       (if_then_else
6981         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6982         (const_string "1")
6983         (const_string "*")))
6984    (set_attr "mode" "<MODE>")])
6985
6986 (define_insn "*addhi_5"
6987   [(set (reg FLAGS_REG)
6988         (compare
6989           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6990                    (match_operand:HI 2 "general_operand" "rmn"))
6991           (const_int 0)))
6992    (clobber (match_scratch:HI 0 "=r"))]
6993   "ix86_match_ccmode (insn, CCGOCmode)
6994    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6995 {
6996   switch (get_attr_type (insn))
6997     {
6998     case TYPE_INCDEC:
6999       if (operands[2] == const1_rtx)
7000         return "inc{w}\t%0";
7001       else
7002         {
7003           gcc_assert (operands[2] == constm1_rtx);
7004           return "dec{w}\t%0";
7005         }
7006
7007     default:
7008       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7009          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7010       if (CONST_INT_P (operands[2])
7011           && (INTVAL (operands[2]) == 128
7012               || (INTVAL (operands[2]) < 0
7013                   && INTVAL (operands[2]) != -128)))
7014         {
7015           operands[2] = GEN_INT (-INTVAL (operands[2]));
7016           return "sub{w}\t{%2, %0|%0, %2}";
7017         }
7018       return "add{w}\t{%2, %0|%0, %2}";
7019     }
7020 }
7021   [(set (attr "type")
7022      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7023         (const_string "incdec")
7024         (const_string "alu")))
7025    (set (attr "length_immediate")
7026       (if_then_else
7027         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7028         (const_string "1")
7029         (const_string "*")))
7030    (set_attr "mode" "HI")])
7031
7032 (define_insn "*addqi_5"
7033   [(set (reg FLAGS_REG)
7034         (compare
7035           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7036                    (match_operand:QI 2 "general_operand" "qmn"))
7037           (const_int 0)))
7038    (clobber (match_scratch:QI 0 "=q"))]
7039   "ix86_match_ccmode (insn, CCGOCmode)
7040    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7041 {
7042   switch (get_attr_type (insn))
7043     {
7044     case TYPE_INCDEC:
7045       if (operands[2] == const1_rtx)
7046         return "inc{b}\t%0";
7047       else
7048         {
7049           gcc_assert (operands[2] == constm1_rtx
7050                       || (CONST_INT_P (operands[2])
7051                           && INTVAL (operands[2]) == 255));
7052           return "dec{b}\t%0";
7053         }
7054
7055     default:
7056       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7057       if (CONST_INT_P (operands[2])
7058           && INTVAL (operands[2]) < 0)
7059         {
7060           operands[2] = GEN_INT (-INTVAL (operands[2]));
7061           return "sub{b}\t{%2, %0|%0, %2}";
7062         }
7063       return "add{b}\t{%2, %0|%0, %2}";
7064     }
7065 }
7066   [(set (attr "type")
7067      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7068         (const_string "incdec")
7069         (const_string "alu")))
7070    (set_attr "mode" "QI")])
7071
7072 (define_insn "*addqi_ext_1_rex64"
7073   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7074                          (const_int 8)
7075                          (const_int 8))
7076         (plus:SI
7077           (zero_extract:SI
7078             (match_operand 1 "ext_register_operand" "0")
7079             (const_int 8)
7080             (const_int 8))
7081           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_64BIT"
7084 {
7085   switch (get_attr_type (insn))
7086     {
7087     case TYPE_INCDEC:
7088       if (operands[2] == const1_rtx)
7089         return "inc{b}\t%h0";
7090       else
7091         {
7092           gcc_assert (operands[2] == constm1_rtx
7093                       || (CONST_INT_P (operands[2])
7094                           && INTVAL (operands[2]) == 255));
7095           return "dec{b}\t%h0";
7096         }
7097
7098     default:
7099       return "add{b}\t{%2, %h0|%h0, %2}";
7100     }
7101 }
7102   [(set (attr "type")
7103      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7104         (const_string "incdec")
7105         (const_string "alu")))
7106    (set_attr "modrm" "1")
7107    (set_attr "mode" "QI")])
7108
7109 (define_insn "addqi_ext_1"
7110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7111                          (const_int 8)
7112                          (const_int 8))
7113         (plus:SI
7114           (zero_extract:SI
7115             (match_operand 1 "ext_register_operand" "0")
7116             (const_int 8)
7117             (const_int 8))
7118           (match_operand:QI 2 "general_operand" "Qmn")))
7119    (clobber (reg:CC FLAGS_REG))]
7120   "!TARGET_64BIT"
7121 {
7122   switch (get_attr_type (insn))
7123     {
7124     case TYPE_INCDEC:
7125       if (operands[2] == const1_rtx)
7126         return "inc{b}\t%h0";
7127       else
7128         {
7129           gcc_assert (operands[2] == constm1_rtx
7130                       || (CONST_INT_P (operands[2])
7131                           && INTVAL (operands[2]) == 255));
7132           return "dec{b}\t%h0";
7133         }
7134
7135     default:
7136       return "add{b}\t{%2, %h0|%h0, %2}";
7137     }
7138 }
7139   [(set (attr "type")
7140      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7141         (const_string "incdec")
7142         (const_string "alu")))
7143    (set_attr "modrm" "1")
7144    (set_attr "mode" "QI")])
7145
7146 (define_insn "*addqi_ext_2"
7147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7148                          (const_int 8)
7149                          (const_int 8))
7150         (plus:SI
7151           (zero_extract:SI
7152             (match_operand 1 "ext_register_operand" "%0")
7153             (const_int 8)
7154             (const_int 8))
7155           (zero_extract:SI
7156             (match_operand 2 "ext_register_operand" "Q")
7157             (const_int 8)
7158             (const_int 8))))
7159    (clobber (reg:CC FLAGS_REG))]
7160   ""
7161   "add{b}\t{%h2, %h0|%h0, %h2}"
7162   [(set_attr "type" "alu")
7163    (set_attr "mode" "QI")])
7164
7165 ;; The lea patterns for non-Pmodes needs to be matched by
7166 ;; several insns converted to real lea by splitters.
7167
7168 (define_insn_and_split "*lea_general_1"
7169   [(set (match_operand 0 "register_operand" "=r")
7170         (plus (plus (match_operand 1 "index_register_operand" "l")
7171                     (match_operand 2 "register_operand" "r"))
7172               (match_operand 3 "immediate_operand" "i")))]
7173   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7174     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7175    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7176    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7177    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7178    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7179        || GET_MODE (operands[3]) == VOIDmode)"
7180   "#"
7181   "&& reload_completed"
7182   [(const_int 0)]
7183 {
7184   rtx pat;
7185   operands[0] = gen_lowpart (SImode, operands[0]);
7186   operands[1] = gen_lowpart (Pmode, operands[1]);
7187   operands[2] = gen_lowpart (Pmode, operands[2]);
7188   operands[3] = gen_lowpart (Pmode, operands[3]);
7189   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7190                       operands[3]);
7191   if (Pmode != SImode)
7192     pat = gen_rtx_SUBREG (SImode, pat, 0);
7193   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7194   DONE;
7195 }
7196   [(set_attr "type" "lea")
7197    (set_attr "mode" "SI")])
7198
7199 (define_insn_and_split "*lea_general_1_zext"
7200   [(set (match_operand:DI 0 "register_operand" "=r")
7201         (zero_extend:DI
7202           (plus:SI (plus:SI
7203                      (match_operand:SI 1 "index_register_operand" "l")
7204                      (match_operand:SI 2 "register_operand" "r"))
7205                    (match_operand:SI 3 "immediate_operand" "i"))))]
7206   "TARGET_64BIT"
7207   "#"
7208   "&& reload_completed"
7209   [(set (match_dup 0)
7210         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7211                                                      (match_dup 2))
7212                                             (match_dup 3)) 0)))]
7213 {
7214   operands[1] = gen_lowpart (Pmode, operands[1]);
7215   operands[2] = gen_lowpart (Pmode, operands[2]);
7216   operands[3] = gen_lowpart (Pmode, operands[3]);
7217 }
7218   [(set_attr "type" "lea")
7219    (set_attr "mode" "SI")])
7220
7221 (define_insn_and_split "*lea_general_2"
7222   [(set (match_operand 0 "register_operand" "=r")
7223         (plus (mult (match_operand 1 "index_register_operand" "l")
7224                     (match_operand 2 "const248_operand" "i"))
7225               (match_operand 3 "nonmemory_operand" "ri")))]
7226   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7227     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7228    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7229    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7230    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7231        || GET_MODE (operands[3]) == VOIDmode)"
7232   "#"
7233   "&& reload_completed"
7234   [(const_int 0)]
7235 {
7236   rtx pat;
7237   operands[0] = gen_lowpart (SImode, operands[0]);
7238   operands[1] = gen_lowpart (Pmode, operands[1]);
7239   operands[3] = gen_lowpart (Pmode, operands[3]);
7240   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7241                       operands[3]);
7242   if (Pmode != SImode)
7243     pat = gen_rtx_SUBREG (SImode, pat, 0);
7244   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7245   DONE;
7246 }
7247   [(set_attr "type" "lea")
7248    (set_attr "mode" "SI")])
7249
7250 (define_insn_and_split "*lea_general_2_zext"
7251   [(set (match_operand:DI 0 "register_operand" "=r")
7252         (zero_extend:DI
7253           (plus:SI (mult:SI
7254                      (match_operand:SI 1 "index_register_operand" "l")
7255                      (match_operand:SI 2 "const248_operand" "n"))
7256                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7257   "TARGET_64BIT"
7258   "#"
7259   "&& reload_completed"
7260   [(set (match_dup 0)
7261         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7262                                                      (match_dup 2))
7263                                             (match_dup 3)) 0)))]
7264 {
7265   operands[1] = gen_lowpart (Pmode, operands[1]);
7266   operands[3] = gen_lowpart (Pmode, operands[3]);
7267 }
7268   [(set_attr "type" "lea")
7269    (set_attr "mode" "SI")])
7270
7271 (define_insn_and_split "*lea_general_3"
7272   [(set (match_operand 0 "register_operand" "=r")
7273         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7274                           (match_operand 2 "const248_operand" "i"))
7275                     (match_operand 3 "register_operand" "r"))
7276               (match_operand 4 "immediate_operand" "i")))]
7277   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7278     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7279    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7280    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7281    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7282   "#"
7283   "&& reload_completed"
7284   [(const_int 0)]
7285 {
7286   rtx pat;
7287   operands[0] = gen_lowpart (SImode, operands[0]);
7288   operands[1] = gen_lowpart (Pmode, operands[1]);
7289   operands[3] = gen_lowpart (Pmode, operands[3]);
7290   operands[4] = gen_lowpart (Pmode, operands[4]);
7291   pat = gen_rtx_PLUS (Pmode,
7292                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7293                                                          operands[2]),
7294                                     operands[3]),
7295                       operands[4]);
7296   if (Pmode != SImode)
7297     pat = gen_rtx_SUBREG (SImode, pat, 0);
7298   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7299   DONE;
7300 }
7301   [(set_attr "type" "lea")
7302    (set_attr "mode" "SI")])
7303
7304 (define_insn_and_split "*lea_general_3_zext"
7305   [(set (match_operand:DI 0 "register_operand" "=r")
7306         (zero_extend:DI
7307           (plus:SI (plus:SI
7308                      (mult:SI
7309                        (match_operand:SI 1 "index_register_operand" "l")
7310                        (match_operand:SI 2 "const248_operand" "n"))
7311                      (match_operand:SI 3 "register_operand" "r"))
7312                    (match_operand:SI 4 "immediate_operand" "i"))))]
7313   "TARGET_64BIT"
7314   "#"
7315   "&& reload_completed"
7316   [(set (match_dup 0)
7317         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7318                                                               (match_dup 2))
7319                                                      (match_dup 3))
7320                                             (match_dup 4)) 0)))]
7321 {
7322   operands[1] = gen_lowpart (Pmode, operands[1]);
7323   operands[3] = gen_lowpart (Pmode, operands[3]);
7324   operands[4] = gen_lowpart (Pmode, operands[4]);
7325 }
7326   [(set_attr "type" "lea")
7327    (set_attr "mode" "SI")])
7328
7329 ;; Convert lea to the lea pattern to avoid flags dependency.
7330 (define_split
7331   [(set (match_operand:DI 0 "register_operand" "")
7332         (plus:DI (match_operand:DI 1 "register_operand" "")
7333                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7334    (clobber (reg:CC FLAGS_REG))]
7335   "TARGET_64BIT && reload_completed 
7336    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7337   [(set (match_dup 0)
7338         (plus:DI (match_dup 1)
7339                  (match_dup 2)))]
7340   "")
7341
7342 ;; Convert lea to the lea pattern to avoid flags dependency.
7343 (define_split
7344   [(set (match_operand 0 "register_operand" "")
7345         (plus (match_operand 1 "register_operand" "")
7346               (match_operand 2 "nonmemory_operand" "")))
7347    (clobber (reg:CC FLAGS_REG))]
7348   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7349   [(const_int 0)]
7350 {
7351   rtx pat;
7352   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7353      may confuse gen_lowpart.  */
7354   if (GET_MODE (operands[0]) != Pmode)
7355     {
7356       operands[1] = gen_lowpart (Pmode, operands[1]);
7357       operands[2] = gen_lowpart (Pmode, operands[2]);
7358     }
7359   operands[0] = gen_lowpart (SImode, operands[0]);
7360   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7361   if (Pmode != SImode)
7362     pat = gen_rtx_SUBREG (SImode, pat, 0);
7363   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7364   DONE;
7365 })
7366
7367 ;; Convert lea to the lea pattern to avoid flags dependency.
7368 (define_split
7369   [(set (match_operand:DI 0 "register_operand" "")
7370         (zero_extend:DI
7371           (plus:SI (match_operand:SI 1 "register_operand" "")
7372                    (match_operand:SI 2 "nonmemory_operand" ""))))
7373    (clobber (reg:CC FLAGS_REG))]
7374   "TARGET_64BIT && reload_completed
7375    && true_regnum (operands[0]) != true_regnum (operands[1])"
7376   [(set (match_dup 0)
7377         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7378 {
7379   operands[1] = gen_lowpart (Pmode, operands[1]);
7380   operands[2] = gen_lowpart (Pmode, operands[2]);
7381 })
7382 \f
7383 ;; Subtract instructions
7384
7385 (define_expand "sub<mode>3"
7386   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7387         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7388                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7389   ""
7390   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7391
7392 (define_insn_and_split "*sub<dwi>3_doubleword"
7393   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7394         (minus:<DWI>
7395           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7396           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7397    (clobber (reg:CC FLAGS_REG))]
7398   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7399   "#"
7400   "reload_completed"
7401   [(parallel [(set (reg:CC FLAGS_REG)
7402                    (compare:CC (match_dup 1) (match_dup 2)))
7403               (set (match_dup 0)
7404                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7405    (parallel [(set (match_dup 3)
7406                    (minus:DWIH
7407                      (match_dup 4)
7408                      (plus:DWIH
7409                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7410                        (match_dup 5))))
7411               (clobber (reg:CC FLAGS_REG))])]
7412   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7413
7414 (define_insn "*sub<mode>_1"
7415   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7416         (minus:SWI
7417           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7418           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7421   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7422   [(set_attr "type" "alu")
7423    (set_attr "mode" "<MODE>")])
7424
7425 (define_insn "*subsi_1_zext"
7426   [(set (match_operand:DI 0 "register_operand" "=r")
7427         (zero_extend:DI
7428           (minus:SI (match_operand:SI 1 "register_operand" "0")
7429                     (match_operand:SI 2 "general_operand" "g"))))
7430    (clobber (reg:CC FLAGS_REG))]
7431   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7432   "sub{l}\t{%2, %k0|%k0, %2}"
7433   [(set_attr "type" "alu")
7434    (set_attr "mode" "SI")])
7435
7436 (define_insn "*subqi_1_slp"
7437   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7438         (minus:QI (match_dup 0)
7439                   (match_operand:QI 1 "general_operand" "qn,qm")))
7440    (clobber (reg:CC FLAGS_REG))]
7441   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443   "sub{b}\t{%1, %0|%0, %1}"
7444   [(set_attr "type" "alu1")
7445    (set_attr "mode" "QI")])
7446
7447 (define_insn "*sub<mode>_2"
7448   [(set (reg FLAGS_REG)
7449         (compare
7450           (minus:SWI
7451             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7452             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7453           (const_int 0)))
7454    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7455         (minus:SWI (match_dup 1) (match_dup 2)))]
7456   "ix86_match_ccmode (insn, CCGOCmode)
7457    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7458   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7459   [(set_attr "type" "alu")
7460    (set_attr "mode" "<MODE>")])
7461
7462 (define_insn "*subsi_2_zext"
7463   [(set (reg FLAGS_REG)
7464         (compare
7465           (minus:SI (match_operand:SI 1 "register_operand" "0")
7466                     (match_operand:SI 2 "general_operand" "g"))
7467           (const_int 0)))
7468    (set (match_operand:DI 0 "register_operand" "=r")
7469         (zero_extend:DI
7470           (minus:SI (match_dup 1)
7471                     (match_dup 2))))]
7472   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7473    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7474   "sub{l}\t{%2, %k0|%k0, %2}"
7475   [(set_attr "type" "alu")
7476    (set_attr "mode" "SI")])
7477
7478 (define_insn "*sub<mode>_3"
7479   [(set (reg FLAGS_REG)
7480         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7481                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7482    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7483         (minus:SWI (match_dup 1) (match_dup 2)))]
7484   "ix86_match_ccmode (insn, CCmode)
7485    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7486   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7487   [(set_attr "type" "alu")
7488    (set_attr "mode" "<MODE>")])
7489
7490 (define_insn "*subsi_3_zext"
7491   [(set (reg FLAGS_REG)
7492         (compare (match_operand:SI 1 "register_operand" "0")
7493                  (match_operand:SI 2 "general_operand" "g")))
7494    (set (match_operand:DI 0 "register_operand" "=r")
7495         (zero_extend:DI
7496           (minus:SI (match_dup 1)
7497                     (match_dup 2))))]
7498   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7499    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7500   "sub{l}\t{%2, %1|%1, %2}"
7501   [(set_attr "type" "alu")
7502    (set_attr "mode" "SI")])
7503 \f
7504 ;; Add with carry and subtract with borrow
7505
7506 (define_expand "<plusminus_insn><mode>3_carry"
7507   [(parallel
7508     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7509           (plusminus:SWI
7510             (match_operand:SWI 1 "nonimmediate_operand" "")
7511             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7512                        [(match_operand 3 "flags_reg_operand" "")
7513                         (const_int 0)])
7514                       (match_operand:SWI 2 "<general_operand>" ""))))
7515      (clobber (reg:CC FLAGS_REG))])]
7516   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7517   "")
7518
7519 (define_insn "*<plusminus_insn><mode>3_carry"
7520   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7521         (plusminus:SWI
7522           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7523           (plus:SWI
7524             (match_operator 3 "ix86_carry_flag_operator"
7525              [(reg FLAGS_REG) (const_int 0)])
7526             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7527    (clobber (reg:CC FLAGS_REG))]
7528   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7529   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7530   [(set_attr "type" "alu")
7531    (set_attr "use_carry" "1")
7532    (set_attr "pent_pair" "pu")
7533    (set_attr "mode" "<MODE>")])
7534
7535 (define_insn "*addsi3_carry_zext"
7536   [(set (match_operand:DI 0 "register_operand" "=r")
7537         (zero_extend:DI
7538           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7539                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7540                              [(reg FLAGS_REG) (const_int 0)])
7541                             (match_operand:SI 2 "general_operand" "g")))))
7542    (clobber (reg:CC FLAGS_REG))]
7543   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7544   "adc{l}\t{%2, %k0|%k0, %2}"
7545   [(set_attr "type" "alu")
7546    (set_attr "use_carry" "1")
7547    (set_attr "pent_pair" "pu")
7548    (set_attr "mode" "SI")])
7549
7550 (define_insn "*subsi3_carry_zext"
7551   [(set (match_operand:DI 0 "register_operand" "=r")
7552         (zero_extend:DI
7553           (minus:SI (match_operand:SI 1 "register_operand" "0")
7554                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7555                               [(reg FLAGS_REG) (const_int 0)])
7556                              (match_operand:SI 2 "general_operand" "g")))))
7557    (clobber (reg:CC FLAGS_REG))]
7558   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7559   "sbb{l}\t{%2, %k0|%k0, %2}"
7560   [(set_attr "type" "alu")
7561    (set_attr "pent_pair" "pu")
7562    (set_attr "mode" "SI")])
7563 \f
7564 ;; Overflow setting add and subtract instructions
7565
7566 (define_insn "*add<mode>3_cconly_overflow"
7567   [(set (reg:CCC FLAGS_REG)
7568         (compare:CCC
7569           (plus:SWI
7570             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7571             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7572           (match_dup 1)))
7573    (clobber (match_scratch:SWI 0 "=<r>"))]
7574   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7575   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7576   [(set_attr "type" "alu")
7577    (set_attr "mode" "<MODE>")])
7578
7579 (define_insn "*sub<mode>3_cconly_overflow"
7580   [(set (reg:CCC FLAGS_REG)
7581         (compare:CCC
7582           (minus:SWI
7583             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7584             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7585           (match_dup 0)))]
7586   ""
7587   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7588   [(set_attr "type" "icmp")
7589    (set_attr "mode" "<MODE>")])
7590
7591 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7592   [(set (reg:CCC FLAGS_REG)
7593         (compare:CCC
7594             (plusminus:SWI
7595                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7596                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7597             (match_dup 1)))
7598    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7599         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7600   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7601   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7602   [(set_attr "type" "alu")
7603    (set_attr "mode" "<MODE>")])
7604
7605 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7606   [(set (reg:CCC FLAGS_REG)
7607         (compare:CCC
7608           (plusminus:SI
7609             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7610             (match_operand:SI 2 "general_operand" "g"))
7611           (match_dup 1)))
7612    (set (match_operand:DI 0 "register_operand" "=r")
7613         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7614   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7615   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7616   [(set_attr "type" "alu")
7617    (set_attr "mode" "SI")])
7618
7619 ;; The patterns that match these are at the end of this file.
7620
7621 (define_expand "<plusminus_insn>xf3"
7622   [(set (match_operand:XF 0 "register_operand" "")
7623         (plusminus:XF
7624           (match_operand:XF 1 "register_operand" "")
7625           (match_operand:XF 2 "register_operand" "")))]
7626   "TARGET_80387"
7627   "")
7628
7629 (define_expand "<plusminus_insn><mode>3"
7630   [(set (match_operand:MODEF 0 "register_operand" "")
7631         (plusminus:MODEF
7632           (match_operand:MODEF 1 "register_operand" "")
7633           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7634   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7635     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7636   "")
7637 \f
7638 ;; Multiply instructions
7639
7640 (define_expand "mul<mode>3"
7641   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7642                    (mult:SWIM248
7643                      (match_operand:SWIM248 1 "register_operand" "")
7644                      (match_operand:SWIM248 2 "<general_operand>" "")))
7645               (clobber (reg:CC FLAGS_REG))])]
7646   ""
7647   "")
7648
7649 (define_expand "mulqi3"
7650   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7651                    (mult:QI
7652                      (match_operand:QI 1 "register_operand" "")
7653                      (match_operand:QI 2 "nonimmediate_operand" "")))
7654               (clobber (reg:CC FLAGS_REG))])]
7655   "TARGET_QIMODE_MATH"
7656   "")
7657
7658 ;; On AMDFAM10
7659 ;; IMUL reg32/64, reg32/64, imm8        Direct
7660 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7661 ;; IMUL reg32/64, reg32/64, imm32       Direct
7662 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7663 ;; IMUL reg32/64, reg32/64              Direct
7664 ;; IMUL reg32/64, mem32/64              Direct
7665
7666 (define_insn "*mul<mode>3_1"
7667   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7668         (mult:SWI48
7669           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7670           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7671    (clobber (reg:CC FLAGS_REG))]
7672   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7673   "@
7674    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7675    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7676    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7677   [(set_attr "type" "imul")
7678    (set_attr "prefix_0f" "0,0,1")
7679    (set (attr "athlon_decode")
7680         (cond [(eq_attr "cpu" "athlon")
7681                   (const_string "vector")
7682                (eq_attr "alternative" "1")
7683                   (const_string "vector")
7684                (and (eq_attr "alternative" "2")
7685                     (match_operand 1 "memory_operand" ""))
7686                   (const_string "vector")]
7687               (const_string "direct")))
7688    (set (attr "amdfam10_decode")
7689         (cond [(and (eq_attr "alternative" "0,1")
7690                     (match_operand 1 "memory_operand" ""))
7691                   (const_string "vector")]
7692               (const_string "direct")))
7693    (set_attr "mode" "<MODE>")])
7694
7695 (define_insn "*mulsi3_1_zext"
7696   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7697         (zero_extend:DI
7698           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7699                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7700    (clobber (reg:CC FLAGS_REG))]
7701   "TARGET_64BIT
7702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7703   "@
7704    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7705    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7706    imul{l}\t{%2, %k0|%k0, %2}"
7707   [(set_attr "type" "imul")
7708    (set_attr "prefix_0f" "0,0,1")
7709    (set (attr "athlon_decode")
7710         (cond [(eq_attr "cpu" "athlon")
7711                   (const_string "vector")
7712                (eq_attr "alternative" "1")
7713                   (const_string "vector")
7714                (and (eq_attr "alternative" "2")
7715                     (match_operand 1 "memory_operand" ""))
7716                   (const_string "vector")]
7717               (const_string "direct")))
7718    (set (attr "amdfam10_decode")
7719         (cond [(and (eq_attr "alternative" "0,1")
7720                     (match_operand 1 "memory_operand" ""))
7721                   (const_string "vector")]
7722               (const_string "direct")))
7723    (set_attr "mode" "SI")])
7724
7725 ;; On AMDFAM10
7726 ;; IMUL reg16, reg16, imm8      VectorPath
7727 ;; IMUL reg16, mem16, imm8      VectorPath
7728 ;; IMUL reg16, reg16, imm16     VectorPath
7729 ;; IMUL reg16, mem16, imm16     VectorPath
7730 ;; IMUL reg16, reg16            Direct
7731 ;; IMUL reg16, mem16            Direct
7732
7733 (define_insn "*mulhi3_1"
7734   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7735         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7736                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7737    (clobber (reg:CC FLAGS_REG))]
7738   "TARGET_HIMODE_MATH
7739    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7740   "@
7741    imul{w}\t{%2, %1, %0|%0, %1, %2}
7742    imul{w}\t{%2, %1, %0|%0, %1, %2}
7743    imul{w}\t{%2, %0|%0, %2}"
7744   [(set_attr "type" "imul")
7745    (set_attr "prefix_0f" "0,0,1")
7746    (set (attr "athlon_decode")
7747         (cond [(eq_attr "cpu" "athlon")
7748                   (const_string "vector")
7749                (eq_attr "alternative" "1,2")
7750                   (const_string "vector")]
7751               (const_string "direct")))
7752    (set (attr "amdfam10_decode")
7753         (cond [(eq_attr "alternative" "0,1")
7754                   (const_string "vector")]
7755               (const_string "direct")))
7756    (set_attr "mode" "HI")])
7757
7758 ;;On AMDFAM10
7759 ;; MUL reg8     Direct
7760 ;; MUL mem8     Direct
7761
7762 (define_insn "*mulqi3_1"
7763   [(set (match_operand:QI 0 "register_operand" "=a")
7764         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7765                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "TARGET_QIMODE_MATH
7768    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7769   "mul{b}\t%2"
7770   [(set_attr "type" "imul")
7771    (set_attr "length_immediate" "0")
7772    (set (attr "athlon_decode")
7773      (if_then_else (eq_attr "cpu" "athlon")
7774         (const_string "vector")
7775         (const_string "direct")))
7776    (set_attr "amdfam10_decode" "direct")
7777    (set_attr "mode" "QI")])
7778
7779 (define_expand "<u>mul<mode><dwi>3"
7780   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7781                    (mult:<DWI>
7782                      (any_extend:<DWI>
7783                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7784                      (any_extend:<DWI>
7785                        (match_operand:DWIH 2 "register_operand" ""))))
7786               (clobber (reg:CC FLAGS_REG))])]
7787   ""
7788   "")
7789
7790 (define_expand "<u>mulqihi3"
7791   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7792                    (mult:HI
7793                      (any_extend:HI
7794                        (match_operand:QI 1 "nonimmediate_operand" ""))
7795                      (any_extend:HI
7796                        (match_operand:QI 2 "register_operand" ""))))
7797               (clobber (reg:CC FLAGS_REG))])]
7798   "TARGET_QIMODE_MATH"
7799   "")
7800
7801 (define_insn "*<u>mul<mode><dwi>3_1"
7802   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7803         (mult:<DWI>
7804           (any_extend:<DWI>
7805             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7806           (any_extend:<DWI>
7807             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7808    (clobber (reg:CC FLAGS_REG))]
7809   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7810   "<sgnprefix>mul{<imodesuffix>}\t%2"
7811   [(set_attr "type" "imul")
7812    (set_attr "length_immediate" "0")
7813    (set (attr "athlon_decode")
7814      (if_then_else (eq_attr "cpu" "athlon")
7815         (const_string "vector")
7816         (const_string "double")))
7817    (set_attr "amdfam10_decode" "double")
7818    (set_attr "mode" "<MODE>")])
7819
7820 (define_insn "*<u>mulqihi3_1"
7821   [(set (match_operand:HI 0 "register_operand" "=a")
7822         (mult:HI
7823           (any_extend:HI
7824             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7825           (any_extend:HI
7826             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7827    (clobber (reg:CC FLAGS_REG))]
7828   "TARGET_QIMODE_MATH
7829    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7830   "<sgnprefix>mul{b}\t%2"
7831   [(set_attr "type" "imul")
7832    (set_attr "length_immediate" "0")
7833    (set (attr "athlon_decode")
7834      (if_then_else (eq_attr "cpu" "athlon")
7835         (const_string "vector")
7836         (const_string "direct")))
7837    (set_attr "amdfam10_decode" "direct")
7838    (set_attr "mode" "QI")])
7839
7840 (define_expand "<s>mul<mode>3_highpart"
7841   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7842                    (truncate:SWI48
7843                      (lshiftrt:<DWI>
7844                        (mult:<DWI>
7845                          (any_extend:<DWI>
7846                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7847                          (any_extend:<DWI>
7848                            (match_operand:SWI48 2 "register_operand" "")))
7849                        (match_dup 4))))
7850               (clobber (match_scratch:SWI48 3 ""))
7851               (clobber (reg:CC FLAGS_REG))])]
7852   ""
7853   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7854
7855 (define_insn "*<s>muldi3_highpart_1"
7856   [(set (match_operand:DI 0 "register_operand" "=d")
7857         (truncate:DI
7858           (lshiftrt:TI
7859             (mult:TI
7860               (any_extend:TI
7861                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7862               (any_extend:TI
7863                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7864             (const_int 64))))
7865    (clobber (match_scratch:DI 3 "=1"))
7866    (clobber (reg:CC FLAGS_REG))]
7867   "TARGET_64BIT
7868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7869   "<sgnprefix>mul{q}\t%2"
7870   [(set_attr "type" "imul")
7871    (set_attr "length_immediate" "0")
7872    (set (attr "athlon_decode")
7873      (if_then_else (eq_attr "cpu" "athlon")
7874         (const_string "vector")
7875         (const_string "double")))
7876    (set_attr "amdfam10_decode" "double")
7877    (set_attr "mode" "DI")])
7878
7879 (define_insn "*<s>mulsi3_highpart_1"
7880   [(set (match_operand:SI 0 "register_operand" "=d")
7881         (truncate:SI
7882           (lshiftrt:DI
7883             (mult:DI
7884               (any_extend:DI
7885                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7886               (any_extend:DI
7887                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7888             (const_int 32))))
7889    (clobber (match_scratch:SI 3 "=1"))
7890    (clobber (reg:CC FLAGS_REG))]
7891   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7892   "<sgnprefix>mul{l}\t%2"
7893   [(set_attr "type" "imul")
7894    (set_attr "length_immediate" "0")
7895    (set (attr "athlon_decode")
7896      (if_then_else (eq_attr "cpu" "athlon")
7897         (const_string "vector")
7898         (const_string "double")))
7899    (set_attr "amdfam10_decode" "double")
7900    (set_attr "mode" "SI")])
7901
7902 (define_insn "*<s>mulsi3_highpart_zext"
7903   [(set (match_operand:DI 0 "register_operand" "=d")
7904         (zero_extend:DI (truncate:SI
7905           (lshiftrt:DI
7906             (mult:DI (any_extend:DI
7907                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7908                      (any_extend:DI
7909                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7910             (const_int 32)))))
7911    (clobber (match_scratch:SI 3 "=1"))
7912    (clobber (reg:CC FLAGS_REG))]
7913   "TARGET_64BIT
7914    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7915   "<sgnprefix>mul{l}\t%2"
7916   [(set_attr "type" "imul")
7917    (set_attr "length_immediate" "0")
7918    (set (attr "athlon_decode")
7919      (if_then_else (eq_attr "cpu" "athlon")
7920         (const_string "vector")
7921         (const_string "double")))
7922    (set_attr "amdfam10_decode" "double")
7923    (set_attr "mode" "SI")])
7924
7925 ;; The patterns that match these are at the end of this file.
7926
7927 (define_expand "mulxf3"
7928   [(set (match_operand:XF 0 "register_operand" "")
7929         (mult:XF (match_operand:XF 1 "register_operand" "")
7930                  (match_operand:XF 2 "register_operand" "")))]
7931   "TARGET_80387"
7932   "")
7933
7934 (define_expand "mul<mode>3"
7935   [(set (match_operand:MODEF 0 "register_operand" "")
7936         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7937                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7938   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7939     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7940   "")
7941 \f
7942 ;; Divide instructions
7943
7944 (define_insn "<u>divqi3"
7945   [(set (match_operand:QI 0 "register_operand" "=a")
7946         (any_div:QI
7947           (match_operand:HI 1 "register_operand" "0")
7948           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7949    (clobber (reg:CC FLAGS_REG))]
7950   "TARGET_QIMODE_MATH"
7951   "<sgnprefix>div{b}\t%2"
7952   [(set_attr "type" "idiv")
7953    (set_attr "mode" "QI")])
7954
7955 ;; The patterns that match these are at the end of this file.
7956
7957 (define_expand "divxf3"
7958   [(set (match_operand:XF 0 "register_operand" "")
7959         (div:XF (match_operand:XF 1 "register_operand" "")
7960                 (match_operand:XF 2 "register_operand" "")))]
7961   "TARGET_80387"
7962   "")
7963
7964 (define_expand "divdf3"
7965   [(set (match_operand:DF 0 "register_operand" "")
7966         (div:DF (match_operand:DF 1 "register_operand" "")
7967                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7968    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7969     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7970    "")
7971
7972 (define_expand "divsf3"
7973   [(set (match_operand:SF 0 "register_operand" "")
7974         (div:SF (match_operand:SF 1 "register_operand" "")
7975                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7976   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7977     || TARGET_SSE_MATH"
7978 {
7979   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7980       && flag_finite_math_only && !flag_trapping_math
7981       && flag_unsafe_math_optimizations)
7982     {
7983       ix86_emit_swdivsf (operands[0], operands[1],
7984                          operands[2], SFmode);
7985       DONE;
7986     }
7987 })
7988 \f
7989 ;; Divmod instructions.
7990
7991 (define_expand "divmod<mode>4"
7992   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7993                    (div:SWIM248
7994                      (match_operand:SWIM248 1 "register_operand" "")
7995                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7996               (set (match_operand:SWIM248 3 "register_operand" "")
7997                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7998               (clobber (reg:CC FLAGS_REG))])]
7999   ""
8000   "")
8001
8002 (define_insn_and_split "*divmod<mode>4"
8003   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8004         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8005                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8006    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8007         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8008    (clobber (reg:CC FLAGS_REG))]
8009   ""
8010   "#"
8011   "&& reload_completed"
8012   [(parallel [(set (match_dup 1)
8013                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8014               (clobber (reg:CC FLAGS_REG))])
8015    (parallel [(set (match_dup 0)
8016                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8017               (set (match_dup 1)
8018                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8019               (use (match_dup 1))
8020               (clobber (reg:CC FLAGS_REG))])]
8021 {
8022   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8023
8024   if (<MODE>mode != HImode
8025       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8026     operands[4] = operands[2];
8027   else
8028     {
8029       /* Avoid use of cltd in favor of a mov+shift.  */
8030       emit_move_insn (operands[1], operands[2]);
8031       operands[4] = operands[1];
8032     }
8033 }
8034   [(set_attr "type" "multi")
8035    (set_attr "mode" "<MODE>")])
8036
8037 (define_insn "*divmod<mode>4_noext"
8038   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8039         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8040                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8041    (set (match_operand:SWIM248 1 "register_operand" "=d")
8042         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8043    (use (match_operand:SWIM248 4 "register_operand" "1"))
8044    (clobber (reg:CC FLAGS_REG))]
8045   ""
8046   "idiv{<imodesuffix>}\t%3"
8047   [(set_attr "type" "idiv")
8048    (set_attr "mode" "<MODE>")])
8049
8050 (define_expand "udivmod<mode>4"
8051   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8052                    (udiv:SWIM248
8053                      (match_operand:SWIM248 1 "register_operand" "")
8054                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8055               (set (match_operand:SWIM248 3 "register_operand" "")
8056                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8057               (clobber (reg:CC FLAGS_REG))])]
8058   ""
8059   "")
8060
8061 (define_insn_and_split "*udivmod<mode>4"
8062   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8063         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8064                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8065    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8066         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8067    (clobber (reg:CC FLAGS_REG))]
8068   ""
8069   "#"
8070   "&& reload_completed"
8071   [(set (match_dup 1) (const_int 0))
8072    (parallel [(set (match_dup 0)
8073                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8074               (set (match_dup 1)
8075                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8076               (use (match_dup 1))
8077               (clobber (reg:CC FLAGS_REG))])]
8078   ""
8079   [(set_attr "type" "multi")
8080    (set_attr "mode" "<MODE>")])
8081
8082 (define_insn "*udivmod<mode>4_noext"
8083   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8084         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8085                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8086    (set (match_operand:SWIM248 1 "register_operand" "=d")
8087         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8088    (use (match_operand:SWIM248 4 "register_operand" "1"))
8089    (clobber (reg:CC FLAGS_REG))]
8090   ""
8091   "div{<imodesuffix>}\t%3"
8092   [(set_attr "type" "idiv")
8093    (set_attr "mode" "<MODE>")])
8094
8095 ;; We cannot use div/idiv for double division, because it causes
8096 ;; "division by zero" on the overflow and that's not what we expect
8097 ;; from truncate.  Because true (non truncating) double division is
8098 ;; never generated, we can't create this insn anyway.
8099 ;
8100 ;(define_insn ""
8101 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8102 ;       (truncate:SI
8103 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8104 ;                  (zero_extend:DI
8105 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8106 ;   (set (match_operand:SI 3 "register_operand" "=d")
8107 ;       (truncate:SI
8108 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8109 ;   (clobber (reg:CC FLAGS_REG))]
8110 ;  ""
8111 ;  "div{l}\t{%2, %0|%0, %2}"
8112 ;  [(set_attr "type" "idiv")])
8113 \f
8114 ;;- Logical AND instructions
8115
8116 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8117 ;; Note that this excludes ah.
8118
8119 (define_expand "testsi_ccno_1"
8120   [(set (reg:CCNO FLAGS_REG)
8121         (compare:CCNO
8122           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8123                   (match_operand:SI 1 "nonmemory_operand" ""))
8124           (const_int 0)))]
8125   ""
8126   "")
8127
8128 (define_expand "testqi_ccz_1"
8129   [(set (reg:CCZ FLAGS_REG)
8130         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8131                              (match_operand:QI 1 "nonmemory_operand" ""))
8132                  (const_int 0)))]
8133   ""
8134   "")
8135
8136 (define_insn "*testdi_1"
8137   [(set (reg FLAGS_REG)
8138         (compare
8139          (and:DI
8140           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8141           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8142          (const_int 0)))]
8143   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8144    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8145   "@
8146    test{l}\t{%k1, %k0|%k0, %k1}
8147    test{l}\t{%k1, %k0|%k0, %k1}
8148    test{q}\t{%1, %0|%0, %1}
8149    test{q}\t{%1, %0|%0, %1}
8150    test{q}\t{%1, %0|%0, %1}"
8151   [(set_attr "type" "test")
8152    (set_attr "modrm" "0,1,0,1,1")
8153    (set_attr "mode" "SI,SI,DI,DI,DI")])
8154
8155 (define_insn "*testqi_1_maybe_si"
8156   [(set (reg FLAGS_REG)
8157         (compare
8158           (and:QI
8159             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8160             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8161           (const_int 0)))]
8162    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8163     && ix86_match_ccmode (insn,
8164                          CONST_INT_P (operands[1])
8165                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8166 {
8167   if (which_alternative == 3)
8168     {
8169       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8170         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8171       return "test{l}\t{%1, %k0|%k0, %1}";
8172     }
8173   return "test{b}\t{%1, %0|%0, %1}";
8174 }
8175   [(set_attr "type" "test")
8176    (set_attr "modrm" "0,1,1,1")
8177    (set_attr "mode" "QI,QI,QI,SI")
8178    (set_attr "pent_pair" "uv,np,uv,np")])
8179
8180 (define_insn "*test<mode>_1"
8181   [(set (reg FLAGS_REG)
8182         (compare
8183          (and:SWI124
8184           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8185           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8186          (const_int 0)))]
8187   "ix86_match_ccmode (insn, CCNOmode)
8188    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8189   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8190   [(set_attr "type" "test")
8191    (set_attr "modrm" "0,1,1")
8192    (set_attr "mode" "<MODE>")
8193    (set_attr "pent_pair" "uv,np,uv")])
8194
8195 (define_expand "testqi_ext_ccno_0"
8196   [(set (reg:CCNO FLAGS_REG)
8197         (compare:CCNO
8198           (and:SI
8199             (zero_extract:SI
8200               (match_operand 0 "ext_register_operand" "")
8201               (const_int 8)
8202               (const_int 8))
8203             (match_operand 1 "const_int_operand" ""))
8204           (const_int 0)))]
8205   ""
8206   "")
8207
8208 (define_insn "*testqi_ext_0"
8209   [(set (reg FLAGS_REG)
8210         (compare
8211           (and:SI
8212             (zero_extract:SI
8213               (match_operand 0 "ext_register_operand" "Q")
8214               (const_int 8)
8215               (const_int 8))
8216             (match_operand 1 "const_int_operand" "n"))
8217           (const_int 0)))]
8218   "ix86_match_ccmode (insn, CCNOmode)"
8219   "test{b}\t{%1, %h0|%h0, %1}"
8220   [(set_attr "type" "test")
8221    (set_attr "mode" "QI")
8222    (set_attr "length_immediate" "1")
8223    (set_attr "modrm" "1")
8224    (set_attr "pent_pair" "np")])
8225
8226 (define_insn "*testqi_ext_1_rex64"
8227   [(set (reg FLAGS_REG)
8228         (compare
8229           (and:SI
8230             (zero_extract:SI
8231               (match_operand 0 "ext_register_operand" "Q")
8232               (const_int 8)
8233               (const_int 8))
8234             (zero_extend:SI
8235               (match_operand:QI 1 "register_operand" "Q")))
8236           (const_int 0)))]
8237   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8238   "test{b}\t{%1, %h0|%h0, %1}"
8239   [(set_attr "type" "test")
8240    (set_attr "mode" "QI")])
8241
8242 (define_insn "*testqi_ext_1"
8243   [(set (reg FLAGS_REG)
8244         (compare
8245           (and:SI
8246             (zero_extract:SI
8247               (match_operand 0 "ext_register_operand" "Q")
8248               (const_int 8)
8249               (const_int 8))
8250             (zero_extend:SI
8251               (match_operand:QI 1 "general_operand" "Qm")))
8252           (const_int 0)))]
8253   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8254   "test{b}\t{%1, %h0|%h0, %1}"
8255   [(set_attr "type" "test")
8256    (set_attr "mode" "QI")])
8257
8258 (define_insn "*testqi_ext_2"
8259   [(set (reg FLAGS_REG)
8260         (compare
8261           (and:SI
8262             (zero_extract:SI
8263               (match_operand 0 "ext_register_operand" "Q")
8264               (const_int 8)
8265               (const_int 8))
8266             (zero_extract:SI
8267               (match_operand 1 "ext_register_operand" "Q")
8268               (const_int 8)
8269               (const_int 8)))
8270           (const_int 0)))]
8271   "ix86_match_ccmode (insn, CCNOmode)"
8272   "test{b}\t{%h1, %h0|%h0, %h1}"
8273   [(set_attr "type" "test")
8274    (set_attr "mode" "QI")])
8275
8276 (define_insn "*testqi_ext_3_rex64"
8277   [(set (reg FLAGS_REG)
8278         (compare (zero_extract:DI
8279                    (match_operand 0 "nonimmediate_operand" "rm")
8280                    (match_operand:DI 1 "const_int_operand" "")
8281                    (match_operand:DI 2 "const_int_operand" ""))
8282                  (const_int 0)))]
8283   "TARGET_64BIT
8284    && ix86_match_ccmode (insn, CCNOmode)
8285    && INTVAL (operands[1]) > 0
8286    && INTVAL (operands[2]) >= 0
8287    /* Ensure that resulting mask is zero or sign extended operand.  */
8288    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8289        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8290            && INTVAL (operands[1]) > 32))
8291    && (GET_MODE (operands[0]) == SImode
8292        || GET_MODE (operands[0]) == DImode
8293        || GET_MODE (operands[0]) == HImode
8294        || GET_MODE (operands[0]) == QImode)"
8295   "#")
8296
8297 ;; Combine likes to form bit extractions for some tests.  Humor it.
8298 (define_insn "*testqi_ext_3"
8299   [(set (reg FLAGS_REG)
8300         (compare (zero_extract:SI
8301                    (match_operand 0 "nonimmediate_operand" "rm")
8302                    (match_operand:SI 1 "const_int_operand" "")
8303                    (match_operand:SI 2 "const_int_operand" ""))
8304                  (const_int 0)))]
8305   "ix86_match_ccmode (insn, CCNOmode)
8306    && INTVAL (operands[1]) > 0
8307    && INTVAL (operands[2]) >= 0
8308    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8309    && (GET_MODE (operands[0]) == SImode
8310        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8311        || GET_MODE (operands[0]) == HImode
8312        || GET_MODE (operands[0]) == QImode)"
8313   "#")
8314
8315 (define_split
8316   [(set (match_operand 0 "flags_reg_operand" "")
8317         (match_operator 1 "compare_operator"
8318           [(zero_extract
8319              (match_operand 2 "nonimmediate_operand" "")
8320              (match_operand 3 "const_int_operand" "")
8321              (match_operand 4 "const_int_operand" ""))
8322            (const_int 0)]))]
8323   "ix86_match_ccmode (insn, CCNOmode)"
8324   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8325 {
8326   rtx val = operands[2];
8327   HOST_WIDE_INT len = INTVAL (operands[3]);
8328   HOST_WIDE_INT pos = INTVAL (operands[4]);
8329   HOST_WIDE_INT mask;
8330   enum machine_mode mode, submode;
8331
8332   mode = GET_MODE (val);
8333   if (MEM_P (val))
8334     {
8335       /* ??? Combine likes to put non-volatile mem extractions in QImode
8336          no matter the size of the test.  So find a mode that works.  */
8337       if (! MEM_VOLATILE_P (val))
8338         {
8339           mode = smallest_mode_for_size (pos + len, MODE_INT);
8340           val = adjust_address (val, mode, 0);
8341         }
8342     }
8343   else if (GET_CODE (val) == SUBREG
8344            && (submode = GET_MODE (SUBREG_REG (val)),
8345                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8346            && pos + len <= GET_MODE_BITSIZE (submode)
8347            && GET_MODE_CLASS (submode) == MODE_INT)
8348     {
8349       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8350       mode = submode;
8351       val = SUBREG_REG (val);
8352     }
8353   else if (mode == HImode && pos + len <= 8)
8354     {
8355       /* Small HImode tests can be converted to QImode.  */
8356       mode = QImode;
8357       val = gen_lowpart (QImode, val);
8358     }
8359
8360   if (len == HOST_BITS_PER_WIDE_INT)
8361     mask = -1;
8362   else
8363     mask = ((HOST_WIDE_INT)1 << len) - 1;
8364   mask <<= pos;
8365
8366   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8367 })
8368
8369 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8370 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8371 ;; this is relatively important trick.
8372 ;; Do the conversion only post-reload to avoid limiting of the register class
8373 ;; to QI regs.
8374 (define_split
8375   [(set (match_operand 0 "flags_reg_operand" "")
8376         (match_operator 1 "compare_operator"
8377           [(and (match_operand 2 "register_operand" "")
8378                 (match_operand 3 "const_int_operand" ""))
8379            (const_int 0)]))]
8380    "reload_completed
8381     && QI_REG_P (operands[2])
8382     && GET_MODE (operands[2]) != QImode
8383     && ((ix86_match_ccmode (insn, CCZmode)
8384          && !(INTVAL (operands[3]) & ~(255 << 8)))
8385         || (ix86_match_ccmode (insn, CCNOmode)
8386             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8387   [(set (match_dup 0)
8388         (match_op_dup 1
8389           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8390                    (match_dup 3))
8391            (const_int 0)]))]
8392   "operands[2] = gen_lowpart (SImode, operands[2]);
8393    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8394
8395 (define_split
8396   [(set (match_operand 0 "flags_reg_operand" "")
8397         (match_operator 1 "compare_operator"
8398           [(and (match_operand 2 "nonimmediate_operand" "")
8399                 (match_operand 3 "const_int_operand" ""))
8400            (const_int 0)]))]
8401    "reload_completed
8402     && GET_MODE (operands[2]) != QImode
8403     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8404     && ((ix86_match_ccmode (insn, CCZmode)
8405          && !(INTVAL (operands[3]) & ~255))
8406         || (ix86_match_ccmode (insn, CCNOmode)
8407             && !(INTVAL (operands[3]) & ~127)))"
8408   [(set (match_dup 0)
8409         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8410                          (const_int 0)]))]
8411   "operands[2] = gen_lowpart (QImode, operands[2]);
8412    operands[3] = gen_lowpart (QImode, operands[3]);")
8413
8414 ;; %%% This used to optimize known byte-wide and operations to memory,
8415 ;; and sometimes to QImode registers.  If this is considered useful,
8416 ;; it should be done with splitters.
8417
8418 (define_expand "and<mode>3"
8419   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8420         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8421                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8422   ""
8423   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8424
8425 (define_insn "*anddi_1"
8426   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8427         (and:DI
8428          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8429          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8430    (clobber (reg:CC FLAGS_REG))]
8431   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8432 {
8433   switch (get_attr_type (insn))
8434     {
8435     case TYPE_IMOVX:
8436       {
8437         enum machine_mode mode;
8438
8439         gcc_assert (CONST_INT_P (operands[2]));
8440         if (INTVAL (operands[2]) == 0xff)
8441           mode = QImode;
8442         else
8443           {
8444             gcc_assert (INTVAL (operands[2]) == 0xffff);
8445             mode = HImode;
8446           }
8447
8448         operands[1] = gen_lowpart (mode, operands[1]);
8449         if (mode == QImode)
8450           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8451         else
8452           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8453       }
8454
8455     default:
8456       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8457       if (get_attr_mode (insn) == MODE_SI)
8458         return "and{l}\t{%k2, %k0|%k0, %k2}";
8459       else
8460         return "and{q}\t{%2, %0|%0, %2}";
8461     }
8462 }
8463   [(set_attr "type" "alu,alu,alu,imovx")
8464    (set_attr "length_immediate" "*,*,*,0")
8465    (set (attr "prefix_rex")
8466      (if_then_else
8467        (and (eq_attr "type" "imovx")
8468             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8469                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8470        (const_string "1")
8471        (const_string "*")))
8472    (set_attr "mode" "SI,DI,DI,SI")])
8473
8474 (define_insn "*andsi_1"
8475   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8476         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8477                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "ix86_binary_operator_ok (AND, SImode, operands)"
8480 {
8481   switch (get_attr_type (insn))
8482     {
8483     case TYPE_IMOVX:
8484       {
8485         enum machine_mode mode;
8486
8487         gcc_assert (CONST_INT_P (operands[2]));
8488         if (INTVAL (operands[2]) == 0xff)
8489           mode = QImode;
8490         else
8491           {
8492             gcc_assert (INTVAL (operands[2]) == 0xffff);
8493             mode = HImode;
8494           }
8495
8496         operands[1] = gen_lowpart (mode, operands[1]);
8497         if (mode == QImode)
8498           return "movz{bl|x}\t{%1, %0|%0, %1}";
8499         else
8500           return "movz{wl|x}\t{%1, %0|%0, %1}";
8501       }
8502
8503     default:
8504       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8505       return "and{l}\t{%2, %0|%0, %2}";
8506     }
8507 }
8508   [(set_attr "type" "alu,alu,imovx")
8509    (set (attr "prefix_rex")
8510      (if_then_else
8511        (and (eq_attr "type" "imovx")
8512             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8513                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8514        (const_string "1")
8515        (const_string "*")))
8516    (set_attr "length_immediate" "*,*,0")
8517    (set_attr "mode" "SI")])
8518
8519 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8520 (define_insn "*andsi_1_zext"
8521   [(set (match_operand:DI 0 "register_operand" "=r")
8522         (zero_extend:DI
8523           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8524                   (match_operand:SI 2 "general_operand" "g"))))
8525    (clobber (reg:CC FLAGS_REG))]
8526   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8527   "and{l}\t{%2, %k0|%k0, %2}"
8528   [(set_attr "type" "alu")
8529    (set_attr "mode" "SI")])
8530
8531 (define_insn "*andhi_1"
8532   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8533         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8534                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "ix86_binary_operator_ok (AND, HImode, operands)"
8537 {
8538   switch (get_attr_type (insn))
8539     {
8540     case TYPE_IMOVX:
8541       gcc_assert (CONST_INT_P (operands[2]));
8542       gcc_assert (INTVAL (operands[2]) == 0xff);
8543       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8544
8545     default:
8546       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8547
8548       return "and{w}\t{%2, %0|%0, %2}";
8549     }
8550 }
8551   [(set_attr "type" "alu,alu,imovx")
8552    (set_attr "length_immediate" "*,*,0")
8553    (set (attr "prefix_rex")
8554      (if_then_else
8555        (and (eq_attr "type" "imovx")
8556             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8557        (const_string "1")
8558        (const_string "*")))
8559    (set_attr "mode" "HI,HI,SI")])
8560
8561 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8562 (define_insn "*andqi_1"
8563   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8564         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8565                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "ix86_binary_operator_ok (AND, QImode, operands)"
8568   "@
8569    and{b}\t{%2, %0|%0, %2}
8570    and{b}\t{%2, %0|%0, %2}
8571    and{l}\t{%k2, %k0|%k0, %k2}"
8572   [(set_attr "type" "alu")
8573    (set_attr "mode" "QI,QI,SI")])
8574
8575 (define_insn "*andqi_1_slp"
8576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8577         (and:QI (match_dup 0)
8578                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8581    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8582   "and{b}\t{%1, %0|%0, %1}"
8583   [(set_attr "type" "alu1")
8584    (set_attr "mode" "QI")])
8585
8586 (define_split
8587   [(set (match_operand 0 "register_operand" "")
8588         (and (match_dup 0)
8589              (const_int -65536)))
8590    (clobber (reg:CC FLAGS_REG))]
8591   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8592     || optimize_function_for_size_p (cfun)"
8593   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8594   "operands[1] = gen_lowpart (HImode, operands[0]);")
8595
8596 (define_split
8597   [(set (match_operand 0 "ext_register_operand" "")
8598         (and (match_dup 0)
8599              (const_int -256)))
8600    (clobber (reg:CC FLAGS_REG))]
8601   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8602    && reload_completed"
8603   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8604   "operands[1] = gen_lowpart (QImode, operands[0]);")
8605
8606 (define_split
8607   [(set (match_operand 0 "ext_register_operand" "")
8608         (and (match_dup 0)
8609              (const_int -65281)))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8612    && reload_completed"
8613   [(parallel [(set (zero_extract:SI (match_dup 0)
8614                                     (const_int 8)
8615                                     (const_int 8))
8616                    (xor:SI
8617                      (zero_extract:SI (match_dup 0)
8618                                       (const_int 8)
8619                                       (const_int 8))
8620                      (zero_extract:SI (match_dup 0)
8621                                       (const_int 8)
8622                                       (const_int 8))))
8623               (clobber (reg:CC FLAGS_REG))])]
8624   "operands[0] = gen_lowpart (SImode, operands[0]);")
8625
8626 (define_insn "*anddi_2"
8627   [(set (reg FLAGS_REG)
8628         (compare
8629          (and:DI
8630           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8631           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8632          (const_int 0)))
8633    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8634         (and:DI (match_dup 1) (match_dup 2)))]
8635   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (AND, DImode, operands)"
8637   "@
8638    and{l}\t{%k2, %k0|%k0, %k2}
8639    and{q}\t{%2, %0|%0, %2}
8640    and{q}\t{%2, %0|%0, %2}"
8641   [(set_attr "type" "alu")
8642    (set_attr "mode" "SI,DI,DI")])
8643
8644 (define_insn "*andqi_2_maybe_si"
8645   [(set (reg FLAGS_REG)
8646         (compare (and:QI
8647                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8648                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8649                  (const_int 0)))
8650    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8651         (and:QI (match_dup 1) (match_dup 2)))]
8652   "ix86_binary_operator_ok (AND, QImode, operands)
8653    && ix86_match_ccmode (insn,
8654                          CONST_INT_P (operands[2])
8655                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8656 {
8657   if (which_alternative == 2)
8658     {
8659       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8660         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8661       return "and{l}\t{%2, %k0|%k0, %2}";
8662     }
8663   return "and{b}\t{%2, %0|%0, %2}";
8664 }
8665   [(set_attr "type" "alu")
8666    (set_attr "mode" "QI,QI,SI")])
8667
8668 (define_insn "*and<mode>_2"
8669   [(set (reg FLAGS_REG)
8670         (compare (and:SWI124
8671                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8672                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8673                  (const_int 0)))
8674    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8675         (and:SWI124 (match_dup 1) (match_dup 2)))]
8676   "ix86_match_ccmode (insn, CCNOmode)
8677    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8678   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "<MODE>")])
8681
8682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8683 (define_insn "*andsi_2_zext"
8684   [(set (reg FLAGS_REG)
8685         (compare (and:SI
8686                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8687                   (match_operand:SI 2 "general_operand" "g"))
8688                  (const_int 0)))
8689    (set (match_operand:DI 0 "register_operand" "=r")
8690         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8691   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8692    && ix86_binary_operator_ok (AND, SImode, operands)"
8693   "and{l}\t{%2, %k0|%k0, %2}"
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "SI")])
8696
8697 (define_insn "*andqi_2_slp"
8698   [(set (reg FLAGS_REG)
8699         (compare (and:QI
8700                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8701                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8702                  (const_int 0)))
8703    (set (strict_low_part (match_dup 0))
8704         (and:QI (match_dup 0) (match_dup 1)))]
8705   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8706    && ix86_match_ccmode (insn, CCNOmode)
8707    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8708   "and{b}\t{%1, %0|%0, %1}"
8709   [(set_attr "type" "alu1")
8710    (set_attr "mode" "QI")])
8711
8712 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8713 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8714 ;; for a QImode operand, which of course failed.
8715 (define_insn "andqi_ext_0"
8716   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8717                          (const_int 8)
8718                          (const_int 8))
8719         (and:SI
8720           (zero_extract:SI
8721             (match_operand 1 "ext_register_operand" "0")
8722             (const_int 8)
8723             (const_int 8))
8724           (match_operand 2 "const_int_operand" "n")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   ""
8727   "and{b}\t{%2, %h0|%h0, %2}"
8728   [(set_attr "type" "alu")
8729    (set_attr "length_immediate" "1")
8730    (set_attr "modrm" "1")
8731    (set_attr "mode" "QI")])
8732
8733 ;; Generated by peephole translating test to and.  This shows up
8734 ;; often in fp comparisons.
8735 (define_insn "*andqi_ext_0_cc"
8736   [(set (reg FLAGS_REG)
8737         (compare
8738           (and:SI
8739             (zero_extract:SI
8740               (match_operand 1 "ext_register_operand" "0")
8741               (const_int 8)
8742               (const_int 8))
8743             (match_operand 2 "const_int_operand" "n"))
8744           (const_int 0)))
8745    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8746                          (const_int 8)
8747                          (const_int 8))
8748         (and:SI
8749           (zero_extract:SI
8750             (match_dup 1)
8751             (const_int 8)
8752             (const_int 8))
8753           (match_dup 2)))]
8754   "ix86_match_ccmode (insn, CCNOmode)"
8755   "and{b}\t{%2, %h0|%h0, %2}"
8756   [(set_attr "type" "alu")
8757    (set_attr "length_immediate" "1")
8758    (set_attr "modrm" "1")
8759    (set_attr "mode" "QI")])
8760
8761 (define_insn "*andqi_ext_1_rex64"
8762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8763                          (const_int 8)
8764                          (const_int 8))
8765         (and:SI
8766           (zero_extract:SI
8767             (match_operand 1 "ext_register_operand" "0")
8768             (const_int 8)
8769             (const_int 8))
8770           (zero_extend:SI
8771             (match_operand 2 "ext_register_operand" "Q"))))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_64BIT"
8774   "and{b}\t{%2, %h0|%h0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "length_immediate" "0")
8777    (set_attr "mode" "QI")])
8778
8779 (define_insn "*andqi_ext_1"
8780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781                          (const_int 8)
8782                          (const_int 8))
8783         (and:SI
8784           (zero_extract:SI
8785             (match_operand 1 "ext_register_operand" "0")
8786             (const_int 8)
8787             (const_int 8))
8788           (zero_extend:SI
8789             (match_operand:QI 2 "general_operand" "Qm"))))
8790    (clobber (reg:CC FLAGS_REG))]
8791   "!TARGET_64BIT"
8792   "and{b}\t{%2, %h0|%h0, %2}"
8793   [(set_attr "type" "alu")
8794    (set_attr "length_immediate" "0")
8795    (set_attr "mode" "QI")])
8796
8797 (define_insn "*andqi_ext_2"
8798   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8799                          (const_int 8)
8800                          (const_int 8))
8801         (and:SI
8802           (zero_extract:SI
8803             (match_operand 1 "ext_register_operand" "%0")
8804             (const_int 8)
8805             (const_int 8))
8806           (zero_extract:SI
8807             (match_operand 2 "ext_register_operand" "Q")
8808             (const_int 8)
8809             (const_int 8))))
8810    (clobber (reg:CC FLAGS_REG))]
8811   ""
8812   "and{b}\t{%h2, %h0|%h0, %h2}"
8813   [(set_attr "type" "alu")
8814    (set_attr "length_immediate" "0")
8815    (set_attr "mode" "QI")])
8816
8817 ;; Convert wide AND instructions with immediate operand to shorter QImode
8818 ;; equivalents when possible.
8819 ;; Don't do the splitting with memory operands, since it introduces risk
8820 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8821 ;; for size, but that can (should?) be handled by generic code instead.
8822 (define_split
8823   [(set (match_operand 0 "register_operand" "")
8824         (and (match_operand 1 "register_operand" "")
8825              (match_operand 2 "const_int_operand" "")))
8826    (clobber (reg:CC FLAGS_REG))]
8827    "reload_completed
8828     && QI_REG_P (operands[0])
8829     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8830     && !(~INTVAL (operands[2]) & ~(255 << 8))
8831     && GET_MODE (operands[0]) != QImode"
8832   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8833                    (and:SI (zero_extract:SI (match_dup 1)
8834                                             (const_int 8) (const_int 8))
8835                            (match_dup 2)))
8836               (clobber (reg:CC FLAGS_REG))])]
8837   "operands[0] = gen_lowpart (SImode, operands[0]);
8838    operands[1] = gen_lowpart (SImode, operands[1]);
8839    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8840
8841 ;; Since AND can be encoded with sign extended immediate, this is only
8842 ;; profitable when 7th bit is not set.
8843 (define_split
8844   [(set (match_operand 0 "register_operand" "")
8845         (and (match_operand 1 "general_operand" "")
8846              (match_operand 2 "const_int_operand" "")))
8847    (clobber (reg:CC FLAGS_REG))]
8848    "reload_completed
8849     && ANY_QI_REG_P (operands[0])
8850     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8851     && !(~INTVAL (operands[2]) & ~255)
8852     && !(INTVAL (operands[2]) & 128)
8853     && GET_MODE (operands[0]) != QImode"
8854   [(parallel [(set (strict_low_part (match_dup 0))
8855                    (and:QI (match_dup 1)
8856                            (match_dup 2)))
8857               (clobber (reg:CC FLAGS_REG))])]
8858   "operands[0] = gen_lowpart (QImode, operands[0]);
8859    operands[1] = gen_lowpart (QImode, operands[1]);
8860    operands[2] = gen_lowpart (QImode, operands[2]);")
8861 \f
8862 ;; Logical inclusive OR instructions
8863
8864 ;; %%% This used to optimize known byte-wide and operations to memory.
8865 ;; If this is considered useful, it should be done with splitters.
8866
8867 (define_expand "ior<mode>3"
8868   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8869         (ior:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8870                   (match_operand:SWIM 2 "<general_operand>" "")))]
8871   ""
8872   "ix86_expand_binary_operator (IOR, <MODE>mode, operands); DONE;")
8873
8874 (define_insn "*ior<mode>_1"
8875   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8876         (ior:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8877                     (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8878    (clobber (reg:CC FLAGS_REG))]
8879   "ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
8880   "or{<imodesuffix>}\t{%2, %0|%0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "mode" "<MODE>")])
8883
8884 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8885 (define_insn "*iorqi_1"
8886   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8887         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8888                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8889    (clobber (reg:CC FLAGS_REG))]
8890   "ix86_binary_operator_ok (IOR, QImode, operands)"
8891   "@
8892    or{b}\t{%2, %0|%0, %2}
8893    or{b}\t{%2, %0|%0, %2}
8894    or{l}\t{%k2, %k0|%k0, %k2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "mode" "QI,QI,SI")])
8897
8898 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8899 (define_insn "*iorsi_1_zext"
8900   [(set (match_operand:DI 0 "register_operand" "=r")
8901         (zero_extend:DI
8902           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8903                   (match_operand:SI 2 "general_operand" "g"))))
8904    (clobber (reg:CC FLAGS_REG))]
8905   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8906   "or{l}\t{%2, %k0|%k0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "SI")])
8909
8910 (define_insn "*iorsi_1_zext_imm"
8911   [(set (match_operand:DI 0 "register_operand" "=r")
8912         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8913                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8914    (clobber (reg:CC FLAGS_REG))]
8915   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8916   "or{l}\t{%2, %k0|%k0, %2}"
8917   [(set_attr "type" "alu")
8918    (set_attr "mode" "SI")])
8919
8920 (define_insn "*iorqi_1_slp"
8921   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8922         (ior:QI (match_dup 0)
8923                 (match_operand:QI 1 "general_operand" "qmn,qn")))
8924    (clobber (reg:CC FLAGS_REG))]
8925   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8926    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8927   "or{b}\t{%1, %0|%0, %1}"
8928   [(set_attr "type" "alu1")
8929    (set_attr "mode" "QI")])
8930
8931 (define_insn "*ior<mode>_2"
8932   [(set (reg FLAGS_REG)
8933         (compare (ior:SWI
8934                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8935                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8936                  (const_int 0)))
8937    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8938         (ior:SWI (match_dup 1) (match_dup 2)))]
8939   "ix86_match_ccmode (insn, CCNOmode)
8940    && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
8941   "or{<imodesuffix>}\t{%2, %0|%0, %2}"
8942   [(set_attr "type" "alu")
8943    (set_attr "mode" "<MODE>")])
8944
8945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8946 ;; ??? Special case for immediate operand is missing - it is tricky.
8947 (define_insn "*iorsi_2_zext"
8948   [(set (reg FLAGS_REG)
8949         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8950                          (match_operand:SI 2 "general_operand" "g"))
8951                  (const_int 0)))
8952    (set (match_operand:DI 0 "register_operand" "=r")
8953         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8954   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8955    && ix86_binary_operator_ok (IOR, SImode, operands)"
8956   "or{l}\t{%2, %k0|%k0, %2}"
8957   [(set_attr "type" "alu")
8958    (set_attr "mode" "SI")])
8959
8960 (define_insn "*iorsi_2_zext_imm"
8961   [(set (reg FLAGS_REG)
8962         (compare (ior:SI
8963                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8964                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8965                  (const_int 0)))
8966    (set (match_operand:DI 0 "register_operand" "=r")
8967         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8968   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8969    && ix86_binary_operator_ok (IOR, SImode, operands)"
8970   "or{l}\t{%2, %k0|%k0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "SI")])
8973
8974 (define_insn "*iorqi_2_slp"
8975   [(set (reg FLAGS_REG)
8976         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8977                          (match_operand:QI 1 "general_operand" "qmn,qn"))
8978                  (const_int 0)))
8979    (set (strict_low_part (match_dup 0))
8980         (ior:QI (match_dup 0) (match_dup 1)))]
8981   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8982    && ix86_match_ccmode (insn, CCNOmode)
8983    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8984   "or{b}\t{%1, %0|%0, %1}"
8985   [(set_attr "type" "alu1")
8986    (set_attr "mode" "QI")])
8987
8988 (define_insn "*ior<mode>_3"
8989   [(set (reg FLAGS_REG)
8990         (compare (ior:SWI
8991                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8992                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8993                  (const_int 0)))
8994    (clobber (match_scratch:SWI 0 "=<r>"))]
8995   "ix86_match_ccmode (insn, CCNOmode)
8996    && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
8997   "or{<imodesuffix>}\t{%2, %0|%0, %2}"
8998   [(set_attr "type" "alu")
8999    (set_attr "mode" "<MODE>")])
9000
9001 (define_insn "*iorqi_ext_0"
9002   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9003                          (const_int 8)
9004                          (const_int 8))
9005         (ior:SI
9006           (zero_extract:SI
9007             (match_operand 1 "ext_register_operand" "0")
9008             (const_int 8)
9009             (const_int 8))
9010           (match_operand 2 "const_int_operand" "n")))
9011    (clobber (reg:CC FLAGS_REG))]
9012   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9013   "or{b}\t{%2, %h0|%h0, %2}"
9014   [(set_attr "type" "alu")
9015    (set_attr "length_immediate" "1")
9016    (set_attr "modrm" "1")
9017    (set_attr "mode" "QI")])
9018
9019 (define_insn "*iorqi_ext_1_rex64"
9020   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9021                          (const_int 8)
9022                          (const_int 8))
9023         (ior:SI
9024           (zero_extract:SI
9025             (match_operand 1 "ext_register_operand" "0")
9026             (const_int 8)
9027             (const_int 8))
9028           (zero_extend:SI
9029             (match_operand 2 "ext_register_operand" "Q"))))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_64BIT
9032    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9033   "or{b}\t{%2, %h0|%h0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "length_immediate" "0")
9036    (set_attr "mode" "QI")])
9037
9038 (define_insn "*iorqi_ext_1"
9039   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9040                          (const_int 8)
9041                          (const_int 8))
9042         (ior:SI
9043           (zero_extract:SI
9044             (match_operand 1 "ext_register_operand" "0")
9045             (const_int 8)
9046             (const_int 8))
9047           (zero_extend:SI
9048             (match_operand:QI 2 "general_operand" "Qm"))))
9049    (clobber (reg:CC FLAGS_REG))]
9050   "!TARGET_64BIT
9051    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9052   "or{b}\t{%2, %h0|%h0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "length_immediate" "0")
9055    (set_attr "mode" "QI")])
9056
9057 (define_insn "*iorqi_ext_2"
9058   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9059                          (const_int 8)
9060                          (const_int 8))
9061         (ior:SI
9062           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9063                            (const_int 8)
9064                            (const_int 8))
9065           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9066                            (const_int 8)
9067                            (const_int 8))))
9068    (clobber (reg:CC FLAGS_REG))]
9069   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9070   "ior{b}\t{%h2, %h0|%h0, %h2}"
9071   [(set_attr "type" "alu")
9072    (set_attr "length_immediate" "0")
9073    (set_attr "mode" "QI")])
9074
9075 (define_split
9076   [(set (match_operand 0 "register_operand" "")
9077         (ior (match_operand 1 "register_operand" "")
9078              (match_operand 2 "const_int_operand" "")))
9079    (clobber (reg:CC FLAGS_REG))]
9080    "reload_completed
9081     && QI_REG_P (operands[0])
9082     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9083     && !(INTVAL (operands[2]) & ~(255 << 8))
9084     && GET_MODE (operands[0]) != QImode"
9085   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9086                    (ior:SI (zero_extract:SI (match_dup 1)
9087                                             (const_int 8) (const_int 8))
9088                            (match_dup 2)))
9089               (clobber (reg:CC FLAGS_REG))])]
9090   "operands[0] = gen_lowpart (SImode, operands[0]);
9091    operands[1] = gen_lowpart (SImode, operands[1]);
9092    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9093
9094 ;; Since OR can be encoded with sign extended immediate, this is only
9095 ;; profitable when 7th bit is set.
9096 (define_split
9097   [(set (match_operand 0 "register_operand" "")
9098         (ior (match_operand 1 "general_operand" "")
9099              (match_operand 2 "const_int_operand" "")))
9100    (clobber (reg:CC FLAGS_REG))]
9101    "reload_completed
9102     && ANY_QI_REG_P (operands[0])
9103     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9104     && !(INTVAL (operands[2]) & ~255)
9105     && (INTVAL (operands[2]) & 128)
9106     && GET_MODE (operands[0]) != QImode"
9107   [(parallel [(set (strict_low_part (match_dup 0))
9108                    (ior:QI (match_dup 1)
9109                            (match_dup 2)))
9110               (clobber (reg:CC FLAGS_REG))])]
9111   "operands[0] = gen_lowpart (QImode, operands[0]);
9112    operands[1] = gen_lowpart (QImode, operands[1]);
9113    operands[2] = gen_lowpart (QImode, operands[2]);")
9114 \f
9115 ;; Logical XOR instructions
9116
9117 ;; %%% This used to optimize known byte-wide and operations to memory.
9118 ;; If this is considered useful, it should be done with splitters.
9119
9120 (define_expand "xor<mode>3"
9121   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9122         (xor:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
9123                   (match_operand:SWIM 2 "<general_operand>" "")))]
9124   ""
9125   "ix86_expand_binary_operator (XOR, <MODE>mode, operands); DONE;")
9126
9127 (define_insn "*xor<mode>_1"
9128   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9129         (xor:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9130                     (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9131    (clobber (reg:CC FLAGS_REG))]
9132   "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
9133   "xor{<imodesuffix>}\t{%2, %0|%0, %2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "mode" "<MODE>")])
9136
9137 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9138 (define_insn "*xorqi_1"
9139   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9140         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9141                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9142    (clobber (reg:CC FLAGS_REG))]
9143   "ix86_binary_operator_ok (XOR, QImode, operands)"
9144   "@
9145    xor{b}\t{%2, %0|%0, %2}
9146    xor{b}\t{%2, %0|%0, %2}
9147    xor{l}\t{%k2, %k0|%k0, %k2}"
9148   [(set_attr "type" "alu")
9149    (set_attr "mode" "QI,QI,SI")])
9150
9151 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9152 ;; Add speccase for immediates
9153 (define_insn "*xorsi_1_zext"
9154   [(set (match_operand:DI 0 "register_operand" "=r")
9155         (zero_extend:DI
9156           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9157                   (match_operand:SI 2 "general_operand" "g"))))
9158    (clobber (reg:CC FLAGS_REG))]
9159   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9160   "xor{l}\t{%2, %k0|%k0, %2}"
9161   [(set_attr "type" "alu")
9162    (set_attr "mode" "SI")])
9163
9164 (define_insn "*xorsi_1_zext_imm"
9165   [(set (match_operand:DI 0 "register_operand" "=r")
9166         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9167                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9170   "xor{l}\t{%2, %k0|%k0, %2}"
9171   [(set_attr "type" "alu")
9172    (set_attr "mode" "SI")])
9173
9174 (define_insn "*xorqi_1_slp"
9175   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9176         (xor:QI (match_dup 0)
9177                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9178    (clobber (reg:CC FLAGS_REG))]
9179   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9180    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9181   "xor{b}\t{%1, %0|%0, %1}"
9182   [(set_attr "type" "alu1")
9183    (set_attr "mode" "QI")])
9184
9185 (define_insn "*xor<mode>_2"
9186   [(set (reg FLAGS_REG)
9187         (compare (xor:SWI
9188                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9189                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9190                  (const_int 0)))
9191    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9192         (xor:SWI (match_dup 1) (match_dup 2)))]
9193   "ix86_match_ccmode (insn, CCNOmode)
9194    && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
9195   "xor{<imodesuffix>}\t{%2, %0|%0, %2}"
9196   [(set_attr "type" "alu")
9197    (set_attr "mode" "<MODE>")])
9198
9199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9200 ;; ??? Special case for immediate operand is missing - it is tricky.
9201 (define_insn "*xorsi_2_zext"
9202   [(set (reg FLAGS_REG)
9203         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9204                          (match_operand:SI 2 "general_operand" "g"))
9205                  (const_int 0)))
9206    (set (match_operand:DI 0 "register_operand" "=r")
9207         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9208   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9209    && ix86_binary_operator_ok (XOR, SImode, operands)"
9210   "xor{l}\t{%2, %k0|%k0, %2}"
9211   [(set_attr "type" "alu")
9212    (set_attr "mode" "SI")])
9213
9214 (define_insn "*xorsi_2_zext_imm"
9215   [(set (reg FLAGS_REG)
9216         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9217                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9218                  (const_int 0)))
9219    (set (match_operand:DI 0 "register_operand" "=r")
9220         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9221   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9222    && ix86_binary_operator_ok (XOR, SImode, operands)"
9223   "xor{l}\t{%2, %k0|%k0, %2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "mode" "SI")])
9226
9227 (define_insn "*xorqi_2_slp"
9228   [(set (reg FLAGS_REG)
9229         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9230                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9231                  (const_int 0)))
9232    (set (strict_low_part (match_dup 0))
9233         (xor:QI (match_dup 0) (match_dup 1)))]
9234   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9235    && ix86_match_ccmode (insn, CCNOmode)
9236    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9237   "xor{b}\t{%1, %0|%0, %1}"
9238   [(set_attr "type" "alu1")
9239    (set_attr "mode" "QI")])
9240
9241 (define_insn "*xor<mode>_3"
9242   [(set (reg FLAGS_REG)
9243         (compare (xor:SWI
9244                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9245                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9246                  (const_int 0)))
9247    (clobber (match_scratch:SWI 0 "=<r>"))]
9248   "ix86_match_ccmode (insn, CCNOmode)
9249    && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
9250   "xor{<imodesuffix>}\t{%2, %0|%0, %2}"
9251   [(set_attr "type" "alu")
9252    (set_attr "mode" "<MODE>")])
9253
9254 (define_insn "*xorqi_ext_0"
9255   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9256                          (const_int 8)
9257                          (const_int 8))
9258         (xor:SI
9259           (zero_extract:SI
9260             (match_operand 1 "ext_register_operand" "0")
9261             (const_int 8)
9262             (const_int 8))
9263           (match_operand 2 "const_int_operand" "n")))
9264    (clobber (reg:CC FLAGS_REG))]
9265   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9266   "xor{b}\t{%2, %h0|%h0, %2}"
9267   [(set_attr "type" "alu")
9268    (set_attr "length_immediate" "1")
9269    (set_attr "modrm" "1")
9270    (set_attr "mode" "QI")])
9271
9272 (define_insn "*xorqi_ext_1_rex64"
9273   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274                          (const_int 8)
9275                          (const_int 8))
9276         (xor:SI
9277           (zero_extract:SI
9278             (match_operand 1 "ext_register_operand" "0")
9279             (const_int 8)
9280             (const_int 8))
9281           (zero_extend:SI
9282             (match_operand 2 "ext_register_operand" "Q"))))
9283    (clobber (reg:CC FLAGS_REG))]
9284   "TARGET_64BIT
9285    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9286   "xor{b}\t{%2, %h0|%h0, %2}"
9287   [(set_attr "type" "alu")
9288    (set_attr "length_immediate" "0")
9289    (set_attr "mode" "QI")])
9290
9291 (define_insn "*xorqi_ext_1"
9292   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9293                          (const_int 8)
9294                          (const_int 8))
9295         (xor:SI
9296           (zero_extract:SI
9297             (match_operand 1 "ext_register_operand" "0")
9298             (const_int 8)
9299             (const_int 8))
9300           (zero_extend:SI
9301             (match_operand:QI 2 "general_operand" "Qm"))))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "!TARGET_64BIT
9304    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9305   "xor{b}\t{%2, %h0|%h0, %2}"
9306   [(set_attr "type" "alu")
9307    (set_attr "length_immediate" "0")
9308    (set_attr "mode" "QI")])
9309
9310 (define_insn "*xorqi_ext_2"
9311   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9312                          (const_int 8)
9313                          (const_int 8))
9314         (xor:SI
9315           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9316                            (const_int 8)
9317                            (const_int 8))
9318           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9319                            (const_int 8)
9320                            (const_int 8))))
9321    (clobber (reg:CC FLAGS_REG))]
9322   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9323   "xor{b}\t{%h2, %h0|%h0, %h2}"
9324   [(set_attr "type" "alu")
9325    (set_attr "length_immediate" "0")
9326    (set_attr "mode" "QI")])
9327
9328 (define_expand "xorqi_cc_ext_1"
9329   [(parallel [
9330      (set (reg:CCNO FLAGS_REG)
9331           (compare:CCNO
9332             (xor:SI
9333               (zero_extract:SI
9334                 (match_operand 1 "ext_register_operand" "")
9335                 (const_int 8)
9336                 (const_int 8))
9337               (match_operand:QI 2 "general_operand" ""))
9338             (const_int 0)))
9339      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9340                            (const_int 8)
9341                            (const_int 8))
9342           (xor:SI
9343             (zero_extract:SI
9344              (match_dup 1)
9345              (const_int 8)
9346              (const_int 8))
9347             (match_dup 2)))])]
9348   ""
9349   "")
9350
9351 (define_insn "*xorqi_cc_ext_1_rex64"
9352   [(set (reg FLAGS_REG)
9353         (compare
9354           (xor:SI
9355             (zero_extract:SI
9356               (match_operand 1 "ext_register_operand" "0")
9357               (const_int 8)
9358               (const_int 8))
9359             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9360           (const_int 0)))
9361    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9362                          (const_int 8)
9363                          (const_int 8))
9364         (xor:SI
9365           (zero_extract:SI
9366            (match_dup 1)
9367            (const_int 8)
9368            (const_int 8))
9369           (match_dup 2)))]
9370   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9371   "xor{b}\t{%2, %h0|%h0, %2}"
9372   [(set_attr "type" "alu")
9373    (set_attr "modrm" "1")
9374    (set_attr "mode" "QI")])
9375
9376 (define_insn "*xorqi_cc_ext_1"
9377   [(set (reg FLAGS_REG)
9378         (compare
9379           (xor:SI
9380             (zero_extract:SI
9381               (match_operand 1 "ext_register_operand" "0")
9382               (const_int 8)
9383               (const_int 8))
9384             (match_operand:QI 2 "general_operand" "qmn"))
9385           (const_int 0)))
9386    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9387                          (const_int 8)
9388                          (const_int 8))
9389         (xor:SI
9390           (zero_extract:SI
9391            (match_dup 1)
9392            (const_int 8)
9393            (const_int 8))
9394           (match_dup 2)))]
9395   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9396   "xor{b}\t{%2, %h0|%h0, %2}"
9397   [(set_attr "type" "alu")
9398    (set_attr "modrm" "1")
9399    (set_attr "mode" "QI")])
9400
9401 (define_split
9402   [(set (match_operand 0 "register_operand" "")
9403         (xor (match_operand 1 "register_operand" "")
9404              (match_operand 2 "const_int_operand" "")))
9405    (clobber (reg:CC FLAGS_REG))]
9406    "reload_completed
9407     && QI_REG_P (operands[0])
9408     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9409     && !(INTVAL (operands[2]) & ~(255 << 8))
9410     && GET_MODE (operands[0]) != QImode"
9411   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9412                    (xor:SI (zero_extract:SI (match_dup 1)
9413                                             (const_int 8) (const_int 8))
9414                            (match_dup 2)))
9415               (clobber (reg:CC FLAGS_REG))])]
9416   "operands[0] = gen_lowpart (SImode, operands[0]);
9417    operands[1] = gen_lowpart (SImode, operands[1]);
9418    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9419
9420 ;; Since XOR can be encoded with sign extended immediate, this is only
9421 ;; profitable when 7th bit is set.
9422 (define_split
9423   [(set (match_operand 0 "register_operand" "")
9424         (xor (match_operand 1 "general_operand" "")
9425              (match_operand 2 "const_int_operand" "")))
9426    (clobber (reg:CC FLAGS_REG))]
9427    "reload_completed
9428     && ANY_QI_REG_P (operands[0])
9429     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9430     && !(INTVAL (operands[2]) & ~255)
9431     && (INTVAL (operands[2]) & 128)
9432     && GET_MODE (operands[0]) != QImode"
9433   [(parallel [(set (strict_low_part (match_dup 0))
9434                    (xor:QI (match_dup 1)
9435                            (match_dup 2)))
9436               (clobber (reg:CC FLAGS_REG))])]
9437   "operands[0] = gen_lowpart (QImode, operands[0]);
9438    operands[1] = gen_lowpart (QImode, operands[1]);
9439    operands[2] = gen_lowpart (QImode, operands[2]);")
9440 \f
9441 ;; Negation instructions
9442
9443 (define_expand "neg<mode>2"
9444   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9445         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9446   ""
9447   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9448
9449 (define_insn_and_split "*neg<dwi>2_doubleword"
9450   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9451         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9452    (clobber (reg:CC FLAGS_REG))]
9453   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9454   "#"
9455   "reload_completed"
9456   [(parallel
9457     [(set (reg:CCZ FLAGS_REG)
9458           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9459      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9460    (parallel
9461     [(set (match_dup 2)
9462           (plus:DWIH (match_dup 3)
9463                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9464                                 (const_int 0))))
9465      (clobber (reg:CC FLAGS_REG))])
9466    (parallel
9467     [(set (match_dup 2)
9468           (neg:DWIH (match_dup 2)))
9469      (clobber (reg:CC FLAGS_REG))])]
9470   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9471
9472 (define_insn "*neg<mode>2_1"
9473   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9474         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9477   "neg{<imodesuffix>}\t%0"
9478   [(set_attr "type" "negnot")
9479    (set_attr "mode" "<MODE>")])
9480
9481 ;; Combine is quite creative about this pattern.
9482 (define_insn "*negsi2_1_zext"
9483   [(set (match_operand:DI 0 "register_operand" "=r")
9484         (lshiftrt:DI
9485           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9486                              (const_int 32)))
9487         (const_int 32)))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9490   "neg{l}\t%k0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "SI")])
9493
9494 ;; The problem with neg is that it does not perform (compare x 0),
9495 ;; it really performs (compare 0 x), which leaves us with the zero
9496 ;; flag being the only useful item.
9497
9498 (define_insn "*neg<mode>2_cmpz"
9499   [(set (reg:CCZ FLAGS_REG)
9500         (compare:CCZ
9501           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9502                    (const_int 0)))
9503    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9504         (neg:SWI (match_dup 1)))]
9505   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9506   "neg{<imodesuffix>}\t%0"
9507   [(set_attr "type" "negnot")
9508    (set_attr "mode" "<MODE>")])
9509
9510 (define_insn "*negsi2_cmpz_zext"
9511   [(set (reg:CCZ FLAGS_REG)
9512         (compare:CCZ
9513           (lshiftrt:DI
9514             (neg:DI (ashift:DI
9515                       (match_operand:DI 1 "register_operand" "0")
9516                       (const_int 32)))
9517             (const_int 32))
9518           (const_int 0)))
9519    (set (match_operand:DI 0 "register_operand" "=r")
9520         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9521                                         (const_int 32)))
9522                      (const_int 32)))]
9523   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9524   "neg{l}\t%k0"
9525   [(set_attr "type" "negnot")
9526    (set_attr "mode" "SI")])
9527
9528 ;; Changing of sign for FP values is doable using integer unit too.
9529
9530 (define_expand "<code><mode>2"
9531   [(set (match_operand:X87MODEF 0 "register_operand" "")
9532         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9533   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9534   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9535
9536 (define_insn "*absneg<mode>2_mixed"
9537   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9538         (match_operator:MODEF 3 "absneg_operator"
9539           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9540    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9543   "#")
9544
9545 (define_insn "*absneg<mode>2_sse"
9546   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9547         (match_operator:MODEF 3 "absneg_operator"
9548           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9549    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9550    (clobber (reg:CC FLAGS_REG))]
9551   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9552   "#")
9553
9554 (define_insn "*absneg<mode>2_i387"
9555   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9556         (match_operator:X87MODEF 3 "absneg_operator"
9557           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9558    (use (match_operand 2 "" ""))
9559    (clobber (reg:CC FLAGS_REG))]
9560   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9561   "#")
9562
9563 (define_expand "<code>tf2"
9564   [(set (match_operand:TF 0 "register_operand" "")
9565         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9566   "TARGET_SSE2"
9567   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9568
9569 (define_insn "*absnegtf2_sse"
9570   [(set (match_operand:TF 0 "register_operand" "=x,x")
9571         (match_operator:TF 3 "absneg_operator"
9572           [(match_operand:TF 1 "register_operand" "0,x")]))
9573    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9574    (clobber (reg:CC FLAGS_REG))]
9575   "TARGET_SSE2"
9576   "#")
9577
9578 ;; Splitters for fp abs and neg.
9579
9580 (define_split
9581   [(set (match_operand 0 "fp_register_operand" "")
9582         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9583    (use (match_operand 2 "" ""))
9584    (clobber (reg:CC FLAGS_REG))]
9585   "reload_completed"
9586   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9587
9588 (define_split
9589   [(set (match_operand 0 "register_operand" "")
9590         (match_operator 3 "absneg_operator"
9591           [(match_operand 1 "register_operand" "")]))
9592    (use (match_operand 2 "nonimmediate_operand" ""))
9593    (clobber (reg:CC FLAGS_REG))]
9594   "reload_completed && SSE_REG_P (operands[0])"
9595   [(set (match_dup 0) (match_dup 3))]
9596 {
9597   enum machine_mode mode = GET_MODE (operands[0]);
9598   enum machine_mode vmode = GET_MODE (operands[2]);
9599   rtx tmp;
9600
9601   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9602   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9603   if (operands_match_p (operands[0], operands[2]))
9604     {
9605       tmp = operands[1];
9606       operands[1] = operands[2];
9607       operands[2] = tmp;
9608     }
9609   if (GET_CODE (operands[3]) == ABS)
9610     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9611   else
9612     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9613   operands[3] = tmp;
9614 })
9615
9616 (define_split
9617   [(set (match_operand:SF 0 "register_operand" "")
9618         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9619    (use (match_operand:V4SF 2 "" ""))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "reload_completed"
9622   [(parallel [(set (match_dup 0) (match_dup 1))
9623               (clobber (reg:CC FLAGS_REG))])]
9624 {
9625   rtx tmp;
9626   operands[0] = gen_lowpart (SImode, operands[0]);
9627   if (GET_CODE (operands[1]) == ABS)
9628     {
9629       tmp = gen_int_mode (0x7fffffff, SImode);
9630       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9631     }
9632   else
9633     {
9634       tmp = gen_int_mode (0x80000000, SImode);
9635       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9636     }
9637   operands[1] = tmp;
9638 })
9639
9640 (define_split
9641   [(set (match_operand:DF 0 "register_operand" "")
9642         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9643    (use (match_operand 2 "" ""))
9644    (clobber (reg:CC FLAGS_REG))]
9645   "reload_completed"
9646   [(parallel [(set (match_dup 0) (match_dup 1))
9647               (clobber (reg:CC FLAGS_REG))])]
9648 {
9649   rtx tmp;
9650   if (TARGET_64BIT)
9651     {
9652       tmp = gen_lowpart (DImode, operands[0]);
9653       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9654       operands[0] = tmp;
9655
9656       if (GET_CODE (operands[1]) == ABS)
9657         tmp = const0_rtx;
9658       else
9659         tmp = gen_rtx_NOT (DImode, tmp);
9660     }
9661   else
9662     {
9663       operands[0] = gen_highpart (SImode, operands[0]);
9664       if (GET_CODE (operands[1]) == ABS)
9665         {
9666           tmp = gen_int_mode (0x7fffffff, SImode);
9667           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9668         }
9669       else
9670         {
9671           tmp = gen_int_mode (0x80000000, SImode);
9672           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9673         }
9674     }
9675   operands[1] = tmp;
9676 })
9677
9678 (define_split
9679   [(set (match_operand:XF 0 "register_operand" "")
9680         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9681    (use (match_operand 2 "" ""))
9682    (clobber (reg:CC FLAGS_REG))]
9683   "reload_completed"
9684   [(parallel [(set (match_dup 0) (match_dup 1))
9685               (clobber (reg:CC FLAGS_REG))])]
9686 {
9687   rtx tmp;
9688   operands[0] = gen_rtx_REG (SImode,
9689                              true_regnum (operands[0])
9690                              + (TARGET_64BIT ? 1 : 2));
9691   if (GET_CODE (operands[1]) == ABS)
9692     {
9693       tmp = GEN_INT (0x7fff);
9694       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9695     }
9696   else
9697     {
9698       tmp = GEN_INT (0x8000);
9699       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9700     }
9701   operands[1] = tmp;
9702 })
9703
9704 ;; Conditionalize these after reload. If they match before reload, we
9705 ;; lose the clobber and ability to use integer instructions.
9706
9707 (define_insn "*<code><mode>2_1"
9708   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9709         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9710   "TARGET_80387
9711    && (reload_completed
9712        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9713   "f<absnegprefix>"
9714   [(set_attr "type" "fsgn")
9715    (set_attr "mode" "<MODE>")])
9716
9717 (define_insn "*<code>extendsfdf2"
9718   [(set (match_operand:DF 0 "register_operand" "=f")
9719         (absneg:DF (float_extend:DF
9720                      (match_operand:SF 1 "register_operand" "0"))))]
9721   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9722   "f<absnegprefix>"
9723   [(set_attr "type" "fsgn")
9724    (set_attr "mode" "DF")])
9725
9726 (define_insn "*<code>extendsfxf2"
9727   [(set (match_operand:XF 0 "register_operand" "=f")
9728         (absneg:XF (float_extend:XF
9729                      (match_operand:SF 1 "register_operand" "0"))))]
9730   "TARGET_80387"
9731   "f<absnegprefix>"
9732   [(set_attr "type" "fsgn")
9733    (set_attr "mode" "XF")])
9734
9735 (define_insn "*<code>extenddfxf2"
9736   [(set (match_operand:XF 0 "register_operand" "=f")
9737         (absneg:XF (float_extend:XF
9738                       (match_operand:DF 1 "register_operand" "0"))))]
9739   "TARGET_80387"
9740   "f<absnegprefix>"
9741   [(set_attr "type" "fsgn")
9742    (set_attr "mode" "XF")])
9743
9744 ;; Copysign instructions
9745
9746 (define_mode_iterator CSGNMODE [SF DF TF])
9747 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9748
9749 (define_expand "copysign<mode>3"
9750   [(match_operand:CSGNMODE 0 "register_operand" "")
9751    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9752    (match_operand:CSGNMODE 2 "register_operand" "")]
9753   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9754    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9755 {
9756   ix86_expand_copysign (operands);
9757   DONE;
9758 })
9759
9760 (define_insn_and_split "copysign<mode>3_const"
9761   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9762         (unspec:CSGNMODE
9763           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9764            (match_operand:CSGNMODE 2 "register_operand" "0")
9765            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9766           UNSPEC_COPYSIGN))]
9767   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9768    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9769   "#"
9770   "&& reload_completed"
9771   [(const_int 0)]
9772 {
9773   ix86_split_copysign_const (operands);
9774   DONE;
9775 })
9776
9777 (define_insn "copysign<mode>3_var"
9778   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9779         (unspec:CSGNMODE
9780           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9781            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9782            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9783            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9784           UNSPEC_COPYSIGN))
9785    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9786   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9787    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9788   "#")
9789
9790 (define_split
9791   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9792         (unspec:CSGNMODE
9793           [(match_operand:CSGNMODE 2 "register_operand" "")
9794            (match_operand:CSGNMODE 3 "register_operand" "")
9795            (match_operand:<CSGNVMODE> 4 "" "")
9796            (match_operand:<CSGNVMODE> 5 "" "")]
9797           UNSPEC_COPYSIGN))
9798    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9799   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9800     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9801    && reload_completed"
9802   [(const_int 0)]
9803 {
9804   ix86_split_copysign_var (operands);
9805   DONE;
9806 })
9807 \f
9808 ;; One complement instructions
9809
9810 (define_expand "one_cmpl<mode>2"
9811   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9812         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9813   ""
9814   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9815
9816 (define_insn "*one_cmpl<mode>2_1"
9817   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9818         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9819   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9820   "not{<imodesuffix>}\t%0"
9821   [(set_attr "type" "negnot")
9822    (set_attr "mode" "<MODE>")])
9823
9824 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9825 (define_insn "*one_cmplqi2_1"
9826   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9827         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9828   "ix86_unary_operator_ok (NOT, QImode, operands)"
9829   "@
9830    not{b}\t%0
9831    not{l}\t%k0"
9832   [(set_attr "type" "negnot")
9833    (set_attr "mode" "QI,SI")])
9834
9835 ;; ??? Currently never generated - xor is used instead.
9836 (define_insn "*one_cmplsi2_1_zext"
9837   [(set (match_operand:DI 0 "register_operand" "=r")
9838         (zero_extend:DI
9839           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9840   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9841   "not{l}\t%k0"
9842   [(set_attr "type" "negnot")
9843    (set_attr "mode" "SI")])
9844
9845 (define_insn "*one_cmpl<mode>2_2"
9846   [(set (reg FLAGS_REG)
9847         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9848                  (const_int 0)))
9849    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9850         (not:SWI (match_dup 1)))]
9851   "ix86_match_ccmode (insn, CCNOmode)
9852    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9853   "#"
9854   [(set_attr "type" "alu1")
9855    (set_attr "mode" "<MODE>")])
9856
9857 (define_split
9858   [(set (match_operand 0 "flags_reg_operand" "")
9859         (match_operator 2 "compare_operator"
9860           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9861            (const_int 0)]))
9862    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9863         (not:SWI (match_dup 3)))]
9864   "ix86_match_ccmode (insn, CCNOmode)"
9865   [(parallel [(set (match_dup 0)
9866                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9867                                     (const_int 0)]))
9868               (set (match_dup 1)
9869                    (xor:SWI (match_dup 3) (const_int -1)))])]
9870   "")
9871
9872 ;; ??? Currently never generated - xor is used instead.
9873 (define_insn "*one_cmplsi2_2_zext"
9874   [(set (reg FLAGS_REG)
9875         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9876                  (const_int 0)))
9877    (set (match_operand:DI 0 "register_operand" "=r")
9878         (zero_extend:DI (not:SI (match_dup 1))))]
9879   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9880    && ix86_unary_operator_ok (NOT, SImode, operands)"
9881   "#"
9882   [(set_attr "type" "alu1")
9883    (set_attr "mode" "SI")])
9884
9885 (define_split
9886   [(set (match_operand 0 "flags_reg_operand" "")
9887         (match_operator 2 "compare_operator"
9888           [(not:SI (match_operand:SI 3 "register_operand" ""))
9889            (const_int 0)]))
9890    (set (match_operand:DI 1 "register_operand" "")
9891         (zero_extend:DI (not:SI (match_dup 3))))]
9892   "ix86_match_ccmode (insn, CCNOmode)"
9893   [(parallel [(set (match_dup 0)
9894                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9895                                     (const_int 0)]))
9896               (set (match_dup 1)
9897                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9898   "")
9899 \f
9900 ;; Arithmetic shift instructions
9901
9902 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9903 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9904 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9905 ;; from the assembler input.
9906 ;;
9907 ;; This instruction shifts the target reg/mem as usual, but instead of
9908 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9909 ;; is a left shift double, bits are taken from the high order bits of
9910 ;; reg, else if the insn is a shift right double, bits are taken from the
9911 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9912 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9913 ;;
9914 ;; Since sh[lr]d does not change the `reg' operand, that is done
9915 ;; separately, making all shifts emit pairs of shift double and normal
9916 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9917 ;; support a 63 bit shift, each shift where the count is in a reg expands
9918 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9919 ;;
9920 ;; If the shift count is a constant, we need never emit more than one
9921 ;; shift pair, instead using moves and sign extension for counts greater
9922 ;; than 31.
9923
9924 (define_expand "ashlti3"
9925   [(set (match_operand:TI 0 "register_operand" "")
9926         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9927                    (match_operand:QI 2 "nonmemory_operand" "")))]
9928   "TARGET_64BIT"
9929   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9930
9931 ;; This pattern must be defined before *ashlti3_1 to prevent
9932 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
9933
9934 (define_insn "*avx_ashlti3"
9935   [(set (match_operand:TI 0 "register_operand" "=x")
9936         (ashift:TI (match_operand:TI 1 "register_operand" "x")
9937                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
9938   "TARGET_AVX"
9939 {
9940   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
9941   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
9942 }
9943   [(set_attr "type" "sseishft")
9944    (set_attr "prefix" "vex")
9945    (set_attr "length_immediate" "1")
9946    (set_attr "mode" "TI")])
9947
9948 (define_insn "sse2_ashlti3"
9949   [(set (match_operand:TI 0 "register_operand" "=x")
9950         (ashift:TI (match_operand:TI 1 "register_operand" "0")
9951                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
9952   "TARGET_SSE2"
9953 {
9954   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
9955   return "pslldq\t{%2, %0|%0, %2}";
9956 }
9957   [(set_attr "type" "sseishft")
9958    (set_attr "prefix_data16" "1")
9959    (set_attr "length_immediate" "1")
9960    (set_attr "mode" "TI")])
9961
9962 (define_insn "*ashlti3_1"
9963   [(set (match_operand:TI 0 "register_operand" "=&r,r")
9964         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9965                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9966    (clobber (reg:CC FLAGS_REG))]
9967   "TARGET_64BIT"
9968   "#"
9969   [(set_attr "type" "multi")])
9970
9971 (define_peephole2
9972   [(match_scratch:DI 3 "r")
9973    (parallel [(set (match_operand:TI 0 "register_operand" "")
9974                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9975                               (match_operand:QI 2 "nonmemory_operand" "")))
9976               (clobber (reg:CC FLAGS_REG))])
9977    (match_dup 3)]
9978   "TARGET_64BIT"
9979   [(const_int 0)]
9980   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9981
9982 (define_split
9983   [(set (match_operand:TI 0 "register_operand" "")
9984         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9985                    (match_operand:QI 2 "nonmemory_operand" "")))
9986    (clobber (reg:CC FLAGS_REG))]
9987   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9988                     ? epilogue_completed : reload_completed)"
9989   [(const_int 0)]
9990   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9991
9992 (define_insn "x86_64_shld"
9993   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9994         (ior:DI (ashift:DI (match_dup 0)
9995                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9996                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9997                   (minus:QI (const_int 64) (match_dup 2)))))
9998    (clobber (reg:CC FLAGS_REG))]
9999   "TARGET_64BIT"
10000   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10001   [(set_attr "type" "ishift")
10002    (set_attr "prefix_0f" "1")
10003    (set_attr "mode" "DI")
10004    (set_attr "athlon_decode" "vector")
10005    (set_attr "amdfam10_decode" "vector")])
10006
10007 (define_expand "x86_64_shift_adj_1"
10008   [(set (reg:CCZ FLAGS_REG)
10009         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10010                              (const_int 64))
10011                      (const_int 0)))
10012    (set (match_operand:DI 0 "register_operand" "")
10013         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10014                          (match_operand:DI 1 "register_operand" "")
10015                          (match_dup 0)))
10016    (set (match_dup 1)
10017         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10018                          (match_operand:DI 3 "register_operand" "r")
10019                          (match_dup 1)))]
10020   "TARGET_64BIT"
10021   "")
10022
10023 (define_expand "x86_64_shift_adj_2"
10024   [(use (match_operand:DI 0 "register_operand" ""))
10025    (use (match_operand:DI 1 "register_operand" ""))
10026    (use (match_operand:QI 2 "register_operand" ""))]
10027   "TARGET_64BIT"
10028 {
10029   rtx label = gen_label_rtx ();
10030   rtx tmp;
10031
10032   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10033
10034   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10035   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10036   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10037                               gen_rtx_LABEL_REF (VOIDmode, label),
10038                               pc_rtx);
10039   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10040   JUMP_LABEL (tmp) = label;
10041
10042   emit_move_insn (operands[0], operands[1]);
10043   ix86_expand_clear (operands[1]);
10044
10045   emit_label (label);
10046   LABEL_NUSES (label) = 1;
10047
10048   DONE;
10049 })
10050
10051 (define_expand "ashldi3"
10052   [(set (match_operand:DI 0 "shiftdi_operand" "")
10053         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10054                    (match_operand:QI 2 "nonmemory_operand" "")))]
10055   ""
10056   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10057
10058 (define_insn "*ashldi3_1_rex64"
10059   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10060         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10061                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10062    (clobber (reg:CC FLAGS_REG))]
10063   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10064 {
10065   switch (get_attr_type (insn))
10066     {
10067     case TYPE_ALU:
10068       gcc_assert (operands[2] == const1_rtx);
10069       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10070       return "add{q}\t%0, %0";
10071
10072     case TYPE_LEA:
10073       gcc_assert (CONST_INT_P (operands[2]));
10074       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10075       operands[1] = gen_rtx_MULT (DImode, operands[1],
10076                                   GEN_INT (1 << INTVAL (operands[2])));
10077       return "lea{q}\t{%a1, %0|%0, %a1}";
10078
10079     default:
10080       if (REG_P (operands[2]))
10081         return "sal{q}\t{%b2, %0|%0, %b2}";
10082       else if (operands[2] == const1_rtx
10083                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10084         return "sal{q}\t%0";
10085       else
10086         return "sal{q}\t{%2, %0|%0, %2}";
10087     }
10088 }
10089   [(set (attr "type")
10090      (cond [(eq_attr "alternative" "1")
10091               (const_string "lea")
10092             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10093                           (const_int 0))
10094                       (match_operand 0 "register_operand" ""))
10095                  (match_operand 2 "const1_operand" ""))
10096               (const_string "alu")
10097            ]
10098            (const_string "ishift")))
10099    (set (attr "length_immediate")
10100      (if_then_else
10101        (ior (eq_attr "type" "alu")
10102             (and (eq_attr "type" "ishift")
10103                  (and (match_operand 2 "const1_operand" "")
10104                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10105                           (const_int 0)))))
10106        (const_string "0")
10107        (const_string "*")))
10108    (set_attr "mode" "DI")])
10109
10110 ;; Convert lea to the lea pattern to avoid flags dependency.
10111 (define_split
10112   [(set (match_operand:DI 0 "register_operand" "")
10113         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10114                    (match_operand:QI 2 "immediate_operand" "")))
10115    (clobber (reg:CC FLAGS_REG))]
10116   "TARGET_64BIT && reload_completed
10117    && true_regnum (operands[0]) != true_regnum (operands[1])"
10118   [(set (match_dup 0)
10119         (mult:DI (match_dup 1)
10120                  (match_dup 2)))]
10121   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10122
10123 ;; This pattern can't accept a variable shift count, since shifts by
10124 ;; zero don't affect the flags.  We assume that shifts by constant
10125 ;; zero are optimized away.
10126 (define_insn "*ashldi3_cmp_rex64"
10127   [(set (reg FLAGS_REG)
10128         (compare
10129           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10130                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10131           (const_int 0)))
10132    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10133         (ashift:DI (match_dup 1) (match_dup 2)))]
10134   "TARGET_64BIT
10135    && (optimize_function_for_size_p (cfun)
10136        || !TARGET_PARTIAL_FLAG_REG_STALL
10137        || (operands[2] == const1_rtx
10138            && (TARGET_SHIFT1
10139                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10140    && ix86_match_ccmode (insn, CCGOCmode)
10141    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10142 {
10143   switch (get_attr_type (insn))
10144     {
10145     case TYPE_ALU:
10146       gcc_assert (operands[2] == const1_rtx);
10147       return "add{q}\t%0, %0";
10148
10149     default:
10150       if (REG_P (operands[2]))
10151         return "sal{q}\t{%b2, %0|%0, %b2}";
10152       else if (operands[2] == const1_rtx
10153                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10154         return "sal{q}\t%0";
10155       else
10156         return "sal{q}\t{%2, %0|%0, %2}";
10157     }
10158 }
10159   [(set (attr "type")
10160      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10161                           (const_int 0))
10162                       (match_operand 0 "register_operand" ""))
10163                  (match_operand 2 "const1_operand" ""))
10164               (const_string "alu")
10165            ]
10166            (const_string "ishift")))
10167    (set (attr "length_immediate")
10168      (if_then_else
10169        (ior (eq_attr "type" "alu")
10170             (and (eq_attr "type" "ishift")
10171                  (and (match_operand 2 "const1_operand" "")
10172                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10173                           (const_int 0)))))
10174        (const_string "0")
10175        (const_string "*")))
10176    (set_attr "mode" "DI")])
10177
10178 (define_insn "*ashldi3_cconly_rex64"
10179   [(set (reg FLAGS_REG)
10180         (compare
10181           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10182                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10183           (const_int 0)))
10184    (clobber (match_scratch:DI 0 "=r"))]
10185   "TARGET_64BIT
10186    && (optimize_function_for_size_p (cfun)
10187        || !TARGET_PARTIAL_FLAG_REG_STALL
10188        || (operands[2] == const1_rtx
10189            && (TARGET_SHIFT1
10190                || TARGET_DOUBLE_WITH_ADD)))
10191    && ix86_match_ccmode (insn, CCGOCmode)
10192    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10193 {
10194   switch (get_attr_type (insn))
10195     {
10196     case TYPE_ALU:
10197       gcc_assert (operands[2] == const1_rtx);
10198       return "add{q}\t%0, %0";
10199
10200     default:
10201       if (REG_P (operands[2]))
10202         return "sal{q}\t{%b2, %0|%0, %b2}";
10203       else if (operands[2] == const1_rtx
10204                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10205         return "sal{q}\t%0";
10206       else
10207         return "sal{q}\t{%2, %0|%0, %2}";
10208     }
10209 }
10210   [(set (attr "type")
10211      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10212                           (const_int 0))
10213                       (match_operand 0 "register_operand" ""))
10214                  (match_operand 2 "const1_operand" ""))
10215               (const_string "alu")
10216            ]
10217            (const_string "ishift")))
10218    (set (attr "length_immediate")
10219      (if_then_else
10220        (ior (eq_attr "type" "alu")
10221             (and (eq_attr "type" "ishift")
10222                  (and (match_operand 2 "const1_operand" "")
10223                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10224                           (const_int 0)))))
10225        (const_string "0")
10226        (const_string "*")))
10227    (set_attr "mode" "DI")])
10228
10229 (define_insn "*ashldi3_1"
10230   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10231         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10232                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10233    (clobber (reg:CC FLAGS_REG))]
10234   "!TARGET_64BIT"
10235   "#"
10236   [(set_attr "type" "multi")])
10237
10238 ;; By default we don't ask for a scratch register, because when DImode
10239 ;; values are manipulated, registers are already at a premium.  But if
10240 ;; we have one handy, we won't turn it away.
10241 (define_peephole2
10242   [(match_scratch:SI 3 "r")
10243    (parallel [(set (match_operand:DI 0 "register_operand" "")
10244                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10245                               (match_operand:QI 2 "nonmemory_operand" "")))
10246               (clobber (reg:CC FLAGS_REG))])
10247    (match_dup 3)]
10248   "!TARGET_64BIT && TARGET_CMOVE"
10249   [(const_int 0)]
10250   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10251
10252 (define_split
10253   [(set (match_operand:DI 0 "register_operand" "")
10254         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10255                    (match_operand:QI 2 "nonmemory_operand" "")))
10256    (clobber (reg:CC FLAGS_REG))]
10257   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10258                      ? epilogue_completed : reload_completed)"
10259   [(const_int 0)]
10260   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10261
10262 (define_insn "x86_shld"
10263   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10264         (ior:SI (ashift:SI (match_dup 0)
10265                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10266                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10267                   (minus:QI (const_int 32) (match_dup 2)))))
10268    (clobber (reg:CC FLAGS_REG))]
10269   ""
10270   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10271   [(set_attr "type" "ishift")
10272    (set_attr "prefix_0f" "1")
10273    (set_attr "mode" "SI")
10274    (set_attr "pent_pair" "np")
10275    (set_attr "athlon_decode" "vector")
10276    (set_attr "amdfam10_decode" "vector")])
10277
10278 (define_expand "x86_shift_adj_1"
10279   [(set (reg:CCZ FLAGS_REG)
10280         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10281                              (const_int 32))
10282                      (const_int 0)))
10283    (set (match_operand:SI 0 "register_operand" "")
10284         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10285                          (match_operand:SI 1 "register_operand" "")
10286                          (match_dup 0)))
10287    (set (match_dup 1)
10288         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10289                          (match_operand:SI 3 "register_operand" "r")
10290                          (match_dup 1)))]
10291   "TARGET_CMOVE"
10292   "")
10293
10294 (define_expand "x86_shift_adj_2"
10295   [(use (match_operand:SI 0 "register_operand" ""))
10296    (use (match_operand:SI 1 "register_operand" ""))
10297    (use (match_operand:QI 2 "register_operand" ""))]
10298   ""
10299 {
10300   rtx label = gen_label_rtx ();
10301   rtx tmp;
10302
10303   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10304
10305   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10306   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10307   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10308                               gen_rtx_LABEL_REF (VOIDmode, label),
10309                               pc_rtx);
10310   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10311   JUMP_LABEL (tmp) = label;
10312
10313   emit_move_insn (operands[0], operands[1]);
10314   ix86_expand_clear (operands[1]);
10315
10316   emit_label (label);
10317   LABEL_NUSES (label) = 1;
10318
10319   DONE;
10320 })
10321
10322 (define_expand "ashlsi3"
10323   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10324         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10325                    (match_operand:QI 2 "nonmemory_operand" "")))]
10326   ""
10327   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10328
10329 (define_insn "*ashlsi3_1"
10330   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10331         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10332                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10335 {
10336   switch (get_attr_type (insn))
10337     {
10338     case TYPE_ALU:
10339       gcc_assert (operands[2] == const1_rtx);
10340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10341       return "add{l}\t%0, %0";
10342
10343     case TYPE_LEA:
10344       return "#";
10345
10346     default:
10347       if (REG_P (operands[2]))
10348         return "sal{l}\t{%b2, %0|%0, %b2}";
10349       else if (operands[2] == const1_rtx
10350                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10351         return "sal{l}\t%0";
10352       else
10353         return "sal{l}\t{%2, %0|%0, %2}";
10354     }
10355 }
10356   [(set (attr "type")
10357      (cond [(eq_attr "alternative" "1")
10358               (const_string "lea")
10359             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10360                           (const_int 0))
10361                       (match_operand 0 "register_operand" ""))
10362                  (match_operand 2 "const1_operand" ""))
10363               (const_string "alu")
10364            ]
10365            (const_string "ishift")))
10366    (set (attr "length_immediate")
10367      (if_then_else
10368        (ior (eq_attr "type" "alu")
10369             (and (eq_attr "type" "ishift")
10370                  (and (match_operand 2 "const1_operand" "")
10371                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10372                           (const_int 0)))))
10373        (const_string "0")
10374        (const_string "*")))
10375    (set_attr "mode" "SI")])
10376
10377 ;; Convert lea to the lea pattern to avoid flags dependency.
10378 (define_split
10379   [(set (match_operand 0 "register_operand" "")
10380         (ashift (match_operand 1 "index_register_operand" "")
10381                 (match_operand:QI 2 "const_int_operand" "")))
10382    (clobber (reg:CC FLAGS_REG))]
10383   "reload_completed
10384    && true_regnum (operands[0]) != true_regnum (operands[1])
10385    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10386   [(const_int 0)]
10387 {
10388   rtx pat;
10389   enum machine_mode mode = GET_MODE (operands[0]);
10390
10391   if (GET_MODE_SIZE (mode) < 4)
10392     operands[0] = gen_lowpart (SImode, operands[0]);
10393   if (mode != Pmode)
10394     operands[1] = gen_lowpart (Pmode, operands[1]);
10395   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10396
10397   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10398   if (Pmode != SImode)
10399     pat = gen_rtx_SUBREG (SImode, pat, 0);
10400   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10401   DONE;
10402 })
10403
10404 ;; Rare case of shifting RSP is handled by generating move and shift
10405 (define_split
10406   [(set (match_operand 0 "register_operand" "")
10407         (ashift (match_operand 1 "register_operand" "")
10408                 (match_operand:QI 2 "const_int_operand" "")))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "reload_completed
10411    && true_regnum (operands[0]) != true_regnum (operands[1])"
10412   [(const_int 0)]
10413 {
10414   rtx pat, clob;
10415   emit_move_insn (operands[0], operands[1]);
10416   pat = gen_rtx_SET (VOIDmode, operands[0],
10417                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10418                                      operands[0], operands[2]));
10419   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10420   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10421   DONE;
10422 })
10423
10424 (define_insn "*ashlsi3_1_zext"
10425   [(set (match_operand:DI 0 "register_operand" "=r,r")
10426         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10427                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10428    (clobber (reg:CC FLAGS_REG))]
10429   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10430 {
10431   switch (get_attr_type (insn))
10432     {
10433     case TYPE_ALU:
10434       gcc_assert (operands[2] == const1_rtx);
10435       return "add{l}\t%k0, %k0";
10436
10437     case TYPE_LEA:
10438       return "#";
10439
10440     default:
10441       if (REG_P (operands[2]))
10442         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10443       else if (operands[2] == const1_rtx
10444                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445         return "sal{l}\t%k0";
10446       else
10447         return "sal{l}\t{%2, %k0|%k0, %2}";
10448     }
10449 }
10450   [(set (attr "type")
10451      (cond [(eq_attr "alternative" "1")
10452               (const_string "lea")
10453             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10454                      (const_int 0))
10455                  (match_operand 2 "const1_operand" ""))
10456               (const_string "alu")
10457            ]
10458            (const_string "ishift")))
10459    (set (attr "length_immediate")
10460      (if_then_else
10461        (ior (eq_attr "type" "alu")
10462             (and (eq_attr "type" "ishift")
10463                  (and (match_operand 2 "const1_operand" "")
10464                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10465                           (const_int 0)))))
10466        (const_string "0")
10467        (const_string "*")))
10468    (set_attr "mode" "SI")])
10469
10470 ;; Convert lea to the lea pattern to avoid flags dependency.
10471 (define_split
10472   [(set (match_operand:DI 0 "register_operand" "")
10473         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10474                                 (match_operand:QI 2 "const_int_operand" ""))))
10475    (clobber (reg:CC FLAGS_REG))]
10476   "TARGET_64BIT && reload_completed
10477    && true_regnum (operands[0]) != true_regnum (operands[1])"
10478   [(set (match_dup 0) (zero_extend:DI
10479                         (subreg:SI (mult:SI (match_dup 1)
10480                                             (match_dup 2)) 0)))]
10481 {
10482   operands[1] = gen_lowpart (Pmode, operands[1]);
10483   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10484 })
10485
10486 ;; This pattern can't accept a variable shift count, since shifts by
10487 ;; zero don't affect the flags.  We assume that shifts by constant
10488 ;; zero are optimized away.
10489 (define_insn "*ashlsi3_cmp"
10490   [(set (reg FLAGS_REG)
10491         (compare
10492           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10493                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10494           (const_int 0)))
10495    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10496         (ashift:SI (match_dup 1) (match_dup 2)))]
10497    "(optimize_function_for_size_p (cfun)
10498      || !TARGET_PARTIAL_FLAG_REG_STALL
10499      || (operands[2] == const1_rtx
10500          && (TARGET_SHIFT1
10501              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10502    && ix86_match_ccmode (insn, CCGOCmode)
10503    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10504 {
10505   switch (get_attr_type (insn))
10506     {
10507     case TYPE_ALU:
10508       gcc_assert (operands[2] == const1_rtx);
10509       return "add{l}\t%0, %0";
10510
10511     default:
10512       if (REG_P (operands[2]))
10513         return "sal{l}\t{%b2, %0|%0, %b2}";
10514       else if (operands[2] == const1_rtx
10515                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10516         return "sal{l}\t%0";
10517       else
10518         return "sal{l}\t{%2, %0|%0, %2}";
10519     }
10520 }
10521   [(set (attr "type")
10522      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10523                           (const_int 0))
10524                       (match_operand 0 "register_operand" ""))
10525                  (match_operand 2 "const1_operand" ""))
10526               (const_string "alu")
10527            ]
10528            (const_string "ishift")))
10529    (set (attr "length_immediate")
10530      (if_then_else
10531        (ior (eq_attr "type" "alu")
10532             (and (eq_attr "type" "ishift")
10533                  (and (match_operand 2 "const1_operand" "")
10534                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10535                           (const_int 0)))))
10536        (const_string "0")
10537        (const_string "*")))
10538    (set_attr "mode" "SI")])
10539
10540 (define_insn "*ashlsi3_cconly"
10541   [(set (reg FLAGS_REG)
10542         (compare
10543           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10544                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10545           (const_int 0)))
10546    (clobber (match_scratch:SI 0 "=r"))]
10547   "(optimize_function_for_size_p (cfun)
10548     || !TARGET_PARTIAL_FLAG_REG_STALL
10549     || (operands[2] == const1_rtx
10550         && (TARGET_SHIFT1
10551             || TARGET_DOUBLE_WITH_ADD)))
10552    && ix86_match_ccmode (insn, CCGOCmode)
10553    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10554 {
10555   switch (get_attr_type (insn))
10556     {
10557     case TYPE_ALU:
10558       gcc_assert (operands[2] == const1_rtx);
10559       return "add{l}\t%0, %0";
10560
10561     default:
10562       if (REG_P (operands[2]))
10563         return "sal{l}\t{%b2, %0|%0, %b2}";
10564       else if (operands[2] == const1_rtx
10565                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10566         return "sal{l}\t%0";
10567       else
10568         return "sal{l}\t{%2, %0|%0, %2}";
10569     }
10570 }
10571   [(set (attr "type")
10572      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10573                           (const_int 0))
10574                       (match_operand 0 "register_operand" ""))
10575                  (match_operand 2 "const1_operand" ""))
10576               (const_string "alu")
10577            ]
10578            (const_string "ishift")))
10579    (set (attr "length_immediate")
10580      (if_then_else
10581        (ior (eq_attr "type" "alu")
10582             (and (eq_attr "type" "ishift")
10583                  (and (match_operand 2 "const1_operand" "")
10584                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10585                           (const_int 0)))))
10586        (const_string "0")
10587        (const_string "*")))
10588    (set_attr "mode" "SI")])
10589
10590 (define_insn "*ashlsi3_cmp_zext"
10591   [(set (reg FLAGS_REG)
10592         (compare
10593           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10594                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10595           (const_int 0)))
10596    (set (match_operand:DI 0 "register_operand" "=r")
10597         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10598   "TARGET_64BIT
10599    && (optimize_function_for_size_p (cfun)
10600        || !TARGET_PARTIAL_FLAG_REG_STALL
10601        || (operands[2] == const1_rtx
10602            && (TARGET_SHIFT1
10603                || TARGET_DOUBLE_WITH_ADD)))
10604    && ix86_match_ccmode (insn, CCGOCmode)
10605    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10606 {
10607   switch (get_attr_type (insn))
10608     {
10609     case TYPE_ALU:
10610       gcc_assert (operands[2] == const1_rtx);
10611       return "add{l}\t%k0, %k0";
10612
10613     default:
10614       if (REG_P (operands[2]))
10615         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10616       else if (operands[2] == const1_rtx
10617                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10618         return "sal{l}\t%k0";
10619       else
10620         return "sal{l}\t{%2, %k0|%k0, %2}";
10621     }
10622 }
10623   [(set (attr "type")
10624      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10625                      (const_int 0))
10626                  (match_operand 2 "const1_operand" ""))
10627               (const_string "alu")
10628            ]
10629            (const_string "ishift")))
10630    (set (attr "length_immediate")
10631      (if_then_else
10632        (ior (eq_attr "type" "alu")
10633             (and (eq_attr "type" "ishift")
10634                  (and (match_operand 2 "const1_operand" "")
10635                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10636                           (const_int 0)))))
10637        (const_string "0")
10638        (const_string "*")))
10639    (set_attr "mode" "SI")])
10640
10641 (define_expand "ashlhi3"
10642   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10643         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10644                    (match_operand:QI 2 "nonmemory_operand" "")))]
10645   "TARGET_HIMODE_MATH"
10646   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10647
10648 (define_insn "*ashlhi3_1_lea"
10649   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10650         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10651                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10652    (clobber (reg:CC FLAGS_REG))]
10653   "!TARGET_PARTIAL_REG_STALL
10654    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10655 {
10656   switch (get_attr_type (insn))
10657     {
10658     case TYPE_LEA:
10659       return "#";
10660     case TYPE_ALU:
10661       gcc_assert (operands[2] == const1_rtx);
10662       return "add{w}\t%0, %0";
10663
10664     default:
10665       if (REG_P (operands[2]))
10666         return "sal{w}\t{%b2, %0|%0, %b2}";
10667       else if (operands[2] == const1_rtx
10668                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10669         return "sal{w}\t%0";
10670       else
10671         return "sal{w}\t{%2, %0|%0, %2}";
10672     }
10673 }
10674   [(set (attr "type")
10675      (cond [(eq_attr "alternative" "1")
10676               (const_string "lea")
10677             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10678                           (const_int 0))
10679                       (match_operand 0 "register_operand" ""))
10680                  (match_operand 2 "const1_operand" ""))
10681               (const_string "alu")
10682            ]
10683            (const_string "ishift")))
10684    (set (attr "length_immediate")
10685      (if_then_else
10686        (ior (eq_attr "type" "alu")
10687             (and (eq_attr "type" "ishift")
10688                  (and (match_operand 2 "const1_operand" "")
10689                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10690                           (const_int 0)))))
10691        (const_string "0")
10692        (const_string "*")))
10693    (set_attr "mode" "HI,SI")])
10694
10695 (define_insn "*ashlhi3_1"
10696   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10697         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10698                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10699    (clobber (reg:CC FLAGS_REG))]
10700   "TARGET_PARTIAL_REG_STALL
10701    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10702 {
10703   switch (get_attr_type (insn))
10704     {
10705     case TYPE_ALU:
10706       gcc_assert (operands[2] == const1_rtx);
10707       return "add{w}\t%0, %0";
10708
10709     default:
10710       if (REG_P (operands[2]))
10711         return "sal{w}\t{%b2, %0|%0, %b2}";
10712       else if (operands[2] == const1_rtx
10713                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10714         return "sal{w}\t%0";
10715       else
10716         return "sal{w}\t{%2, %0|%0, %2}";
10717     }
10718 }
10719   [(set (attr "type")
10720      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10721                           (const_int 0))
10722                       (match_operand 0 "register_operand" ""))
10723                  (match_operand 2 "const1_operand" ""))
10724               (const_string "alu")
10725            ]
10726            (const_string "ishift")))
10727    (set (attr "length_immediate")
10728      (if_then_else
10729        (ior (eq_attr "type" "alu")
10730             (and (eq_attr "type" "ishift")
10731                  (and (match_operand 2 "const1_operand" "")
10732                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10733                           (const_int 0)))))
10734        (const_string "0")
10735        (const_string "*")))
10736    (set_attr "mode" "HI")])
10737
10738 ;; This pattern can't accept a variable shift count, since shifts by
10739 ;; zero don't affect the flags.  We assume that shifts by constant
10740 ;; zero are optimized away.
10741 (define_insn "*ashlhi3_cmp"
10742   [(set (reg FLAGS_REG)
10743         (compare
10744           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10745                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10746           (const_int 0)))
10747    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10748         (ashift:HI (match_dup 1) (match_dup 2)))]
10749   "(optimize_function_for_size_p (cfun)
10750     || !TARGET_PARTIAL_FLAG_REG_STALL
10751     || (operands[2] == const1_rtx
10752         && (TARGET_SHIFT1
10753             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10754    && ix86_match_ccmode (insn, CCGOCmode)
10755    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10756 {
10757   switch (get_attr_type (insn))
10758     {
10759     case TYPE_ALU:
10760       gcc_assert (operands[2] == const1_rtx);
10761       return "add{w}\t%0, %0";
10762
10763     default:
10764       if (REG_P (operands[2]))
10765         return "sal{w}\t{%b2, %0|%0, %b2}";
10766       else if (operands[2] == const1_rtx
10767                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10768         return "sal{w}\t%0";
10769       else
10770         return "sal{w}\t{%2, %0|%0, %2}";
10771     }
10772 }
10773   [(set (attr "type")
10774      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10775                           (const_int 0))
10776                       (match_operand 0 "register_operand" ""))
10777                  (match_operand 2 "const1_operand" ""))
10778               (const_string "alu")
10779            ]
10780            (const_string "ishift")))
10781    (set (attr "length_immediate")
10782      (if_then_else
10783        (ior (eq_attr "type" "alu")
10784             (and (eq_attr "type" "ishift")
10785                  (and (match_operand 2 "const1_operand" "")
10786                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10787                           (const_int 0)))))
10788        (const_string "0")
10789        (const_string "*")))
10790    (set_attr "mode" "HI")])
10791
10792 (define_insn "*ashlhi3_cconly"
10793   [(set (reg FLAGS_REG)
10794         (compare
10795           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10796                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10797           (const_int 0)))
10798    (clobber (match_scratch:HI 0 "=r"))]
10799   "(optimize_function_for_size_p (cfun)
10800     || !TARGET_PARTIAL_FLAG_REG_STALL
10801     || (operands[2] == const1_rtx
10802         && (TARGET_SHIFT1
10803             || TARGET_DOUBLE_WITH_ADD)))
10804    && ix86_match_ccmode (insn, CCGOCmode)
10805    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10806 {
10807   switch (get_attr_type (insn))
10808     {
10809     case TYPE_ALU:
10810       gcc_assert (operands[2] == const1_rtx);
10811       return "add{w}\t%0, %0";
10812
10813     default:
10814       if (REG_P (operands[2]))
10815         return "sal{w}\t{%b2, %0|%0, %b2}";
10816       else if (operands[2] == const1_rtx
10817                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10818         return "sal{w}\t%0";
10819       else
10820         return "sal{w}\t{%2, %0|%0, %2}";
10821     }
10822 }
10823   [(set (attr "type")
10824      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10825                           (const_int 0))
10826                       (match_operand 0 "register_operand" ""))
10827                  (match_operand 2 "const1_operand" ""))
10828               (const_string "alu")
10829            ]
10830            (const_string "ishift")))
10831    (set (attr "length_immediate")
10832      (if_then_else
10833        (ior (eq_attr "type" "alu")
10834             (and (eq_attr "type" "ishift")
10835                  (and (match_operand 2 "const1_operand" "")
10836                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10837                           (const_int 0)))))
10838        (const_string "0")
10839        (const_string "*")))
10840    (set_attr "mode" "HI")])
10841
10842 (define_expand "ashlqi3"
10843   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10844         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10845                    (match_operand:QI 2 "nonmemory_operand" "")))]
10846   "TARGET_QIMODE_MATH"
10847   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10848
10849 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10850
10851 (define_insn "*ashlqi3_1_lea"
10852   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10853         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10854                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10855    (clobber (reg:CC FLAGS_REG))]
10856   "!TARGET_PARTIAL_REG_STALL
10857    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10858 {
10859   switch (get_attr_type (insn))
10860     {
10861     case TYPE_LEA:
10862       return "#";
10863     case TYPE_ALU:
10864       gcc_assert (operands[2] == const1_rtx);
10865       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10866         return "add{l}\t%k0, %k0";
10867       else
10868         return "add{b}\t%0, %0";
10869
10870     default:
10871       if (REG_P (operands[2]))
10872         {
10873           if (get_attr_mode (insn) == MODE_SI)
10874             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10875           else
10876             return "sal{b}\t{%b2, %0|%0, %b2}";
10877         }
10878       else if (operands[2] == const1_rtx
10879                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10880         {
10881           if (get_attr_mode (insn) == MODE_SI)
10882             return "sal{l}\t%0";
10883           else
10884             return "sal{b}\t%0";
10885         }
10886       else
10887         {
10888           if (get_attr_mode (insn) == MODE_SI)
10889             return "sal{l}\t{%2, %k0|%k0, %2}";
10890           else
10891             return "sal{b}\t{%2, %0|%0, %2}";
10892         }
10893     }
10894 }
10895   [(set (attr "type")
10896      (cond [(eq_attr "alternative" "2")
10897               (const_string "lea")
10898             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10899                           (const_int 0))
10900                       (match_operand 0 "register_operand" ""))
10901                  (match_operand 2 "const1_operand" ""))
10902               (const_string "alu")
10903            ]
10904            (const_string "ishift")))
10905    (set (attr "length_immediate")
10906      (if_then_else
10907        (ior (eq_attr "type" "alu")
10908             (and (eq_attr "type" "ishift")
10909                  (and (match_operand 2 "const1_operand" "")
10910                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10911                           (const_int 0)))))
10912        (const_string "0")
10913        (const_string "*")))
10914    (set_attr "mode" "QI,SI,SI")])
10915
10916 (define_insn "*ashlqi3_1"
10917   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10918         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10919                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10920    (clobber (reg:CC FLAGS_REG))]
10921   "TARGET_PARTIAL_REG_STALL
10922    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10923 {
10924   switch (get_attr_type (insn))
10925     {
10926     case TYPE_ALU:
10927       gcc_assert (operands[2] == const1_rtx);
10928       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10929         return "add{l}\t%k0, %k0";
10930       else
10931         return "add{b}\t%0, %0";
10932
10933     default:
10934       if (REG_P (operands[2]))
10935         {
10936           if (get_attr_mode (insn) == MODE_SI)
10937             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10938           else
10939             return "sal{b}\t{%b2, %0|%0, %b2}";
10940         }
10941       else if (operands[2] == const1_rtx
10942                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10943         {
10944           if (get_attr_mode (insn) == MODE_SI)
10945             return "sal{l}\t%0";
10946           else
10947             return "sal{b}\t%0";
10948         }
10949       else
10950         {
10951           if (get_attr_mode (insn) == MODE_SI)
10952             return "sal{l}\t{%2, %k0|%k0, %2}";
10953           else
10954             return "sal{b}\t{%2, %0|%0, %2}";
10955         }
10956     }
10957 }
10958   [(set (attr "type")
10959      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10960                           (const_int 0))
10961                       (match_operand 0 "register_operand" ""))
10962                  (match_operand 2 "const1_operand" ""))
10963               (const_string "alu")
10964            ]
10965            (const_string "ishift")))
10966    (set (attr "length_immediate")
10967      (if_then_else
10968        (ior (eq_attr "type" "alu")
10969             (and (eq_attr "type" "ishift")
10970                  (and (match_operand 2 "const1_operand" "")
10971                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10972                           (const_int 0)))))
10973        (const_string "0")
10974        (const_string "*")))
10975    (set_attr "mode" "QI,SI")])
10976
10977 ;; This pattern can't accept a variable shift count, since shifts by
10978 ;; zero don't affect the flags.  We assume that shifts by constant
10979 ;; zero are optimized away.
10980 (define_insn "*ashlqi3_cmp"
10981   [(set (reg FLAGS_REG)
10982         (compare
10983           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10984                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10985           (const_int 0)))
10986    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10987         (ashift:QI (match_dup 1) (match_dup 2)))]
10988   "(optimize_function_for_size_p (cfun)
10989     || !TARGET_PARTIAL_FLAG_REG_STALL
10990     || (operands[2] == const1_rtx
10991         && (TARGET_SHIFT1
10992             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10993    && ix86_match_ccmode (insn, CCGOCmode)
10994    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10995 {
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{b}\t%0, %0";
11001
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{b}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11007         return "sal{b}\t%0";
11008       else
11009         return "sal{b}\t{%2, %0|%0, %2}";
11010     }
11011 }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set (attr "length_immediate")
11021      (if_then_else
11022        (ior (eq_attr "type" "alu")
11023             (and (eq_attr "type" "ishift")
11024                  (and (match_operand 2 "const1_operand" "")
11025                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11026                           (const_int 0)))))
11027        (const_string "0")
11028        (const_string "*")))
11029    (set_attr "mode" "QI")])
11030
11031 (define_insn "*ashlqi3_cconly"
11032   [(set (reg FLAGS_REG)
11033         (compare
11034           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11035                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11036           (const_int 0)))
11037    (clobber (match_scratch:QI 0 "=q"))]
11038   "(optimize_function_for_size_p (cfun)
11039     || !TARGET_PARTIAL_FLAG_REG_STALL
11040     || (operands[2] == const1_rtx
11041         && (TARGET_SHIFT1
11042             || TARGET_DOUBLE_WITH_ADD)))
11043    && ix86_match_ccmode (insn, CCGOCmode)
11044    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11045 {
11046   switch (get_attr_type (insn))
11047     {
11048     case TYPE_ALU:
11049       gcc_assert (operands[2] == const1_rtx);
11050       return "add{b}\t%0, %0";
11051
11052     default:
11053       if (REG_P (operands[2]))
11054         return "sal{b}\t{%b2, %0|%0, %b2}";
11055       else if (operands[2] == const1_rtx
11056                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11057         return "sal{b}\t%0";
11058       else
11059         return "sal{b}\t{%2, %0|%0, %2}";
11060     }
11061 }
11062   [(set (attr "type")
11063      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11064                           (const_int 0))
11065                       (match_operand 0 "register_operand" ""))
11066                  (match_operand 2 "const1_operand" ""))
11067               (const_string "alu")
11068            ]
11069            (const_string "ishift")))
11070    (set (attr "length_immediate")
11071      (if_then_else
11072        (ior (eq_attr "type" "alu")
11073             (and (eq_attr "type" "ishift")
11074                  (and (match_operand 2 "const1_operand" "")
11075                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11076                           (const_int 0)))))
11077        (const_string "0")
11078        (const_string "*")))
11079    (set_attr "mode" "QI")])
11080
11081 ;; See comment above `ashldi3' about how this works.
11082
11083 (define_expand "ashrti3"
11084   [(set (match_operand:TI 0 "register_operand" "")
11085         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11086                      (match_operand:QI 2 "nonmemory_operand" "")))]
11087   "TARGET_64BIT"
11088   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11089
11090 (define_insn "*ashrti3_1"
11091   [(set (match_operand:TI 0 "register_operand" "=r")
11092         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11093                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "TARGET_64BIT"
11096   "#"
11097   [(set_attr "type" "multi")])
11098
11099 (define_peephole2
11100   [(match_scratch:DI 3 "r")
11101    (parallel [(set (match_operand:TI 0 "register_operand" "")
11102                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11103                                 (match_operand:QI 2 "nonmemory_operand" "")))
11104               (clobber (reg:CC FLAGS_REG))])
11105    (match_dup 3)]
11106   "TARGET_64BIT"
11107   [(const_int 0)]
11108   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11109
11110 (define_split
11111   [(set (match_operand:TI 0 "register_operand" "")
11112         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11113                      (match_operand:QI 2 "nonmemory_operand" "")))
11114    (clobber (reg:CC FLAGS_REG))]
11115   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11116                     ? epilogue_completed : reload_completed)"
11117   [(const_int 0)]
11118   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11119
11120 (define_insn "x86_64_shrd"
11121   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11122         (ior:DI (ashiftrt:DI (match_dup 0)
11123                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11124                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11125                   (minus:QI (const_int 64) (match_dup 2)))))
11126    (clobber (reg:CC FLAGS_REG))]
11127   "TARGET_64BIT"
11128   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11129   [(set_attr "type" "ishift")
11130    (set_attr "prefix_0f" "1")
11131    (set_attr "mode" "DI")
11132    (set_attr "athlon_decode" "vector")
11133    (set_attr "amdfam10_decode" "vector")])
11134
11135 (define_expand "ashrdi3"
11136   [(set (match_operand:DI 0 "shiftdi_operand" "")
11137         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11138                      (match_operand:QI 2 "nonmemory_operand" "")))]
11139   ""
11140   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11141
11142 (define_expand "x86_64_shift_adj_3"
11143   [(use (match_operand:DI 0 "register_operand" ""))
11144    (use (match_operand:DI 1 "register_operand" ""))
11145    (use (match_operand:QI 2 "register_operand" ""))]
11146   ""
11147 {
11148   rtx label = gen_label_rtx ();
11149   rtx tmp;
11150
11151   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11152
11153   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11154   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11155   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11156                               gen_rtx_LABEL_REF (VOIDmode, label),
11157                               pc_rtx);
11158   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11159   JUMP_LABEL (tmp) = label;
11160
11161   emit_move_insn (operands[0], operands[1]);
11162   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11163
11164   emit_label (label);
11165   LABEL_NUSES (label) = 1;
11166
11167   DONE;
11168 })
11169
11170 (define_insn "ashrdi3_63_rex64"
11171   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11172         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11173                      (match_operand:DI 2 "const_int_operand" "i,i")))
11174    (clobber (reg:CC FLAGS_REG))]
11175   "TARGET_64BIT && INTVAL (operands[2]) == 63
11176    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11177    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11178   "@
11179    {cqto|cqo}
11180    sar{q}\t{%2, %0|%0, %2}"
11181   [(set_attr "type" "imovx,ishift")
11182    (set_attr "prefix_0f" "0,*")
11183    (set_attr "length_immediate" "0,*")
11184    (set_attr "modrm" "0,1")
11185    (set_attr "mode" "DI")])
11186
11187 (define_insn "*ashrdi3_1_one_bit_rex64"
11188   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11189         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11190                      (match_operand:QI 2 "const1_operand" "")))
11191    (clobber (reg:CC FLAGS_REG))]
11192   "TARGET_64BIT
11193    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11194    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11195   "sar{q}\t%0"
11196   [(set_attr "type" "ishift")
11197    (set_attr "length_immediate" "0")
11198    (set_attr "mode" "DI")])
11199
11200 (define_insn "*ashrdi3_1_rex64"
11201   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11202         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11203                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11204    (clobber (reg:CC FLAGS_REG))]
11205   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11206   "@
11207    sar{q}\t{%2, %0|%0, %2}
11208    sar{q}\t{%b2, %0|%0, %b2}"
11209   [(set_attr "type" "ishift")
11210    (set_attr "mode" "DI")])
11211
11212 ;; This pattern can't accept a variable shift count, since shifts by
11213 ;; zero don't affect the flags.  We assume that shifts by constant
11214 ;; zero are optimized away.
11215 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11216   [(set (reg FLAGS_REG)
11217         (compare
11218           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11219                        (match_operand:QI 2 "const1_operand" ""))
11220           (const_int 0)))
11221    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11222         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11223   "TARGET_64BIT
11224    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11225    && ix86_match_ccmode (insn, CCGOCmode)
11226    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11227   "sar{q}\t%0"
11228   [(set_attr "type" "ishift")
11229    (set_attr "length_immediate" "0")
11230    (set_attr "mode" "DI")])
11231
11232 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11233   [(set (reg FLAGS_REG)
11234         (compare
11235           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11236                        (match_operand:QI 2 "const1_operand" ""))
11237           (const_int 0)))
11238    (clobber (match_scratch:DI 0 "=r"))]
11239   "TARGET_64BIT
11240    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11241    && ix86_match_ccmode (insn, CCGOCmode)
11242    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11243   "sar{q}\t%0"
11244   [(set_attr "type" "ishift")
11245    (set_attr "length_immediate" "0")
11246    (set_attr "mode" "DI")])
11247
11248 ;; This pattern can't accept a variable shift count, since shifts by
11249 ;; zero don't affect the flags.  We assume that shifts by constant
11250 ;; zero are optimized away.
11251 (define_insn "*ashrdi3_cmp_rex64"
11252   [(set (reg FLAGS_REG)
11253         (compare
11254           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11255                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11256           (const_int 0)))
11257    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11258         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11259   "TARGET_64BIT
11260    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11261    && ix86_match_ccmode (insn, CCGOCmode)
11262    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11263   "sar{q}\t{%2, %0|%0, %2}"
11264   [(set_attr "type" "ishift")
11265    (set_attr "mode" "DI")])
11266
11267 (define_insn "*ashrdi3_cconly_rex64"
11268   [(set (reg FLAGS_REG)
11269         (compare
11270           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11271                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11272           (const_int 0)))
11273    (clobber (match_scratch:DI 0 "=r"))]
11274   "TARGET_64BIT
11275    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11276    && ix86_match_ccmode (insn, CCGOCmode)
11277    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11278   "sar{q}\t{%2, %0|%0, %2}"
11279   [(set_attr "type" "ishift")
11280    (set_attr "mode" "DI")])
11281
11282 (define_insn "*ashrdi3_1"
11283   [(set (match_operand:DI 0 "register_operand" "=r")
11284         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11285                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11286    (clobber (reg:CC FLAGS_REG))]
11287   "!TARGET_64BIT"
11288   "#"
11289   [(set_attr "type" "multi")])
11290
11291 ;; By default we don't ask for a scratch register, because when DImode
11292 ;; values are manipulated, registers are already at a premium.  But if
11293 ;; we have one handy, we won't turn it away.
11294 (define_peephole2
11295   [(match_scratch:SI 3 "r")
11296    (parallel [(set (match_operand:DI 0 "register_operand" "")
11297                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11298                                 (match_operand:QI 2 "nonmemory_operand" "")))
11299               (clobber (reg:CC FLAGS_REG))])
11300    (match_dup 3)]
11301   "!TARGET_64BIT && TARGET_CMOVE"
11302   [(const_int 0)]
11303   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11304
11305 (define_split
11306   [(set (match_operand:DI 0 "register_operand" "")
11307         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11308                      (match_operand:QI 2 "nonmemory_operand" "")))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11311                      ? epilogue_completed : reload_completed)"
11312   [(const_int 0)]
11313   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11314
11315 (define_insn "x86_shrd"
11316   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11317         (ior:SI (ashiftrt:SI (match_dup 0)
11318                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11319                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11320                   (minus:QI (const_int 32) (match_dup 2)))))
11321    (clobber (reg:CC FLAGS_REG))]
11322   ""
11323   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11324   [(set_attr "type" "ishift")
11325    (set_attr "prefix_0f" "1")
11326    (set_attr "pent_pair" "np")
11327    (set_attr "mode" "SI")])
11328
11329 (define_expand "x86_shift_adj_3"
11330   [(use (match_operand:SI 0 "register_operand" ""))
11331    (use (match_operand:SI 1 "register_operand" ""))
11332    (use (match_operand:QI 2 "register_operand" ""))]
11333   ""
11334 {
11335   rtx label = gen_label_rtx ();
11336   rtx tmp;
11337
11338   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11339
11340   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11341   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11342   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11343                               gen_rtx_LABEL_REF (VOIDmode, label),
11344                               pc_rtx);
11345   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11346   JUMP_LABEL (tmp) = label;
11347
11348   emit_move_insn (operands[0], operands[1]);
11349   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11350
11351   emit_label (label);
11352   LABEL_NUSES (label) = 1;
11353
11354   DONE;
11355 })
11356
11357 (define_expand "ashrsi3_31"
11358   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11359                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11360                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11361               (clobber (reg:CC FLAGS_REG))])]
11362   "")
11363
11364 (define_insn "*ashrsi3_31"
11365   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11366         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11367                      (match_operand:SI 2 "const_int_operand" "i,i")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "INTVAL (operands[2]) == 31
11370    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11371    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11372   "@
11373    {cltd|cdq}
11374    sar{l}\t{%2, %0|%0, %2}"
11375   [(set_attr "type" "imovx,ishift")
11376    (set_attr "prefix_0f" "0,*")
11377    (set_attr "length_immediate" "0,*")
11378    (set_attr "modrm" "0,1")
11379    (set_attr "mode" "SI")])
11380
11381 (define_insn "*ashrsi3_31_zext"
11382   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11383         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11384                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11387    && INTVAL (operands[2]) == 31
11388    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11389   "@
11390    {cltd|cdq}
11391    sar{l}\t{%2, %k0|%k0, %2}"
11392   [(set_attr "type" "imovx,ishift")
11393    (set_attr "prefix_0f" "0,*")
11394    (set_attr "length_immediate" "0,*")
11395    (set_attr "modrm" "0,1")
11396    (set_attr "mode" "SI")])
11397
11398 (define_expand "ashrsi3"
11399   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11400         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11401                      (match_operand:QI 2 "nonmemory_operand" "")))]
11402   ""
11403   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11404
11405 (define_insn "*ashrsi3_1_one_bit"
11406   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11407         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11408                      (match_operand:QI 2 "const1_operand" "")))
11409    (clobber (reg:CC FLAGS_REG))]
11410   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11411    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412   "sar{l}\t%0"
11413   [(set_attr "type" "ishift")
11414    (set_attr "length_immediate" "0")
11415    (set_attr "mode" "SI")])
11416
11417 (define_insn "*ashrsi3_1_one_bit_zext"
11418   [(set (match_operand:DI 0 "register_operand" "=r")
11419         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11420                                      (match_operand:QI 2 "const1_operand" ""))))
11421    (clobber (reg:CC FLAGS_REG))]
11422   "TARGET_64BIT
11423    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11424    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11425   "sar{l}\t%k0"
11426   [(set_attr "type" "ishift")
11427    (set_attr "length_immediate" "0")
11428    (set_attr "mode" "SI")])
11429
11430 (define_insn "*ashrsi3_1"
11431   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11432         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11433                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11434    (clobber (reg:CC FLAGS_REG))]
11435   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11436   "@
11437    sar{l}\t{%2, %0|%0, %2}
11438    sar{l}\t{%b2, %0|%0, %b2}"
11439   [(set_attr "type" "ishift")
11440    (set_attr "mode" "SI")])
11441
11442 (define_insn "*ashrsi3_1_zext"
11443   [(set (match_operand:DI 0 "register_operand" "=r,r")
11444         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11445                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11446    (clobber (reg:CC FLAGS_REG))]
11447   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11448   "@
11449    sar{l}\t{%2, %k0|%k0, %2}
11450    sar{l}\t{%b2, %k0|%k0, %b2}"
11451   [(set_attr "type" "ishift")
11452    (set_attr "mode" "SI")])
11453
11454 ;; This pattern can't accept a variable shift count, since shifts by
11455 ;; zero don't affect the flags.  We assume that shifts by constant
11456 ;; zero are optimized away.
11457 (define_insn "*ashrsi3_one_bit_cmp"
11458   [(set (reg FLAGS_REG)
11459         (compare
11460           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11461                        (match_operand:QI 2 "const1_operand" ""))
11462           (const_int 0)))
11463    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11464         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11465   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11466    && ix86_match_ccmode (insn, CCGOCmode)
11467    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11468   "sar{l}\t%0"
11469   [(set_attr "type" "ishift")
11470    (set_attr "length_immediate" "0")
11471    (set_attr "mode" "SI")])
11472
11473 (define_insn "*ashrsi3_one_bit_cconly"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11477                        (match_operand:QI 2 "const1_operand" ""))
11478           (const_int 0)))
11479    (clobber (match_scratch:SI 0 "=r"))]
11480   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11481    && ix86_match_ccmode (insn, CCGOCmode)
11482    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11483   "sar{l}\t%0"
11484   [(set_attr "type" "ishift")
11485    (set_attr "length_immediate" "0")
11486    (set_attr "mode" "SI")])
11487
11488 (define_insn "*ashrsi3_one_bit_cmp_zext"
11489   [(set (reg FLAGS_REG)
11490         (compare
11491           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11492                        (match_operand:QI 2 "const1_operand" ""))
11493           (const_int 0)))
11494    (set (match_operand:DI 0 "register_operand" "=r")
11495         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11496   "TARGET_64BIT
11497    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11498    && ix86_match_ccmode (insn, CCmode)
11499    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11500   "sar{l}\t%k0"
11501   [(set_attr "type" "ishift")
11502    (set_attr "length_immediate" "0")
11503    (set_attr "mode" "SI")])
11504
11505 ;; This pattern can't accept a variable shift count, since shifts by
11506 ;; zero don't affect the flags.  We assume that shifts by constant
11507 ;; zero are optimized away.
11508 (define_insn "*ashrsi3_cmp"
11509   [(set (reg FLAGS_REG)
11510         (compare
11511           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11512                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11513           (const_int 0)))
11514    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11515         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11516   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11517    && ix86_match_ccmode (insn, CCGOCmode)
11518    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519   "sar{l}\t{%2, %0|%0, %2}"
11520   [(set_attr "type" "ishift")
11521    (set_attr "mode" "SI")])
11522
11523 (define_insn "*ashrsi3_cconly"
11524   [(set (reg FLAGS_REG)
11525         (compare
11526           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11527                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11528           (const_int 0)))
11529    (clobber (match_scratch:SI 0 "=r"))]
11530   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11531    && ix86_match_ccmode (insn, CCGOCmode)
11532    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11533   "sar{l}\t{%2, %0|%0, %2}"
11534   [(set_attr "type" "ishift")
11535    (set_attr "mode" "SI")])
11536
11537 (define_insn "*ashrsi3_cmp_zext"
11538   [(set (reg FLAGS_REG)
11539         (compare
11540           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11541                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11542           (const_int 0)))
11543    (set (match_operand:DI 0 "register_operand" "=r")
11544         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11545   "TARGET_64BIT
11546    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11547    && ix86_match_ccmode (insn, CCGOCmode)
11548    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11549   "sar{l}\t{%2, %k0|%k0, %2}"
11550   [(set_attr "type" "ishift")
11551    (set_attr "mode" "SI")])
11552
11553 (define_expand "ashrhi3"
11554   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11555         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11556                      (match_operand:QI 2 "nonmemory_operand" "")))]
11557   "TARGET_HIMODE_MATH"
11558   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11559
11560 (define_insn "*ashrhi3_1_one_bit"
11561   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11562         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11563                      (match_operand:QI 2 "const1_operand" "")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11566    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11567   "sar{w}\t%0"
11568   [(set_attr "type" "ishift")
11569    (set_attr "length_immediate" "0")
11570    (set_attr "mode" "HI")])
11571
11572 (define_insn "*ashrhi3_1"
11573   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11574         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11575                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11578   "@
11579    sar{w}\t{%2, %0|%0, %2}
11580    sar{w}\t{%b2, %0|%0, %b2}"
11581   [(set_attr "type" "ishift")
11582    (set_attr "mode" "HI")])
11583
11584 ;; This pattern can't accept a variable shift count, since shifts by
11585 ;; zero don't affect the flags.  We assume that shifts by constant
11586 ;; zero are optimized away.
11587 (define_insn "*ashrhi3_one_bit_cmp"
11588   [(set (reg FLAGS_REG)
11589         (compare
11590           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11591                        (match_operand:QI 2 "const1_operand" ""))
11592           (const_int 0)))
11593    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11594         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11595   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11596    && ix86_match_ccmode (insn, CCGOCmode)
11597    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11598   "sar{w}\t%0"
11599   [(set_attr "type" "ishift")
11600    (set_attr "length_immediate" "0")
11601    (set_attr "mode" "HI")])
11602
11603 (define_insn "*ashrhi3_one_bit_cconly"
11604   [(set (reg FLAGS_REG)
11605         (compare
11606           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11607                        (match_operand:QI 2 "const1_operand" ""))
11608           (const_int 0)))
11609    (clobber (match_scratch:HI 0 "=r"))]
11610   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11611    && ix86_match_ccmode (insn, CCGOCmode)
11612    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11613   "sar{w}\t%0"
11614   [(set_attr "type" "ishift")
11615    (set_attr "length_immediate" "0")
11616    (set_attr "mode" "HI")])
11617
11618 ;; This pattern can't accept a variable shift count, since shifts by
11619 ;; zero don't affect the flags.  We assume that shifts by constant
11620 ;; zero are optimized away.
11621 (define_insn "*ashrhi3_cmp"
11622   [(set (reg FLAGS_REG)
11623         (compare
11624           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11625                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11626           (const_int 0)))
11627    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11628         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11629   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11630    && ix86_match_ccmode (insn, CCGOCmode)
11631    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11632   "sar{w}\t{%2, %0|%0, %2}"
11633   [(set_attr "type" "ishift")
11634    (set_attr "mode" "HI")])
11635
11636 (define_insn "*ashrhi3_cconly"
11637   [(set (reg FLAGS_REG)
11638         (compare
11639           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11640                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11641           (const_int 0)))
11642    (clobber (match_scratch:HI 0 "=r"))]
11643   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11644    && ix86_match_ccmode (insn, CCGOCmode)
11645    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11646   "sar{w}\t{%2, %0|%0, %2}"
11647   [(set_attr "type" "ishift")
11648    (set_attr "mode" "HI")])
11649
11650 (define_expand "ashrqi3"
11651   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11652         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11653                      (match_operand:QI 2 "nonmemory_operand" "")))]
11654   "TARGET_QIMODE_MATH"
11655   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11656
11657 (define_insn "*ashrqi3_1_one_bit"
11658   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11659         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11660                      (match_operand:QI 2 "const1_operand" "")))
11661    (clobber (reg:CC FLAGS_REG))]
11662   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11663    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11664   "sar{b}\t%0"
11665   [(set_attr "type" "ishift")
11666    (set_attr "length_immediate" "0")
11667    (set_attr "mode" "QI")])
11668
11669 (define_insn "*ashrqi3_1_one_bit_slp"
11670   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11671         (ashiftrt:QI (match_dup 0)
11672                      (match_operand:QI 1 "const1_operand" "")))
11673    (clobber (reg:CC FLAGS_REG))]
11674   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11675    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11676    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11677   "sar{b}\t%0"
11678   [(set_attr "type" "ishift1")
11679    (set_attr "length_immediate" "0")
11680    (set_attr "mode" "QI")])
11681
11682 (define_insn "*ashrqi3_1"
11683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11684         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11685                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11688   "@
11689    sar{b}\t{%2, %0|%0, %2}
11690    sar{b}\t{%b2, %0|%0, %b2}"
11691   [(set_attr "type" "ishift")
11692    (set_attr "mode" "QI")])
11693
11694 (define_insn "*ashrqi3_1_slp"
11695   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11696         (ashiftrt:QI (match_dup 0)
11697                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11698    (clobber (reg:CC FLAGS_REG))]
11699   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11700    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11701   "@
11702    sar{b}\t{%1, %0|%0, %1}
11703    sar{b}\t{%b1, %0|%0, %b1}"
11704   [(set_attr "type" "ishift1")
11705    (set_attr "mode" "QI")])
11706
11707 ;; This pattern can't accept a variable shift count, since shifts by
11708 ;; zero don't affect the flags.  We assume that shifts by constant
11709 ;; zero are optimized away.
11710 (define_insn "*ashrqi3_one_bit_cmp"
11711   [(set (reg FLAGS_REG)
11712         (compare
11713           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11714                        (match_operand:QI 2 "const1_operand" "I"))
11715           (const_int 0)))
11716    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11717         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11718   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11719    && ix86_match_ccmode (insn, CCGOCmode)
11720    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11721   "sar{b}\t%0"
11722   [(set_attr "type" "ishift")
11723    (set_attr "length_immediate" "0")
11724    (set_attr "mode" "QI")])
11725
11726 (define_insn "*ashrqi3_one_bit_cconly"
11727   [(set (reg FLAGS_REG)
11728         (compare
11729           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11730                        (match_operand:QI 2 "const1_operand" ""))
11731           (const_int 0)))
11732    (clobber (match_scratch:QI 0 "=q"))]
11733   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11734    && ix86_match_ccmode (insn, CCGOCmode)
11735    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11736   "sar{b}\t%0"
11737   [(set_attr "type" "ishift")
11738    (set_attr "length_immediate" "0")
11739    (set_attr "mode" "QI")])
11740
11741 ;; This pattern can't accept a variable shift count, since shifts by
11742 ;; zero don't affect the flags.  We assume that shifts by constant
11743 ;; zero are optimized away.
11744 (define_insn "*ashrqi3_cmp"
11745   [(set (reg FLAGS_REG)
11746         (compare
11747           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11748                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11749           (const_int 0)))
11750    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11751         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11752   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11753    && ix86_match_ccmode (insn, CCGOCmode)
11754    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11755   "sar{b}\t{%2, %0|%0, %2}"
11756   [(set_attr "type" "ishift")
11757    (set_attr "mode" "QI")])
11758
11759 (define_insn "*ashrqi3_cconly"
11760   [(set (reg FLAGS_REG)
11761         (compare
11762           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11763                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11764           (const_int 0)))
11765    (clobber (match_scratch:QI 0 "=q"))]
11766   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11767    && ix86_match_ccmode (insn, CCGOCmode)
11768    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11769   "sar{b}\t{%2, %0|%0, %2}"
11770   [(set_attr "type" "ishift")
11771    (set_attr "mode" "QI")])
11772
11773 \f
11774 ;; Logical shift instructions
11775
11776 ;; See comment above `ashldi3' about how this works.
11777
11778 (define_expand "lshrti3"
11779   [(set (match_operand:TI 0 "register_operand" "")
11780         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11781                      (match_operand:QI 2 "nonmemory_operand" "")))]
11782   "TARGET_64BIT"
11783   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11784
11785 ;; This pattern must be defined before *lshrti3_1 to prevent
11786 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
11787
11788 (define_insn "*avx_lshrti3"
11789   [(set (match_operand:TI 0 "register_operand" "=x")
11790         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
11791                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11792   "TARGET_AVX"
11793 {
11794   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11795   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
11796 }
11797   [(set_attr "type" "sseishft")
11798    (set_attr "prefix" "vex")
11799    (set_attr "length_immediate" "1")
11800    (set_attr "mode" "TI")])
11801
11802 (define_insn "sse2_lshrti3"
11803   [(set (match_operand:TI 0 "register_operand" "=x")
11804         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11805                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11806   "TARGET_SSE2"
11807 {
11808   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11809   return "psrldq\t{%2, %0|%0, %2}";
11810 }
11811   [(set_attr "type" "sseishft")
11812    (set_attr "prefix_data16" "1")
11813    (set_attr "length_immediate" "1")
11814    (set_attr "mode" "TI")])
11815
11816 (define_insn "*lshrti3_1"
11817   [(set (match_operand:TI 0 "register_operand" "=r")
11818         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11819                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "TARGET_64BIT"
11822   "#"
11823   [(set_attr "type" "multi")])
11824
11825 (define_peephole2
11826   [(match_scratch:DI 3 "r")
11827    (parallel [(set (match_operand:TI 0 "register_operand" "")
11828                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11829                                 (match_operand:QI 2 "nonmemory_operand" "")))
11830               (clobber (reg:CC FLAGS_REG))])
11831    (match_dup 3)]
11832   "TARGET_64BIT"
11833   [(const_int 0)]
11834   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11835
11836 (define_split
11837   [(set (match_operand:TI 0 "register_operand" "")
11838         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11839                      (match_operand:QI 2 "nonmemory_operand" "")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11842                     ? epilogue_completed : reload_completed)"
11843   [(const_int 0)]
11844   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11845
11846 (define_expand "lshrdi3"
11847   [(set (match_operand:DI 0 "shiftdi_operand" "")
11848         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11849                      (match_operand:QI 2 "nonmemory_operand" "")))]
11850   ""
11851   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11852
11853 (define_insn "*lshrdi3_1_one_bit_rex64"
11854   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11855         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11856                      (match_operand:QI 2 "const1_operand" "")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "TARGET_64BIT
11859    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11860    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11861   "shr{q}\t%0"
11862   [(set_attr "type" "ishift")
11863    (set_attr "length_immediate" "0")
11864    (set_attr "mode" "DI")])
11865
11866 (define_insn "*lshrdi3_1_rex64"
11867   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11868         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11869                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11870    (clobber (reg:CC FLAGS_REG))]
11871   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11872   "@
11873    shr{q}\t{%2, %0|%0, %2}
11874    shr{q}\t{%b2, %0|%0, %b2}"
11875   [(set_attr "type" "ishift")
11876    (set_attr "mode" "DI")])
11877
11878 ;; This pattern can't accept a variable shift count, since shifts by
11879 ;; zero don't affect the flags.  We assume that shifts by constant
11880 ;; zero are optimized away.
11881 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11882   [(set (reg FLAGS_REG)
11883         (compare
11884           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11885                        (match_operand:QI 2 "const1_operand" ""))
11886           (const_int 0)))
11887    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11888         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11889   "TARGET_64BIT
11890    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11891    && ix86_match_ccmode (insn, CCGOCmode)
11892    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11893   "shr{q}\t%0"
11894   [(set_attr "type" "ishift")
11895    (set_attr "length_immediate" "0")
11896    (set_attr "mode" "DI")])
11897
11898 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11899   [(set (reg FLAGS_REG)
11900         (compare
11901           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11902                        (match_operand:QI 2 "const1_operand" ""))
11903           (const_int 0)))
11904    (clobber (match_scratch:DI 0 "=r"))]
11905   "TARGET_64BIT
11906    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11907    && ix86_match_ccmode (insn, CCGOCmode)
11908    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11909   "shr{q}\t%0"
11910   [(set_attr "type" "ishift")
11911    (set_attr "length_immediate" "0")
11912    (set_attr "mode" "DI")])
11913
11914 ;; This pattern can't accept a variable shift count, since shifts by
11915 ;; zero don't affect the flags.  We assume that shifts by constant
11916 ;; zero are optimized away.
11917 (define_insn "*lshrdi3_cmp_rex64"
11918   [(set (reg FLAGS_REG)
11919         (compare
11920           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11921                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11922           (const_int 0)))
11923    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11924         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11925   "TARGET_64BIT
11926    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11927    && ix86_match_ccmode (insn, CCGOCmode)
11928    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11929   "shr{q}\t{%2, %0|%0, %2}"
11930   [(set_attr "type" "ishift")
11931    (set_attr "mode" "DI")])
11932
11933 (define_insn "*lshrdi3_cconly_rex64"
11934   [(set (reg FLAGS_REG)
11935         (compare
11936           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11937                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11938           (const_int 0)))
11939    (clobber (match_scratch:DI 0 "=r"))]
11940   "TARGET_64BIT
11941    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11942    && ix86_match_ccmode (insn, CCGOCmode)
11943    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11944   "shr{q}\t{%2, %0|%0, %2}"
11945   [(set_attr "type" "ishift")
11946    (set_attr "mode" "DI")])
11947
11948 (define_insn "*lshrdi3_1"
11949   [(set (match_operand:DI 0 "register_operand" "=r")
11950         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11951                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11952    (clobber (reg:CC FLAGS_REG))]
11953   "!TARGET_64BIT"
11954   "#"
11955   [(set_attr "type" "multi")])
11956
11957 ;; By default we don't ask for a scratch register, because when DImode
11958 ;; values are manipulated, registers are already at a premium.  But if
11959 ;; we have one handy, we won't turn it away.
11960 (define_peephole2
11961   [(match_scratch:SI 3 "r")
11962    (parallel [(set (match_operand:DI 0 "register_operand" "")
11963                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11964                                 (match_operand:QI 2 "nonmemory_operand" "")))
11965               (clobber (reg:CC FLAGS_REG))])
11966    (match_dup 3)]
11967   "!TARGET_64BIT && TARGET_CMOVE"
11968   [(const_int 0)]
11969   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11970
11971 (define_split
11972   [(set (match_operand:DI 0 "register_operand" "")
11973         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11974                      (match_operand:QI 2 "nonmemory_operand" "")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11977                      ? epilogue_completed : reload_completed)"
11978   [(const_int 0)]
11979   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11980
11981 (define_expand "lshrsi3"
11982   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11983         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11984                      (match_operand:QI 2 "nonmemory_operand" "")))]
11985   ""
11986   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11987
11988 (define_insn "*lshrsi3_1_one_bit"
11989   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11991                      (match_operand:QI 2 "const1_operand" "")))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11994    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11995   "shr{l}\t%0"
11996   [(set_attr "type" "ishift")
11997    (set_attr "length_immediate" "0")
11998    (set_attr "mode" "SI")])
11999
12000 (define_insn "*lshrsi3_1_one_bit_zext"
12001   [(set (match_operand:DI 0 "register_operand" "=r")
12002         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12003                      (match_operand:QI 2 "const1_operand" "")))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "TARGET_64BIT
12006    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12007    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12008   "shr{l}\t%k0"
12009   [(set_attr "type" "ishift")
12010    (set_attr "length_immediate" "0")
12011    (set_attr "mode" "SI")])
12012
12013 (define_insn "*lshrsi3_1"
12014   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12015         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12016                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12017    (clobber (reg:CC FLAGS_REG))]
12018   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12019   "@
12020    shr{l}\t{%2, %0|%0, %2}
12021    shr{l}\t{%b2, %0|%0, %b2}"
12022   [(set_attr "type" "ishift")
12023    (set_attr "mode" "SI")])
12024
12025 (define_insn "*lshrsi3_1_zext"
12026   [(set (match_operand:DI 0 "register_operand" "=r,r")
12027         (zero_extend:DI
12028           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12029                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12030    (clobber (reg:CC FLAGS_REG))]
12031   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12032   "@
12033    shr{l}\t{%2, %k0|%k0, %2}
12034    shr{l}\t{%b2, %k0|%k0, %b2}"
12035   [(set_attr "type" "ishift")
12036    (set_attr "mode" "SI")])
12037
12038 ;; This pattern can't accept a variable shift count, since shifts by
12039 ;; zero don't affect the flags.  We assume that shifts by constant
12040 ;; zero are optimized away.
12041 (define_insn "*lshrsi3_one_bit_cmp"
12042   [(set (reg FLAGS_REG)
12043         (compare
12044           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12045                        (match_operand:QI 2 "const1_operand" ""))
12046           (const_int 0)))
12047    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12048         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12049   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12050    && ix86_match_ccmode (insn, CCGOCmode)
12051    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12052   "shr{l}\t%0"
12053   [(set_attr "type" "ishift")
12054    (set_attr "length_immediate" "0")
12055    (set_attr "mode" "SI")])
12056
12057 (define_insn "*lshrsi3_one_bit_cconly"
12058   [(set (reg FLAGS_REG)
12059         (compare
12060           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12061                        (match_operand:QI 2 "const1_operand" ""))
12062           (const_int 0)))
12063    (clobber (match_scratch:SI 0 "=r"))]
12064   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12065    && ix86_match_ccmode (insn, CCGOCmode)
12066    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12067   "shr{l}\t%0"
12068   [(set_attr "type" "ishift")
12069    (set_attr "length_immediate" "0")
12070    (set_attr "mode" "SI")])
12071
12072 (define_insn "*lshrsi3_cmp_one_bit_zext"
12073   [(set (reg FLAGS_REG)
12074         (compare
12075           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12076                        (match_operand:QI 2 "const1_operand" ""))
12077           (const_int 0)))
12078    (set (match_operand:DI 0 "register_operand" "=r")
12079         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12080   "TARGET_64BIT
12081    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12082    && ix86_match_ccmode (insn, CCGOCmode)
12083    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12084   "shr{l}\t%k0"
12085   [(set_attr "type" "ishift")
12086    (set_attr "length_immediate" "0")
12087    (set_attr "mode" "SI")])
12088
12089 ;; This pattern can't accept a variable shift count, since shifts by
12090 ;; zero don't affect the flags.  We assume that shifts by constant
12091 ;; zero are optimized away.
12092 (define_insn "*lshrsi3_cmp"
12093   [(set (reg FLAGS_REG)
12094         (compare
12095           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12096                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12097           (const_int 0)))
12098    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12099         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12100   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12101    && ix86_match_ccmode (insn, CCGOCmode)
12102    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12103   "shr{l}\t{%2, %0|%0, %2}"
12104   [(set_attr "type" "ishift")
12105    (set_attr "mode" "SI")])
12106
12107 (define_insn "*lshrsi3_cconly"
12108   [(set (reg FLAGS_REG)
12109       (compare
12110         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12111                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12112         (const_int 0)))
12113    (clobber (match_scratch:SI 0 "=r"))]
12114   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12115    && ix86_match_ccmode (insn, CCGOCmode)
12116    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12117   "shr{l}\t{%2, %0|%0, %2}"
12118   [(set_attr "type" "ishift")
12119    (set_attr "mode" "SI")])
12120
12121 (define_insn "*lshrsi3_cmp_zext"
12122   [(set (reg FLAGS_REG)
12123         (compare
12124           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12125                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12126           (const_int 0)))
12127    (set (match_operand:DI 0 "register_operand" "=r")
12128         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12129   "TARGET_64BIT
12130    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12131    && ix86_match_ccmode (insn, CCGOCmode)
12132    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12133   "shr{l}\t{%2, %k0|%k0, %2}"
12134   [(set_attr "type" "ishift")
12135    (set_attr "mode" "SI")])
12136
12137 (define_expand "lshrhi3"
12138   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12139         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12140                      (match_operand:QI 2 "nonmemory_operand" "")))]
12141   "TARGET_HIMODE_MATH"
12142   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12143
12144 (define_insn "*lshrhi3_1_one_bit"
12145   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12146         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12147                      (match_operand:QI 2 "const1_operand" "")))
12148    (clobber (reg:CC FLAGS_REG))]
12149   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12150    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12151   "shr{w}\t%0"
12152   [(set_attr "type" "ishift")
12153    (set_attr "length_immediate" "0")
12154    (set_attr "mode" "HI")])
12155
12156 (define_insn "*lshrhi3_1"
12157   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12158         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12159                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12160    (clobber (reg:CC FLAGS_REG))]
12161   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12162   "@
12163    shr{w}\t{%2, %0|%0, %2}
12164    shr{w}\t{%b2, %0|%0, %b2}"
12165   [(set_attr "type" "ishift")
12166    (set_attr "mode" "HI")])
12167
12168 ;; This pattern can't accept a variable shift count, since shifts by
12169 ;; zero don't affect the flags.  We assume that shifts by constant
12170 ;; zero are optimized away.
12171 (define_insn "*lshrhi3_one_bit_cmp"
12172   [(set (reg FLAGS_REG)
12173         (compare
12174           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12175                        (match_operand:QI 2 "const1_operand" ""))
12176           (const_int 0)))
12177    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12178         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12179   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12180    && ix86_match_ccmode (insn, CCGOCmode)
12181    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12182   "shr{w}\t%0"
12183   [(set_attr "type" "ishift")
12184    (set_attr "length_immediate" "0")
12185    (set_attr "mode" "HI")])
12186
12187 (define_insn "*lshrhi3_one_bit_cconly"
12188   [(set (reg FLAGS_REG)
12189         (compare
12190           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12191                        (match_operand:QI 2 "const1_operand" ""))
12192           (const_int 0)))
12193    (clobber (match_scratch:HI 0 "=r"))]
12194   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12195    && ix86_match_ccmode (insn, CCGOCmode)
12196    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12197   "shr{w}\t%0"
12198   [(set_attr "type" "ishift")
12199    (set_attr "length_immediate" "0")
12200    (set_attr "mode" "HI")])
12201
12202 ;; This pattern can't accept a variable shift count, since shifts by
12203 ;; zero don't affect the flags.  We assume that shifts by constant
12204 ;; zero are optimized away.
12205 (define_insn "*lshrhi3_cmp"
12206   [(set (reg FLAGS_REG)
12207         (compare
12208           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12209                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12210           (const_int 0)))
12211    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12212         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12213   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12214    && ix86_match_ccmode (insn, CCGOCmode)
12215    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12216   "shr{w}\t{%2, %0|%0, %2}"
12217   [(set_attr "type" "ishift")
12218    (set_attr "mode" "HI")])
12219
12220 (define_insn "*lshrhi3_cconly"
12221   [(set (reg FLAGS_REG)
12222         (compare
12223           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12224                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12225           (const_int 0)))
12226    (clobber (match_scratch:HI 0 "=r"))]
12227   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12228    && ix86_match_ccmode (insn, CCGOCmode)
12229    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12230   "shr{w}\t{%2, %0|%0, %2}"
12231   [(set_attr "type" "ishift")
12232    (set_attr "mode" "HI")])
12233
12234 (define_expand "lshrqi3"
12235   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12236         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12237                      (match_operand:QI 2 "nonmemory_operand" "")))]
12238   "TARGET_QIMODE_MATH"
12239   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12240
12241 (define_insn "*lshrqi3_1_one_bit"
12242   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12243         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12244                      (match_operand:QI 2 "const1_operand" "")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12247    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12248   "shr{b}\t%0"
12249   [(set_attr "type" "ishift")
12250    (set_attr "length_immediate" "0")
12251    (set_attr "mode" "QI")])
12252
12253 (define_insn "*lshrqi3_1_one_bit_slp"
12254   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12255         (lshiftrt:QI (match_dup 0)
12256                      (match_operand:QI 1 "const1_operand" "")))
12257    (clobber (reg:CC FLAGS_REG))]
12258   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12259    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12260   "shr{b}\t%0"
12261   [(set_attr "type" "ishift1")
12262    (set_attr "length_immediate" "0")
12263    (set_attr "mode" "QI")])
12264
12265 (define_insn "*lshrqi3_1"
12266   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12267         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12268                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12269    (clobber (reg:CC FLAGS_REG))]
12270   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12271   "@
12272    shr{b}\t{%2, %0|%0, %2}
12273    shr{b}\t{%b2, %0|%0, %b2}"
12274   [(set_attr "type" "ishift")
12275    (set_attr "mode" "QI")])
12276
12277 (define_insn "*lshrqi3_1_slp"
12278   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12279         (lshiftrt:QI (match_dup 0)
12280                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12281    (clobber (reg:CC FLAGS_REG))]
12282   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12283    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12284   "@
12285    shr{b}\t{%1, %0|%0, %1}
12286    shr{b}\t{%b1, %0|%0, %b1}"
12287   [(set_attr "type" "ishift1")
12288    (set_attr "mode" "QI")])
12289
12290 ;; This pattern can't accept a variable shift count, since shifts by
12291 ;; zero don't affect the flags.  We assume that shifts by constant
12292 ;; zero are optimized away.
12293 (define_insn "*lshrqi2_one_bit_cmp"
12294   [(set (reg FLAGS_REG)
12295         (compare
12296           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12297                        (match_operand:QI 2 "const1_operand" ""))
12298           (const_int 0)))
12299    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12300         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12301   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12302    && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12304   "shr{b}\t%0"
12305   [(set_attr "type" "ishift")
12306    (set_attr "length_immediate" "0")
12307    (set_attr "mode" "QI")])
12308
12309 (define_insn "*lshrqi2_one_bit_cconly"
12310   [(set (reg FLAGS_REG)
12311         (compare
12312           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12313                        (match_operand:QI 2 "const1_operand" ""))
12314           (const_int 0)))
12315    (clobber (match_scratch:QI 0 "=q"))]
12316   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12317    && ix86_match_ccmode (insn, CCGOCmode)
12318    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12319   "shr{b}\t%0"
12320   [(set_attr "type" "ishift")
12321    (set_attr "length_immediate" "0")
12322    (set_attr "mode" "QI")])
12323
12324 ;; This pattern can't accept a variable shift count, since shifts by
12325 ;; zero don't affect the flags.  We assume that shifts by constant
12326 ;; zero are optimized away.
12327 (define_insn "*lshrqi2_cmp"
12328   [(set (reg FLAGS_REG)
12329         (compare
12330           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12331                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12332           (const_int 0)))
12333    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12334         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12335   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12336    && ix86_match_ccmode (insn, CCGOCmode)
12337    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12338   "shr{b}\t{%2, %0|%0, %2}"
12339   [(set_attr "type" "ishift")
12340    (set_attr "mode" "QI")])
12341
12342 (define_insn "*lshrqi2_cconly"
12343   [(set (reg FLAGS_REG)
12344         (compare
12345           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12346                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347           (const_int 0)))
12348    (clobber (match_scratch:QI 0 "=q"))]
12349   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12350    && ix86_match_ccmode (insn, CCGOCmode)
12351    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12352   "shr{b}\t{%2, %0|%0, %2}"
12353   [(set_attr "type" "ishift")
12354    (set_attr "mode" "QI")])
12355 \f
12356 ;; Rotate instructions
12357
12358 (define_expand "rotldi3"
12359   [(set (match_operand:DI 0 "shiftdi_operand" "")
12360         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12361                    (match_operand:QI 2 "nonmemory_operand" "")))]
12362  ""
12363 {
12364   if (TARGET_64BIT)
12365     {
12366       ix86_expand_binary_operator (ROTATE, DImode, operands);
12367       DONE;
12368     }
12369   if (!const_1_to_31_operand (operands[2], VOIDmode))
12370     FAIL;
12371   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12372   DONE;
12373 })
12374
12375 ;; Implement rotation using two double-precision shift instructions
12376 ;; and a scratch register.
12377 (define_insn_and_split "ix86_rotldi3"
12378  [(set (match_operand:DI 0 "register_operand" "=r")
12379        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12380                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12381   (clobber (reg:CC FLAGS_REG))
12382   (clobber (match_scratch:SI 3 "=&r"))]
12383  "!TARGET_64BIT"
12384  ""
12385  "&& reload_completed"
12386  [(set (match_dup 3) (match_dup 4))
12387   (parallel
12388    [(set (match_dup 4)
12389          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12390                  (lshiftrt:SI (match_dup 5)
12391                               (minus:QI (const_int 32) (match_dup 2)))))
12392     (clobber (reg:CC FLAGS_REG))])
12393   (parallel
12394    [(set (match_dup 5)
12395          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12396                  (lshiftrt:SI (match_dup 3)
12397                               (minus:QI (const_int 32) (match_dup 2)))))
12398     (clobber (reg:CC FLAGS_REG))])]
12399  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12400
12401 (define_insn "*rotlsi3_1_one_bit_rex64"
12402   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12403         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12404                    (match_operand:QI 2 "const1_operand" "")))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "TARGET_64BIT
12407    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12409   "rol{q}\t%0"
12410   [(set_attr "type" "rotate")
12411    (set_attr "length_immediate" "0")
12412    (set_attr "mode" "DI")])
12413
12414 (define_insn "*rotldi3_1_rex64"
12415   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12416         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12417                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12418    (clobber (reg:CC FLAGS_REG))]
12419   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12420   "@
12421    rol{q}\t{%2, %0|%0, %2}
12422    rol{q}\t{%b2, %0|%0, %b2}"
12423   [(set_attr "type" "rotate")
12424    (set_attr "mode" "DI")])
12425
12426 (define_expand "rotlsi3"
12427   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12428         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12429                    (match_operand:QI 2 "nonmemory_operand" "")))]
12430   ""
12431   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12432
12433 (define_insn "*rotlsi3_1_one_bit"
12434   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12435         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12436                    (match_operand:QI 2 "const1_operand" "")))
12437    (clobber (reg:CC FLAGS_REG))]
12438   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12439    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12440   "rol{l}\t%0"
12441   [(set_attr "type" "rotate")
12442    (set_attr "length_immediate" "0")
12443    (set_attr "mode" "SI")])
12444
12445 (define_insn "*rotlsi3_1_one_bit_zext"
12446   [(set (match_operand:DI 0 "register_operand" "=r")
12447         (zero_extend:DI
12448           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12449                      (match_operand:QI 2 "const1_operand" ""))))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "TARGET_64BIT
12452    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12453    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12454   "rol{l}\t%k0"
12455   [(set_attr "type" "rotate")
12456    (set_attr "length_immediate" "0")
12457    (set_attr "mode" "SI")])
12458
12459 (define_insn "*rotlsi3_1"
12460   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12461         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12462                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12465   "@
12466    rol{l}\t{%2, %0|%0, %2}
12467    rol{l}\t{%b2, %0|%0, %b2}"
12468   [(set_attr "type" "rotate")
12469    (set_attr "mode" "SI")])
12470
12471 (define_insn "*rotlsi3_1_zext"
12472   [(set (match_operand:DI 0 "register_operand" "=r,r")
12473         (zero_extend:DI
12474           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12475                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12476    (clobber (reg:CC FLAGS_REG))]
12477   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12478   "@
12479    rol{l}\t{%2, %k0|%k0, %2}
12480    rol{l}\t{%b2, %k0|%k0, %b2}"
12481   [(set_attr "type" "rotate")
12482    (set_attr "mode" "SI")])
12483
12484 (define_expand "rotlhi3"
12485   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12486         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12487                    (match_operand:QI 2 "nonmemory_operand" "")))]
12488   "TARGET_HIMODE_MATH"
12489   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12490
12491 (define_insn "*rotlhi3_1_one_bit"
12492   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12493         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12494                    (match_operand:QI 2 "const1_operand" "")))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12498   "rol{w}\t%0"
12499   [(set_attr "type" "rotate")
12500    (set_attr "length_immediate" "0")
12501    (set_attr "mode" "HI")])
12502
12503 (define_insn "*rotlhi3_1"
12504   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12505         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12506                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12507    (clobber (reg:CC FLAGS_REG))]
12508   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12509   "@
12510    rol{w}\t{%2, %0|%0, %2}
12511    rol{w}\t{%b2, %0|%0, %b2}"
12512   [(set_attr "type" "rotate")
12513    (set_attr "mode" "HI")])
12514
12515 (define_split
12516  [(set (match_operand:HI 0 "register_operand" "")
12517        (rotate:HI (match_dup 0) (const_int 8)))
12518   (clobber (reg:CC FLAGS_REG))]
12519  "reload_completed"
12520  [(parallel [(set (strict_low_part (match_dup 0))
12521                   (bswap:HI (match_dup 0)))
12522              (clobber (reg:CC FLAGS_REG))])]
12523  "")
12524
12525 (define_expand "rotlqi3"
12526   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12527         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12528                    (match_operand:QI 2 "nonmemory_operand" "")))]
12529   "TARGET_QIMODE_MATH"
12530   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12531
12532 (define_insn "*rotlqi3_1_one_bit_slp"
12533   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12534         (rotate:QI (match_dup 0)
12535                    (match_operand:QI 1 "const1_operand" "")))
12536    (clobber (reg:CC FLAGS_REG))]
12537   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12538    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12539   "rol{b}\t%0"
12540   [(set_attr "type" "rotate1")
12541    (set_attr "length_immediate" "0")
12542    (set_attr "mode" "QI")])
12543
12544 (define_insn "*rotlqi3_1_one_bit"
12545   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12546         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12547                    (match_operand:QI 2 "const1_operand" "")))
12548    (clobber (reg:CC FLAGS_REG))]
12549   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12550    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12551   "rol{b}\t%0"
12552   [(set_attr "type" "rotate")
12553    (set_attr "length_immediate" "0")
12554    (set_attr "mode" "QI")])
12555
12556 (define_insn "*rotlqi3_1_slp"
12557   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12558         (rotate:QI (match_dup 0)
12559                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12560    (clobber (reg:CC FLAGS_REG))]
12561   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12562    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12563   "@
12564    rol{b}\t{%1, %0|%0, %1}
12565    rol{b}\t{%b1, %0|%0, %b1}"
12566   [(set_attr "type" "rotate1")
12567    (set_attr "mode" "QI")])
12568
12569 (define_insn "*rotlqi3_1"
12570   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12571         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12572                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12573    (clobber (reg:CC FLAGS_REG))]
12574   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12575   "@
12576    rol{b}\t{%2, %0|%0, %2}
12577    rol{b}\t{%b2, %0|%0, %b2}"
12578   [(set_attr "type" "rotate")
12579    (set_attr "mode" "QI")])
12580
12581 (define_expand "rotrdi3"
12582   [(set (match_operand:DI 0 "shiftdi_operand" "")
12583         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12584                    (match_operand:QI 2 "nonmemory_operand" "")))]
12585  ""
12586 {
12587   if (TARGET_64BIT)
12588     {
12589       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12590       DONE;
12591     }
12592   if (!const_1_to_31_operand (operands[2], VOIDmode))
12593     FAIL;
12594   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12595   DONE;
12596 })
12597
12598 ;; Implement rotation using two double-precision shift instructions
12599 ;; and a scratch register.
12600 (define_insn_and_split "ix86_rotrdi3"
12601  [(set (match_operand:DI 0 "register_operand" "=r")
12602        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12603                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12604   (clobber (reg:CC FLAGS_REG))
12605   (clobber (match_scratch:SI 3 "=&r"))]
12606  "!TARGET_64BIT"
12607  ""
12608  "&& reload_completed"
12609  [(set (match_dup 3) (match_dup 4))
12610   (parallel
12611    [(set (match_dup 4)
12612          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12613                  (ashift:SI (match_dup 5)
12614                             (minus:QI (const_int 32) (match_dup 2)))))
12615     (clobber (reg:CC FLAGS_REG))])
12616   (parallel
12617    [(set (match_dup 5)
12618          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12619                  (ashift:SI (match_dup 3)
12620                             (minus:QI (const_int 32) (match_dup 2)))))
12621     (clobber (reg:CC FLAGS_REG))])]
12622  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12623
12624 (define_insn "*rotrdi3_1_one_bit_rex64"
12625   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12626         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12627                      (match_operand:QI 2 "const1_operand" "")))
12628    (clobber (reg:CC FLAGS_REG))]
12629   "TARGET_64BIT
12630    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12631    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12632   "ror{q}\t%0"
12633   [(set_attr "type" "rotate")
12634    (set_attr "length_immediate" "0")
12635    (set_attr "mode" "DI")])
12636
12637 (define_insn "*rotrdi3_1_rex64"
12638   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12639         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12640                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12641    (clobber (reg:CC FLAGS_REG))]
12642   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12643   "@
12644    ror{q}\t{%2, %0|%0, %2}
12645    ror{q}\t{%b2, %0|%0, %b2}"
12646   [(set_attr "type" "rotate")
12647    (set_attr "mode" "DI")])
12648
12649 (define_expand "rotrsi3"
12650   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12651         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12652                      (match_operand:QI 2 "nonmemory_operand" "")))]
12653   ""
12654   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12655
12656 (define_insn "*rotrsi3_1_one_bit"
12657   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12658         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12659                      (match_operand:QI 2 "const1_operand" "")))
12660    (clobber (reg:CC FLAGS_REG))]
12661   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12662    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12663   "ror{l}\t%0"
12664   [(set_attr "type" "rotate")
12665    (set_attr "length_immediate" "0")
12666    (set_attr "mode" "SI")])
12667
12668 (define_insn "*rotrsi3_1_one_bit_zext"
12669   [(set (match_operand:DI 0 "register_operand" "=r")
12670         (zero_extend:DI
12671           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12672                        (match_operand:QI 2 "const1_operand" ""))))
12673    (clobber (reg:CC FLAGS_REG))]
12674   "TARGET_64BIT
12675    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12676    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12677   "ror{l}\t%k0"
12678   [(set_attr "type" "rotate")
12679    (set_attr "length_immediate" "0")
12680    (set_attr "mode" "SI")])
12681
12682 (define_insn "*rotrsi3_1"
12683   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12684         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12685                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12686    (clobber (reg:CC FLAGS_REG))]
12687   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12688   "@
12689    ror{l}\t{%2, %0|%0, %2}
12690    ror{l}\t{%b2, %0|%0, %b2}"
12691   [(set_attr "type" "rotate")
12692    (set_attr "mode" "SI")])
12693
12694 (define_insn "*rotrsi3_1_zext"
12695   [(set (match_operand:DI 0 "register_operand" "=r,r")
12696         (zero_extend:DI
12697           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12698                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12699    (clobber (reg:CC FLAGS_REG))]
12700   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12701   "@
12702    ror{l}\t{%2, %k0|%k0, %2}
12703    ror{l}\t{%b2, %k0|%k0, %b2}"
12704   [(set_attr "type" "rotate")
12705    (set_attr "mode" "SI")])
12706
12707 (define_expand "rotrhi3"
12708   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12709         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12710                      (match_operand:QI 2 "nonmemory_operand" "")))]
12711   "TARGET_HIMODE_MATH"
12712   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12713
12714 (define_insn "*rotrhi3_one_bit"
12715   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12716         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12717                      (match_operand:QI 2 "const1_operand" "")))
12718    (clobber (reg:CC FLAGS_REG))]
12719   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12720    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12721   "ror{w}\t%0"
12722   [(set_attr "type" "rotate")
12723    (set_attr "length_immediate" "0")
12724    (set_attr "mode" "HI")])
12725
12726 (define_insn "*rotrhi3_1"
12727   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12728         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12729                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12730    (clobber (reg:CC FLAGS_REG))]
12731   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12732   "@
12733    ror{w}\t{%2, %0|%0, %2}
12734    ror{w}\t{%b2, %0|%0, %b2}"
12735   [(set_attr "type" "rotate")
12736    (set_attr "mode" "HI")])
12737
12738 (define_split
12739  [(set (match_operand:HI 0 "register_operand" "")
12740        (rotatert:HI (match_dup 0) (const_int 8)))
12741   (clobber (reg:CC FLAGS_REG))]
12742  "reload_completed"
12743  [(parallel [(set (strict_low_part (match_dup 0))
12744                   (bswap:HI (match_dup 0)))
12745              (clobber (reg:CC FLAGS_REG))])]
12746  "")
12747
12748 (define_expand "rotrqi3"
12749   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12750         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12751                      (match_operand:QI 2 "nonmemory_operand" "")))]
12752   "TARGET_QIMODE_MATH"
12753   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12754
12755 (define_insn "*rotrqi3_1_one_bit"
12756   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12757         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12758                      (match_operand:QI 2 "const1_operand" "")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12761    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12762   "ror{b}\t%0"
12763   [(set_attr "type" "rotate")
12764    (set_attr "length_immediate" "0")
12765    (set_attr "mode" "QI")])
12766
12767 (define_insn "*rotrqi3_1_one_bit_slp"
12768   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12769         (rotatert:QI (match_dup 0)
12770                      (match_operand:QI 1 "const1_operand" "")))
12771    (clobber (reg:CC FLAGS_REG))]
12772   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12773    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12774   "ror{b}\t%0"
12775   [(set_attr "type" "rotate1")
12776    (set_attr "length_immediate" "0")
12777    (set_attr "mode" "QI")])
12778
12779 (define_insn "*rotrqi3_1"
12780   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12781         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12782                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12783    (clobber (reg:CC FLAGS_REG))]
12784   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12785   "@
12786    ror{b}\t{%2, %0|%0, %2}
12787    ror{b}\t{%b2, %0|%0, %b2}"
12788   [(set_attr "type" "rotate")
12789    (set_attr "mode" "QI")])
12790
12791 (define_insn "*rotrqi3_1_slp"
12792   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793         (rotatert:QI (match_dup 0)
12794                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12798   "@
12799    ror{b}\t{%1, %0|%0, %1}
12800    ror{b}\t{%b1, %0|%0, %b1}"
12801   [(set_attr "type" "rotate1")
12802    (set_attr "mode" "QI")])
12803 \f
12804 ;; Bit set / bit test instructions
12805
12806 (define_expand "extv"
12807   [(set (match_operand:SI 0 "register_operand" "")
12808         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12809                          (match_operand:SI 2 "const8_operand" "")
12810                          (match_operand:SI 3 "const8_operand" "")))]
12811   ""
12812 {
12813   /* Handle extractions from %ah et al.  */
12814   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12815     FAIL;
12816
12817   /* From mips.md: extract_bit_field doesn't verify that our source
12818      matches the predicate, so check it again here.  */
12819   if (! ext_register_operand (operands[1], VOIDmode))
12820     FAIL;
12821 })
12822
12823 (define_expand "extzv"
12824   [(set (match_operand:SI 0 "register_operand" "")
12825         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12826                          (match_operand:SI 2 "const8_operand" "")
12827                          (match_operand:SI 3 "const8_operand" "")))]
12828   ""
12829 {
12830   /* Handle extractions from %ah et al.  */
12831   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12832     FAIL;
12833
12834   /* From mips.md: extract_bit_field doesn't verify that our source
12835      matches the predicate, so check it again here.  */
12836   if (! ext_register_operand (operands[1], VOIDmode))
12837     FAIL;
12838 })
12839
12840 (define_expand "insv"
12841   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12842                       (match_operand 1 "const8_operand" "")
12843                       (match_operand 2 "const8_operand" ""))
12844         (match_operand 3 "register_operand" ""))]
12845   ""
12846 {
12847   /* Handle insertions to %ah et al.  */
12848   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12849     FAIL;
12850
12851   /* From mips.md: insert_bit_field doesn't verify that our source
12852      matches the predicate, so check it again here.  */
12853   if (! ext_register_operand (operands[0], VOIDmode))
12854     FAIL;
12855
12856   if (TARGET_64BIT)
12857     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12858   else
12859     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12860
12861   DONE;
12862 })
12863
12864 ;; %%% bts, btr, btc, bt.
12865 ;; In general these instructions are *slow* when applied to memory,
12866 ;; since they enforce atomic operation.  When applied to registers,
12867 ;; it depends on the cpu implementation.  They're never faster than
12868 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12869 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12870 ;; within the instruction itself, so operating on bits in the high
12871 ;; 32-bits of a register becomes easier.
12872 ;;
12873 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12874 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12875 ;; negdf respectively, so they can never be disabled entirely.
12876
12877 (define_insn "*btsq"
12878   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12879                          (const_int 1)
12880                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12881         (const_int 1))
12882    (clobber (reg:CC FLAGS_REG))]
12883   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12884   "bts{q}\t{%1, %0|%0, %1}"
12885   [(set_attr "type" "alu1")
12886    (set_attr "prefix_0f" "1")
12887    (set_attr "mode" "DI")])
12888
12889 (define_insn "*btrq"
12890   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12891                          (const_int 1)
12892                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12893         (const_int 0))
12894    (clobber (reg:CC FLAGS_REG))]
12895   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12896   "btr{q}\t{%1, %0|%0, %1}"
12897   [(set_attr "type" "alu1")
12898    (set_attr "prefix_0f" "1")
12899    (set_attr "mode" "DI")])
12900
12901 (define_insn "*btcq"
12902   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12903                          (const_int 1)
12904                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12905         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12906    (clobber (reg:CC FLAGS_REG))]
12907   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12908   "btc{q}\t{%1, %0|%0, %1}"
12909   [(set_attr "type" "alu1")
12910    (set_attr "prefix_0f" "1")
12911    (set_attr "mode" "DI")])
12912
12913 ;; Allow Nocona to avoid these instructions if a register is available.
12914
12915 (define_peephole2
12916   [(match_scratch:DI 2 "r")
12917    (parallel [(set (zero_extract:DI
12918                      (match_operand:DI 0 "register_operand" "")
12919                      (const_int 1)
12920                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12921                    (const_int 1))
12922               (clobber (reg:CC FLAGS_REG))])]
12923   "TARGET_64BIT && !TARGET_USE_BT"
12924   [(const_int 0)]
12925 {
12926   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12927   rtx op1;
12928
12929   if (HOST_BITS_PER_WIDE_INT >= 64)
12930     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12931   else if (i < HOST_BITS_PER_WIDE_INT)
12932     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12933   else
12934     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12935
12936   op1 = immed_double_const (lo, hi, DImode);
12937   if (i >= 31)
12938     {
12939       emit_move_insn (operands[2], op1);
12940       op1 = operands[2];
12941     }
12942
12943   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12944   DONE;
12945 })
12946
12947 (define_peephole2
12948   [(match_scratch:DI 2 "r")
12949    (parallel [(set (zero_extract:DI
12950                      (match_operand:DI 0 "register_operand" "")
12951                      (const_int 1)
12952                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12953                    (const_int 0))
12954               (clobber (reg:CC FLAGS_REG))])]
12955   "TARGET_64BIT && !TARGET_USE_BT"
12956   [(const_int 0)]
12957 {
12958   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12959   rtx op1;
12960
12961   if (HOST_BITS_PER_WIDE_INT >= 64)
12962     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12963   else if (i < HOST_BITS_PER_WIDE_INT)
12964     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12965   else
12966     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12967
12968   op1 = immed_double_const (~lo, ~hi, DImode);
12969   if (i >= 32)
12970     {
12971       emit_move_insn (operands[2], op1);
12972       op1 = operands[2];
12973     }
12974
12975   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12976   DONE;
12977 })
12978
12979 (define_peephole2
12980   [(match_scratch:DI 2 "r")
12981    (parallel [(set (zero_extract:DI
12982                      (match_operand:DI 0 "register_operand" "")
12983                      (const_int 1)
12984                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12985               (not:DI (zero_extract:DI
12986                         (match_dup 0) (const_int 1) (match_dup 1))))
12987               (clobber (reg:CC FLAGS_REG))])]
12988   "TARGET_64BIT && !TARGET_USE_BT"
12989   [(const_int 0)]
12990 {
12991   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12992   rtx op1;
12993
12994   if (HOST_BITS_PER_WIDE_INT >= 64)
12995     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12996   else if (i < HOST_BITS_PER_WIDE_INT)
12997     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12998   else
12999     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13000
13001   op1 = immed_double_const (lo, hi, DImode);
13002   if (i >= 31)
13003     {
13004       emit_move_insn (operands[2], op1);
13005       op1 = operands[2];
13006     }
13007
13008   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13009   DONE;
13010 })
13011
13012 (define_insn "*btdi_rex64"
13013   [(set (reg:CCC FLAGS_REG)
13014         (compare:CCC
13015           (zero_extract:DI
13016             (match_operand:DI 0 "register_operand" "r")
13017             (const_int 1)
13018             (match_operand:DI 1 "nonmemory_operand" "rN"))
13019           (const_int 0)))]
13020   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13021   "bt{q}\t{%1, %0|%0, %1}"
13022   [(set_attr "type" "alu1")
13023    (set_attr "prefix_0f" "1")
13024    (set_attr "mode" "DI")])
13025
13026 (define_insn "*btsi"
13027   [(set (reg:CCC FLAGS_REG)
13028         (compare:CCC
13029           (zero_extract:SI
13030             (match_operand:SI 0 "register_operand" "r")
13031             (const_int 1)
13032             (match_operand:SI 1 "nonmemory_operand" "rN"))
13033           (const_int 0)))]
13034   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13035   "bt{l}\t{%1, %0|%0, %1}"
13036   [(set_attr "type" "alu1")
13037    (set_attr "prefix_0f" "1")
13038    (set_attr "mode" "SI")])
13039 \f
13040 ;; Store-flag instructions.
13041
13042 ;; For all sCOND expanders, also expand the compare or test insn that
13043 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13044
13045 (define_insn_and_split "*setcc_di_1"
13046   [(set (match_operand:DI 0 "register_operand" "=q")
13047         (match_operator:DI 1 "ix86_comparison_operator"
13048           [(reg FLAGS_REG) (const_int 0)]))]
13049   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13050   "#"
13051   "&& reload_completed"
13052   [(set (match_dup 2) (match_dup 1))
13053    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13054 {
13055   PUT_MODE (operands[1], QImode);
13056   operands[2] = gen_lowpart (QImode, operands[0]);
13057 })
13058
13059 (define_insn_and_split "*setcc_si_1_and"
13060   [(set (match_operand:SI 0 "register_operand" "=q")
13061         (match_operator:SI 1 "ix86_comparison_operator"
13062           [(reg FLAGS_REG) (const_int 0)]))
13063    (clobber (reg:CC FLAGS_REG))]
13064   "!TARGET_PARTIAL_REG_STALL
13065    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13066   "#"
13067   "&& reload_completed"
13068   [(set (match_dup 2) (match_dup 1))
13069    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13070               (clobber (reg:CC FLAGS_REG))])]
13071 {
13072   PUT_MODE (operands[1], QImode);
13073   operands[2] = gen_lowpart (QImode, operands[0]);
13074 })
13075
13076 (define_insn_and_split "*setcc_si_1_movzbl"
13077   [(set (match_operand:SI 0 "register_operand" "=q")
13078         (match_operator:SI 1 "ix86_comparison_operator"
13079           [(reg FLAGS_REG) (const_int 0)]))]
13080   "!TARGET_PARTIAL_REG_STALL
13081    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13082   "#"
13083   "&& reload_completed"
13084   [(set (match_dup 2) (match_dup 1))
13085    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13086 {
13087   PUT_MODE (operands[1], QImode);
13088   operands[2] = gen_lowpart (QImode, operands[0]);
13089 })
13090
13091 (define_insn "*setcc_qi"
13092   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13093         (match_operator:QI 1 "ix86_comparison_operator"
13094           [(reg FLAGS_REG) (const_int 0)]))]
13095   ""
13096   "set%C1\t%0"
13097   [(set_attr "type" "setcc")
13098    (set_attr "mode" "QI")])
13099
13100 (define_insn "*setcc_qi_slp"
13101   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13102         (match_operator:QI 1 "ix86_comparison_operator"
13103           [(reg FLAGS_REG) (const_int 0)]))]
13104   ""
13105   "set%C1\t%0"
13106   [(set_attr "type" "setcc")
13107    (set_attr "mode" "QI")])
13108
13109 ;; In general it is not safe to assume too much about CCmode registers,
13110 ;; so simplify-rtx stops when it sees a second one.  Under certain
13111 ;; conditions this is safe on x86, so help combine not create
13112 ;;
13113 ;;      seta    %al
13114 ;;      testb   %al, %al
13115 ;;      sete    %al
13116
13117 (define_split
13118   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13119         (ne:QI (match_operator 1 "ix86_comparison_operator"
13120                  [(reg FLAGS_REG) (const_int 0)])
13121             (const_int 0)))]
13122   ""
13123   [(set (match_dup 0) (match_dup 1))]
13124 {
13125   PUT_MODE (operands[1], QImode);
13126 })
13127
13128 (define_split
13129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13130         (ne:QI (match_operator 1 "ix86_comparison_operator"
13131                  [(reg FLAGS_REG) (const_int 0)])
13132             (const_int 0)))]
13133   ""
13134   [(set (match_dup 0) (match_dup 1))]
13135 {
13136   PUT_MODE (operands[1], QImode);
13137 })
13138
13139 (define_split
13140   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13141         (eq:QI (match_operator 1 "ix86_comparison_operator"
13142                  [(reg FLAGS_REG) (const_int 0)])
13143             (const_int 0)))]
13144   ""
13145   [(set (match_dup 0) (match_dup 1))]
13146 {
13147   rtx new_op1 = copy_rtx (operands[1]);
13148   operands[1] = new_op1;
13149   PUT_MODE (new_op1, QImode);
13150   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13151                                              GET_MODE (XEXP (new_op1, 0))));
13152
13153   /* Make sure that (a) the CCmode we have for the flags is strong
13154      enough for the reversed compare or (b) we have a valid FP compare.  */
13155   if (! ix86_comparison_operator (new_op1, VOIDmode))
13156     FAIL;
13157 })
13158
13159 (define_split
13160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13161         (eq:QI (match_operator 1 "ix86_comparison_operator"
13162                  [(reg FLAGS_REG) (const_int 0)])
13163             (const_int 0)))]
13164   ""
13165   [(set (match_dup 0) (match_dup 1))]
13166 {
13167   rtx new_op1 = copy_rtx (operands[1]);
13168   operands[1] = new_op1;
13169   PUT_MODE (new_op1, QImode);
13170   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13171                                              GET_MODE (XEXP (new_op1, 0))));
13172
13173   /* Make sure that (a) the CCmode we have for the flags is strong
13174      enough for the reversed compare or (b) we have a valid FP compare.  */
13175   if (! ix86_comparison_operator (new_op1, VOIDmode))
13176     FAIL;
13177 })
13178
13179 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13180 ;; subsequent logical operations are used to imitate conditional moves.
13181 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13182 ;; it directly.
13183
13184 (define_insn "*avx_setcc<mode>"
13185   [(set (match_operand:MODEF 0 "register_operand" "=x")
13186         (match_operator:MODEF 1 "avx_comparison_float_operator"
13187           [(match_operand:MODEF 2 "register_operand" "x")
13188            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13189   "TARGET_AVX"
13190   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13191   [(set_attr "type" "ssecmp")
13192    (set_attr "prefix" "vex")
13193    (set_attr "length_immediate" "1")
13194    (set_attr "mode" "<MODE>")])
13195
13196 (define_insn "*sse_setcc<mode>"
13197   [(set (match_operand:MODEF 0 "register_operand" "=x")
13198         (match_operator:MODEF 1 "sse_comparison_operator"
13199           [(match_operand:MODEF 2 "register_operand" "0")
13200            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13201   "SSE_FLOAT_MODE_P (<MODE>mode)"
13202   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13203   [(set_attr "type" "ssecmp")
13204    (set_attr "length_immediate" "1")
13205    (set_attr "mode" "<MODE>")])
13206 \f
13207 ;; Basic conditional jump instructions.
13208 ;; We ignore the overflow flag for signed branch instructions.
13209
13210 (define_insn "*jcc_1"
13211   [(set (pc)
13212         (if_then_else (match_operator 1 "ix86_comparison_operator"
13213                                       [(reg FLAGS_REG) (const_int 0)])
13214                       (label_ref (match_operand 0 "" ""))
13215                       (pc)))]
13216   ""
13217   "%+j%C1\t%l0"
13218   [(set_attr "type" "ibr")
13219    (set_attr "modrm" "0")
13220    (set (attr "length")
13221            (if_then_else (and (ge (minus (match_dup 0) (pc))
13222                                   (const_int -126))
13223                               (lt (minus (match_dup 0) (pc))
13224                                   (const_int 128)))
13225              (const_int 2)
13226              (const_int 6)))])
13227
13228 (define_insn "*jcc_2"
13229   [(set (pc)
13230         (if_then_else (match_operator 1 "ix86_comparison_operator"
13231                                       [(reg FLAGS_REG) (const_int 0)])
13232                       (pc)
13233                       (label_ref (match_operand 0 "" ""))))]
13234   ""
13235   "%+j%c1\t%l0"
13236   [(set_attr "type" "ibr")
13237    (set_attr "modrm" "0")
13238    (set (attr "length")
13239            (if_then_else (and (ge (minus (match_dup 0) (pc))
13240                                   (const_int -126))
13241                               (lt (minus (match_dup 0) (pc))
13242                                   (const_int 128)))
13243              (const_int 2)
13244              (const_int 6)))])
13245
13246 ;; In general it is not safe to assume too much about CCmode registers,
13247 ;; so simplify-rtx stops when it sees a second one.  Under certain
13248 ;; conditions this is safe on x86, so help combine not create
13249 ;;
13250 ;;      seta    %al
13251 ;;      testb   %al, %al
13252 ;;      je      Lfoo
13253
13254 (define_split
13255   [(set (pc)
13256         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13257                                       [(reg FLAGS_REG) (const_int 0)])
13258                           (const_int 0))
13259                       (label_ref (match_operand 1 "" ""))
13260                       (pc)))]
13261   ""
13262   [(set (pc)
13263         (if_then_else (match_dup 0)
13264                       (label_ref (match_dup 1))
13265                       (pc)))]
13266 {
13267   PUT_MODE (operands[0], VOIDmode);
13268 })
13269
13270 (define_split
13271   [(set (pc)
13272         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13273                                       [(reg FLAGS_REG) (const_int 0)])
13274                           (const_int 0))
13275                       (label_ref (match_operand 1 "" ""))
13276                       (pc)))]
13277   ""
13278   [(set (pc)
13279         (if_then_else (match_dup 0)
13280                       (label_ref (match_dup 1))
13281                       (pc)))]
13282 {
13283   rtx new_op0 = copy_rtx (operands[0]);
13284   operands[0] = new_op0;
13285   PUT_MODE (new_op0, VOIDmode);
13286   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13287                                              GET_MODE (XEXP (new_op0, 0))));
13288
13289   /* Make sure that (a) the CCmode we have for the flags is strong
13290      enough for the reversed compare or (b) we have a valid FP compare.  */
13291   if (! ix86_comparison_operator (new_op0, VOIDmode))
13292     FAIL;
13293 })
13294
13295 ;; zero_extend in SImode is correct, since this is what combine pass
13296 ;; generates from shift insn with QImode operand.  Actually, the mode of
13297 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13298 ;; appropriate modulo of the bit offset value.
13299
13300 (define_insn_and_split "*jcc_btdi_rex64"
13301   [(set (pc)
13302         (if_then_else (match_operator 0 "bt_comparison_operator"
13303                         [(zero_extract:DI
13304                            (match_operand:DI 1 "register_operand" "r")
13305                            (const_int 1)
13306                            (zero_extend:SI
13307                              (match_operand:QI 2 "register_operand" "r")))
13308                          (const_int 0)])
13309                       (label_ref (match_operand 3 "" ""))
13310                       (pc)))
13311    (clobber (reg:CC FLAGS_REG))]
13312   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13313   "#"
13314   "&& 1"
13315   [(set (reg:CCC FLAGS_REG)
13316         (compare:CCC
13317           (zero_extract:DI
13318             (match_dup 1)
13319             (const_int 1)
13320             (match_dup 2))
13321           (const_int 0)))
13322    (set (pc)
13323         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13324                       (label_ref (match_dup 3))
13325                       (pc)))]
13326 {
13327   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13328
13329   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13330 })
13331
13332 ;; avoid useless masking of bit offset operand
13333 (define_insn_and_split "*jcc_btdi_mask_rex64"
13334   [(set (pc)
13335         (if_then_else (match_operator 0 "bt_comparison_operator"
13336                         [(zero_extract:DI
13337                            (match_operand:DI 1 "register_operand" "r")
13338                            (const_int 1)
13339                            (and:SI
13340                              (match_operand:SI 2 "register_operand" "r")
13341                              (match_operand:SI 3 "const_int_operand" "n")))])
13342                       (label_ref (match_operand 4 "" ""))
13343                       (pc)))
13344    (clobber (reg:CC FLAGS_REG))]
13345   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13346    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13347   "#"
13348   "&& 1"
13349   [(set (reg:CCC FLAGS_REG)
13350         (compare:CCC
13351           (zero_extract:DI
13352             (match_dup 1)
13353             (const_int 1)
13354             (match_dup 2))
13355           (const_int 0)))
13356    (set (pc)
13357         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13358                       (label_ref (match_dup 4))
13359                       (pc)))]
13360 {
13361   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13362
13363   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13364 })
13365
13366 (define_insn_and_split "*jcc_btsi"
13367   [(set (pc)
13368         (if_then_else (match_operator 0 "bt_comparison_operator"
13369                         [(zero_extract:SI
13370                            (match_operand:SI 1 "register_operand" "r")
13371                            (const_int 1)
13372                            (zero_extend:SI
13373                              (match_operand:QI 2 "register_operand" "r")))
13374                          (const_int 0)])
13375                       (label_ref (match_operand 3 "" ""))
13376                       (pc)))
13377    (clobber (reg:CC FLAGS_REG))]
13378   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13379   "#"
13380   "&& 1"
13381   [(set (reg:CCC FLAGS_REG)
13382         (compare:CCC
13383           (zero_extract:SI
13384             (match_dup 1)
13385             (const_int 1)
13386             (match_dup 2))
13387           (const_int 0)))
13388    (set (pc)
13389         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13390                       (label_ref (match_dup 3))
13391                       (pc)))]
13392 {
13393   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13394
13395   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13396 })
13397
13398 ;; avoid useless masking of bit offset operand
13399 (define_insn_and_split "*jcc_btsi_mask"
13400   [(set (pc)
13401         (if_then_else (match_operator 0 "bt_comparison_operator"
13402                         [(zero_extract:SI
13403                            (match_operand:SI 1 "register_operand" "r")
13404                            (const_int 1)
13405                            (and:SI
13406                              (match_operand:SI 2 "register_operand" "r")
13407                              (match_operand:SI 3 "const_int_operand" "n")))])
13408                       (label_ref (match_operand 4 "" ""))
13409                       (pc)))
13410    (clobber (reg:CC FLAGS_REG))]
13411   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13412    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13413   "#"
13414   "&& 1"
13415   [(set (reg:CCC FLAGS_REG)
13416         (compare:CCC
13417           (zero_extract:SI
13418             (match_dup 1)
13419             (const_int 1)
13420             (match_dup 2))
13421           (const_int 0)))
13422    (set (pc)
13423         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13424                       (label_ref (match_dup 4))
13425                       (pc)))]
13426   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13427
13428 (define_insn_and_split "*jcc_btsi_1"
13429   [(set (pc)
13430         (if_then_else (match_operator 0 "bt_comparison_operator"
13431                         [(and:SI
13432                            (lshiftrt:SI
13433                              (match_operand:SI 1 "register_operand" "r")
13434                              (match_operand:QI 2 "register_operand" "r"))
13435                            (const_int 1))
13436                          (const_int 0)])
13437                       (label_ref (match_operand 3 "" ""))
13438                       (pc)))
13439    (clobber (reg:CC FLAGS_REG))]
13440   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13441   "#"
13442   "&& 1"
13443   [(set (reg:CCC FLAGS_REG)
13444         (compare:CCC
13445           (zero_extract:SI
13446             (match_dup 1)
13447             (const_int 1)
13448             (match_dup 2))
13449           (const_int 0)))
13450    (set (pc)
13451         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13452                       (label_ref (match_dup 3))
13453                       (pc)))]
13454 {
13455   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13456
13457   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13458 })
13459
13460 ;; avoid useless masking of bit offset operand
13461 (define_insn_and_split "*jcc_btsi_mask_1"
13462   [(set (pc)
13463         (if_then_else
13464           (match_operator 0 "bt_comparison_operator"
13465             [(and:SI
13466                (lshiftrt:SI
13467                  (match_operand:SI 1 "register_operand" "r")
13468                  (subreg:QI
13469                    (and:SI
13470                      (match_operand:SI 2 "register_operand" "r")
13471                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13472                (const_int 1))
13473              (const_int 0)])
13474           (label_ref (match_operand 4 "" ""))
13475           (pc)))
13476    (clobber (reg:CC FLAGS_REG))]
13477   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13478    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13479   "#"
13480   "&& 1"
13481   [(set (reg:CCC FLAGS_REG)
13482         (compare:CCC
13483           (zero_extract:SI
13484             (match_dup 1)
13485             (const_int 1)
13486             (match_dup 2))
13487           (const_int 0)))
13488    (set (pc)
13489         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13490                       (label_ref (match_dup 4))
13491                       (pc)))]
13492   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13493
13494 ;; Define combination compare-and-branch fp compare instructions to help
13495 ;; combine.
13496
13497 (define_insn "*fp_jcc_3_387"
13498   [(set (pc)
13499         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13500                         [(match_operand 1 "register_operand" "f")
13501                          (match_operand 2 "nonimmediate_operand" "fm")])
13502           (label_ref (match_operand 3 "" ""))
13503           (pc)))
13504    (clobber (reg:CCFP FPSR_REG))
13505    (clobber (reg:CCFP FLAGS_REG))
13506    (clobber (match_scratch:HI 4 "=a"))]
13507   "TARGET_80387
13508    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13509    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13510    && SELECT_CC_MODE (GET_CODE (operands[0]),
13511                       operands[1], operands[2]) == CCFPmode
13512    && !TARGET_CMOVE"
13513   "#")
13514
13515 (define_insn "*fp_jcc_4_387"
13516   [(set (pc)
13517         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13518                         [(match_operand 1 "register_operand" "f")
13519                          (match_operand 2 "nonimmediate_operand" "fm")])
13520           (pc)
13521           (label_ref (match_operand 3 "" ""))))
13522    (clobber (reg:CCFP FPSR_REG))
13523    (clobber (reg:CCFP FLAGS_REG))
13524    (clobber (match_scratch:HI 4 "=a"))]
13525   "TARGET_80387
13526    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13527    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13528    && SELECT_CC_MODE (GET_CODE (operands[0]),
13529                       operands[1], operands[2]) == CCFPmode
13530    && !TARGET_CMOVE"
13531   "#")
13532
13533 (define_insn "*fp_jcc_5_387"
13534   [(set (pc)
13535         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13536                         [(match_operand 1 "register_operand" "f")
13537                          (match_operand 2 "register_operand" "f")])
13538           (label_ref (match_operand 3 "" ""))
13539           (pc)))
13540    (clobber (reg:CCFP FPSR_REG))
13541    (clobber (reg:CCFP FLAGS_REG))
13542    (clobber (match_scratch:HI 4 "=a"))]
13543   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13544    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13545    && !TARGET_CMOVE"
13546   "#")
13547
13548 (define_insn "*fp_jcc_6_387"
13549   [(set (pc)
13550         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13551                         [(match_operand 1 "register_operand" "f")
13552                          (match_operand 2 "register_operand" "f")])
13553           (pc)
13554           (label_ref (match_operand 3 "" ""))))
13555    (clobber (reg:CCFP FPSR_REG))
13556    (clobber (reg:CCFP FLAGS_REG))
13557    (clobber (match_scratch:HI 4 "=a"))]
13558   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13559    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13560    && !TARGET_CMOVE"
13561   "#")
13562
13563 (define_insn "*fp_jcc_7_387"
13564   [(set (pc)
13565         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13566                         [(match_operand 1 "register_operand" "f")
13567                          (match_operand 2 "const0_operand" "")])
13568           (label_ref (match_operand 3 "" ""))
13569           (pc)))
13570    (clobber (reg:CCFP FPSR_REG))
13571    (clobber (reg:CCFP FLAGS_REG))
13572    (clobber (match_scratch:HI 4 "=a"))]
13573   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13574    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13575    && SELECT_CC_MODE (GET_CODE (operands[0]),
13576                       operands[1], operands[2]) == CCFPmode
13577    && !TARGET_CMOVE"
13578   "#")
13579
13580 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13581 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13582 ;; with a precedence over other operators and is always put in the first
13583 ;; place. Swap condition and operands to match ficom instruction.
13584
13585 (define_insn "*fp_jcc_8<mode>_387"
13586   [(set (pc)
13587         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13588                         [(match_operator 1 "float_operator"
13589                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13590                            (match_operand 3 "register_operand" "f,f")])
13591           (label_ref (match_operand 4 "" ""))
13592           (pc)))
13593    (clobber (reg:CCFP FPSR_REG))
13594    (clobber (reg:CCFP FLAGS_REG))
13595    (clobber (match_scratch:HI 5 "=a,a"))]
13596   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13597    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13598    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13599    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13600    && !TARGET_CMOVE"
13601   "#")
13602
13603 (define_split
13604   [(set (pc)
13605         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13606                         [(match_operand 1 "register_operand" "")
13607                          (match_operand 2 "nonimmediate_operand" "")])
13608           (match_operand 3 "" "")
13609           (match_operand 4 "" "")))
13610    (clobber (reg:CCFP FPSR_REG))
13611    (clobber (reg:CCFP FLAGS_REG))]
13612   "reload_completed"
13613   [(const_int 0)]
13614 {
13615   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13616                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13617   DONE;
13618 })
13619
13620 (define_split
13621   [(set (pc)
13622         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13623                         [(match_operand 1 "register_operand" "")
13624                          (match_operand 2 "general_operand" "")])
13625           (match_operand 3 "" "")
13626           (match_operand 4 "" "")))
13627    (clobber (reg:CCFP FPSR_REG))
13628    (clobber (reg:CCFP FLAGS_REG))
13629    (clobber (match_scratch:HI 5 "=a"))]
13630   "reload_completed"
13631   [(const_int 0)]
13632 {
13633   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13634                         operands[3], operands[4], operands[5], NULL_RTX);
13635   DONE;
13636 })
13637
13638 (define_split
13639   [(set (pc)
13640         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13641                         [(match_operator 1 "float_operator"
13642                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13643                            (match_operand 3 "register_operand" "")])
13644           (match_operand 4 "" "")
13645           (match_operand 5 "" "")))
13646    (clobber (reg:CCFP FPSR_REG))
13647    (clobber (reg:CCFP FLAGS_REG))
13648    (clobber (match_scratch:HI 6 "=a"))]
13649   "reload_completed"
13650   [(const_int 0)]
13651 {
13652   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13653   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13654                         operands[3], operands[7],
13655                         operands[4], operands[5], operands[6], NULL_RTX);
13656   DONE;
13657 })
13658
13659 ;; %%% Kill this when reload knows how to do it.
13660 (define_split
13661   [(set (pc)
13662         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13663                         [(match_operator 1 "float_operator"
13664                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13665                            (match_operand 3 "register_operand" "")])
13666           (match_operand 4 "" "")
13667           (match_operand 5 "" "")))
13668    (clobber (reg:CCFP FPSR_REG))
13669    (clobber (reg:CCFP FLAGS_REG))
13670    (clobber (match_scratch:HI 6 "=a"))]
13671   "reload_completed"
13672   [(const_int 0)]
13673 {
13674   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13675   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13676   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13677                         operands[3], operands[7],
13678                         operands[4], operands[5], operands[6], operands[2]);
13679   DONE;
13680 })
13681 \f
13682 ;; Unconditional and other jump instructions
13683
13684 (define_insn "jump"
13685   [(set (pc)
13686         (label_ref (match_operand 0 "" "")))]
13687   ""
13688   "jmp\t%l0"
13689   [(set_attr "type" "ibr")
13690    (set (attr "length")
13691            (if_then_else (and (ge (minus (match_dup 0) (pc))
13692                                   (const_int -126))
13693                               (lt (minus (match_dup 0) (pc))
13694                                   (const_int 128)))
13695              (const_int 2)
13696              (const_int 5)))
13697    (set_attr "modrm" "0")])
13698
13699 (define_expand "indirect_jump"
13700   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13701   ""
13702   "")
13703
13704 (define_insn "*indirect_jump"
13705   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13706   ""
13707   "jmp\t%A0"
13708   [(set_attr "type" "ibr")
13709    (set_attr "length_immediate" "0")])
13710
13711 (define_expand "tablejump"
13712   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13713               (use (label_ref (match_operand 1 "" "")))])]
13714   ""
13715 {
13716   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13717      relative.  Convert the relative address to an absolute address.  */
13718   if (flag_pic)
13719     {
13720       rtx op0, op1;
13721       enum rtx_code code;
13722
13723       /* We can't use @GOTOFF for text labels on VxWorks;
13724          see gotoff_operand.  */
13725       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13726         {
13727           code = PLUS;
13728           op0 = operands[0];
13729           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13730         }
13731       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13732         {
13733           code = PLUS;
13734           op0 = operands[0];
13735           op1 = pic_offset_table_rtx;
13736         }
13737       else
13738         {
13739           code = MINUS;
13740           op0 = pic_offset_table_rtx;
13741           op1 = operands[0];
13742         }
13743
13744       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13745                                          OPTAB_DIRECT);
13746     }
13747 })
13748
13749 (define_insn "*tablejump_1"
13750   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13751    (use (label_ref (match_operand 1 "" "")))]
13752   ""
13753   "jmp\t%A0"
13754   [(set_attr "type" "ibr")
13755    (set_attr "length_immediate" "0")])
13756 \f
13757 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13758
13759 (define_peephole2
13760   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13761    (set (match_operand:QI 1 "register_operand" "")
13762         (match_operator:QI 2 "ix86_comparison_operator"
13763           [(reg FLAGS_REG) (const_int 0)]))
13764    (set (match_operand 3 "q_regs_operand" "")
13765         (zero_extend (match_dup 1)))]
13766   "(peep2_reg_dead_p (3, operands[1])
13767     || operands_match_p (operands[1], operands[3]))
13768    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13769   [(set (match_dup 4) (match_dup 0))
13770    (set (strict_low_part (match_dup 5))
13771         (match_dup 2))]
13772 {
13773   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13774   operands[5] = gen_lowpart (QImode, operands[3]);
13775   ix86_expand_clear (operands[3]);
13776 })
13777
13778 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13779
13780 (define_peephole2
13781   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13782    (set (match_operand:QI 1 "register_operand" "")
13783         (match_operator:QI 2 "ix86_comparison_operator"
13784           [(reg FLAGS_REG) (const_int 0)]))
13785    (parallel [(set (match_operand 3 "q_regs_operand" "")
13786                    (zero_extend (match_dup 1)))
13787               (clobber (reg:CC FLAGS_REG))])]
13788   "(peep2_reg_dead_p (3, operands[1])
13789     || operands_match_p (operands[1], operands[3]))
13790    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13791   [(set (match_dup 4) (match_dup 0))
13792    (set (strict_low_part (match_dup 5))
13793         (match_dup 2))]
13794 {
13795   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13796   operands[5] = gen_lowpart (QImode, operands[3]);
13797   ix86_expand_clear (operands[3]);
13798 })
13799 \f
13800 ;; Call instructions.
13801
13802 ;; The predicates normally associated with named expanders are not properly
13803 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13804 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13805
13806 ;; P6 processors will jump to the address after the decrement when %esp
13807 ;; is used as a call operand, so they will execute return address as a code.
13808 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13809  
13810 ;; Call subroutine returning no value.
13811
13812 (define_expand "call_pop"
13813   [(parallel [(call (match_operand:QI 0 "" "")
13814                     (match_operand:SI 1 "" ""))
13815               (set (reg:SI SP_REG)
13816                    (plus:SI (reg:SI SP_REG)
13817                             (match_operand:SI 3 "" "")))])]
13818   "!TARGET_64BIT"
13819 {
13820   ix86_expand_call (NULL, operands[0], operands[1],
13821                     operands[2], operands[3], 0);
13822   DONE;
13823 })
13824
13825 (define_insn "*call_pop_0"
13826   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13827          (match_operand:SI 1 "" ""))
13828    (set (reg:SI SP_REG)
13829         (plus:SI (reg:SI SP_REG)
13830                  (match_operand:SI 2 "immediate_operand" "")))]
13831   "!TARGET_64BIT"
13832 {
13833   if (SIBLING_CALL_P (insn))
13834     return "jmp\t%P0";
13835   else
13836     return "call\t%P0";
13837 }
13838   [(set_attr "type" "call")])
13839
13840 (define_insn "*call_pop_1"
13841   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13842          (match_operand:SI 1 "" ""))
13843    (set (reg:SI SP_REG)
13844         (plus:SI (reg:SI SP_REG)
13845                  (match_operand:SI 2 "immediate_operand" "i")))]
13846   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13847 {
13848   if (constant_call_address_operand (operands[0], Pmode))
13849     return "call\t%P0";
13850   return "call\t%A0";
13851 }
13852   [(set_attr "type" "call")])
13853
13854 (define_insn "*sibcall_pop_1"
13855   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13856          (match_operand:SI 1 "" ""))
13857    (set (reg:SI SP_REG)
13858         (plus:SI (reg:SI SP_REG)
13859                  (match_operand:SI 2 "immediate_operand" "i,i")))]
13860   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13861   "@
13862    jmp\t%P0
13863    jmp\t%A0"
13864   [(set_attr "type" "call")])
13865
13866 (define_expand "call"
13867   [(call (match_operand:QI 0 "" "")
13868          (match_operand 1 "" ""))
13869    (use (match_operand 2 "" ""))]
13870   ""
13871 {
13872   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13873   DONE;
13874 })
13875
13876 (define_expand "sibcall"
13877   [(call (match_operand:QI 0 "" "")
13878          (match_operand 1 "" ""))
13879    (use (match_operand 2 "" ""))]
13880   ""
13881 {
13882   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13883   DONE;
13884 })
13885
13886 (define_insn "*call_0"
13887   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13888          (match_operand 1 "" ""))]
13889   ""
13890 {
13891   if (SIBLING_CALL_P (insn))
13892     return "jmp\t%P0";
13893   else
13894     return "call\t%P0";
13895 }
13896   [(set_attr "type" "call")])
13897
13898 (define_insn "*call_1"
13899   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13900          (match_operand 1 "" ""))]
13901   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13902 {
13903   if (constant_call_address_operand (operands[0], Pmode))
13904     return "call\t%P0";
13905   return "call\t%A0";
13906 }
13907   [(set_attr "type" "call")])
13908
13909 (define_insn "*sibcall_1"
13910   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13911          (match_operand 1 "" ""))]
13912   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13913   "@
13914    jmp\t%P0
13915    jmp\t%A0"
13916   [(set_attr "type" "call")])
13917
13918 (define_insn "*call_1_rex64"
13919   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13920          (match_operand 1 "" ""))]
13921   "TARGET_64BIT && !SIBLING_CALL_P (insn)
13922    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13923 {
13924   if (constant_call_address_operand (operands[0], Pmode))
13925     return "call\t%P0";
13926   return "call\t%A0";
13927 }
13928   [(set_attr "type" "call")])
13929
13930 (define_insn "*call_1_rex64_ms_sysv"
13931   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13932          (match_operand 1 "" ""))
13933    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13934    (clobber (reg:TI XMM6_REG))
13935    (clobber (reg:TI XMM7_REG))
13936    (clobber (reg:TI XMM8_REG))
13937    (clobber (reg:TI XMM9_REG))
13938    (clobber (reg:TI XMM10_REG))
13939    (clobber (reg:TI XMM11_REG))
13940    (clobber (reg:TI XMM12_REG))
13941    (clobber (reg:TI XMM13_REG))
13942    (clobber (reg:TI XMM14_REG))
13943    (clobber (reg:TI XMM15_REG))
13944    (clobber (reg:DI SI_REG))
13945    (clobber (reg:DI DI_REG))]
13946   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13947 {
13948   if (constant_call_address_operand (operands[0], Pmode))
13949     return "call\t%P0";
13950   return "call\t%A0";
13951 }
13952   [(set_attr "type" "call")])
13953
13954 (define_insn "*call_1_rex64_large"
13955   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13956          (match_operand 1 "" ""))]
13957   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13958   "call\t%A0"
13959   [(set_attr "type" "call")])
13960
13961 (define_insn "*sibcall_1_rex64"
13962   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13963          (match_operand 1 "" ""))]
13964   "TARGET_64BIT && SIBLING_CALL_P (insn)"
13965   "@
13966    jmp\t%P0
13967    jmp\t%A0"
13968   [(set_attr "type" "call")])
13969
13970 ;; Call subroutine, returning value in operand 0
13971 (define_expand "call_value_pop"
13972   [(parallel [(set (match_operand 0 "" "")
13973                    (call (match_operand:QI 1 "" "")
13974                          (match_operand:SI 2 "" "")))
13975               (set (reg:SI SP_REG)
13976                    (plus:SI (reg:SI SP_REG)
13977                             (match_operand:SI 4 "" "")))])]
13978   "!TARGET_64BIT"
13979 {
13980   ix86_expand_call (operands[0], operands[1], operands[2],
13981                     operands[3], operands[4], 0);
13982   DONE;
13983 })
13984
13985 (define_expand "call_value"
13986   [(set (match_operand 0 "" "")
13987         (call (match_operand:QI 1 "" "")
13988               (match_operand:SI 2 "" "")))
13989    (use (match_operand:SI 3 "" ""))]
13990   ;; Operand 3 is not used on the i386.
13991   ""
13992 {
13993   ix86_expand_call (operands[0], operands[1], operands[2],
13994                     operands[3], NULL, 0);
13995   DONE;
13996 })
13997
13998 (define_expand "sibcall_value"
13999   [(set (match_operand 0 "" "")
14000         (call (match_operand:QI 1 "" "")
14001               (match_operand:SI 2 "" "")))
14002    (use (match_operand:SI 3 "" ""))]
14003   ;; Operand 3 is not used on the i386.
14004   ""
14005 {
14006   ix86_expand_call (operands[0], operands[1], operands[2],
14007                     operands[3], NULL, 1);
14008   DONE;
14009 })
14010
14011 ;; Call subroutine returning any type.
14012
14013 (define_expand "untyped_call"
14014   [(parallel [(call (match_operand 0 "" "")
14015                     (const_int 0))
14016               (match_operand 1 "" "")
14017               (match_operand 2 "" "")])]
14018   ""
14019 {
14020   int i;
14021
14022   /* In order to give reg-stack an easier job in validating two
14023      coprocessor registers as containing a possible return value,
14024      simply pretend the untyped call returns a complex long double
14025      value. 
14026
14027      We can't use SSE_REGPARM_MAX here since callee is unprototyped
14028      and should have the default ABI.  */
14029
14030   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14031                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14032                     operands[0], const0_rtx,
14033                     GEN_INT ((TARGET_64BIT
14034                               ? (ix86_abi == SYSV_ABI
14035                                  ? X86_64_SSE_REGPARM_MAX
14036                                  : X86_64_MS_SSE_REGPARM_MAX)
14037                               : X86_32_SSE_REGPARM_MAX)
14038                              - 1),
14039                     NULL, 0);
14040
14041   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14042     {
14043       rtx set = XVECEXP (operands[2], 0, i);
14044       emit_move_insn (SET_DEST (set), SET_SRC (set));
14045     }
14046
14047   /* The optimizer does not know that the call sets the function value
14048      registers we stored in the result block.  We avoid problems by
14049      claiming that all hard registers are used and clobbered at this
14050      point.  */
14051   emit_insn (gen_blockage ());
14052
14053   DONE;
14054 })
14055 \f
14056 ;; Prologue and epilogue instructions
14057
14058 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14059 ;; all of memory.  This blocks insns from being moved across this point.
14060
14061 (define_insn "blockage"
14062   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14063   ""
14064   ""
14065   [(set_attr "length" "0")])
14066
14067 ;; Do not schedule instructions accessing memory across this point.
14068
14069 (define_expand "memory_blockage"
14070   [(set (match_dup 0)
14071         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14072   ""
14073 {
14074   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14075   MEM_VOLATILE_P (operands[0]) = 1;
14076 })
14077
14078 (define_insn "*memory_blockage"
14079   [(set (match_operand:BLK 0 "" "")
14080         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14081   ""
14082   ""
14083   [(set_attr "length" "0")])
14084
14085 ;; As USE insns aren't meaningful after reload, this is used instead
14086 ;; to prevent deleting instructions setting registers for PIC code
14087 (define_insn "prologue_use"
14088   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14089   ""
14090   ""
14091   [(set_attr "length" "0")])
14092
14093 ;; Insn emitted into the body of a function to return from a function.
14094 ;; This is only done if the function's epilogue is known to be simple.
14095 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14096
14097 (define_expand "return"
14098   [(return)]
14099   "ix86_can_use_return_insn_p ()"
14100 {
14101   if (crtl->args.pops_args)
14102     {
14103       rtx popc = GEN_INT (crtl->args.pops_args);
14104       emit_jump_insn (gen_return_pop_internal (popc));
14105       DONE;
14106     }
14107 })
14108
14109 (define_insn "return_internal"
14110   [(return)]
14111   "reload_completed"
14112   "ret"
14113   [(set_attr "length" "1")
14114    (set_attr "atom_unit" "jeu")
14115    (set_attr "length_immediate" "0")
14116    (set_attr "modrm" "0")])
14117
14118 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14119 ;; instruction Athlon and K8 have.
14120
14121 (define_insn "return_internal_long"
14122   [(return)
14123    (unspec [(const_int 0)] UNSPEC_REP)]
14124   "reload_completed"
14125   "rep\;ret"
14126   [(set_attr "length" "2")
14127    (set_attr "atom_unit" "jeu")
14128    (set_attr "length_immediate" "0")
14129    (set_attr "prefix_rep" "1")
14130    (set_attr "modrm" "0")])
14131
14132 (define_insn "return_pop_internal"
14133   [(return)
14134    (use (match_operand:SI 0 "const_int_operand" ""))]
14135   "reload_completed"
14136   "ret\t%0"
14137   [(set_attr "length" "3")
14138    (set_attr "atom_unit" "jeu")
14139    (set_attr "length_immediate" "2")
14140    (set_attr "modrm" "0")])
14141
14142 (define_insn "return_indirect_internal"
14143   [(return)
14144    (use (match_operand:SI 0 "register_operand" "r"))]
14145   "reload_completed"
14146   "jmp\t%A0"
14147   [(set_attr "type" "ibr")
14148    (set_attr "length_immediate" "0")])
14149
14150 (define_insn "nop"
14151   [(const_int 0)]
14152   ""
14153   "nop"
14154   [(set_attr "length" "1")
14155    (set_attr "length_immediate" "0")
14156    (set_attr "modrm" "0")])
14157
14158 (define_insn "vswapmov"
14159   [(set (match_operand:SI 0 "register_operand" "=r")
14160         (match_operand:SI 1 "register_operand" "r"))
14161    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14162   ""
14163   "movl.s\t{%1, %0|%0, %1}"
14164   [(set_attr "length" "2")
14165    (set_attr "length_immediate" "0")
14166    (set_attr "modrm" "0")])
14167
14168 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
14169 ;; branch prediction penalty for the third jump in a 16-byte
14170 ;; block on K8.
14171
14172 (define_insn "pad"
14173   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14174   ""
14175 {
14176 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14177   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14178 #else
14179   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14180      The align insn is used to avoid 3 jump instructions in the row to improve
14181      branch prediction and the benefits hardly outweigh the cost of extra 8
14182      nops on the average inserted by full alignment pseudo operation.  */
14183 #endif
14184   return "";
14185 }
14186   [(set_attr "length" "16")])
14187
14188 (define_expand "prologue"
14189   [(const_int 0)]
14190   ""
14191   "ix86_expand_prologue (); DONE;")
14192
14193 (define_insn "set_got"
14194   [(set (match_operand:SI 0 "register_operand" "=r")
14195         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14196    (clobber (reg:CC FLAGS_REG))]
14197   "!TARGET_64BIT"
14198   { return output_set_got (operands[0], NULL_RTX); }
14199   [(set_attr "type" "multi")
14200    (set_attr "length" "12")])
14201
14202 (define_insn "set_got_labelled"
14203   [(set (match_operand:SI 0 "register_operand" "=r")
14204         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14205          UNSPEC_SET_GOT))
14206    (clobber (reg:CC FLAGS_REG))]
14207   "!TARGET_64BIT"
14208   { return output_set_got (operands[0], operands[1]); }
14209   [(set_attr "type" "multi")
14210    (set_attr "length" "12")])
14211
14212 (define_insn "set_got_rex64"
14213   [(set (match_operand:DI 0 "register_operand" "=r")
14214         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14215   "TARGET_64BIT"
14216   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14217   [(set_attr "type" "lea")
14218    (set_attr "length_address" "4")
14219    (set_attr "mode" "DI")])
14220
14221 (define_insn "set_rip_rex64"
14222   [(set (match_operand:DI 0 "register_operand" "=r")
14223         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14224   "TARGET_64BIT"
14225   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14226   [(set_attr "type" "lea")
14227    (set_attr "length_address" "4")
14228    (set_attr "mode" "DI")])
14229
14230 (define_insn "set_got_offset_rex64"
14231   [(set (match_operand:DI 0 "register_operand" "=r")
14232         (unspec:DI
14233           [(label_ref (match_operand 1 "" ""))]
14234           UNSPEC_SET_GOT_OFFSET))]
14235   "TARGET_64BIT"
14236   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14237   [(set_attr "type" "imov")
14238    (set_attr "length_immediate" "0")
14239    (set_attr "length_address" "8")
14240    (set_attr "mode" "DI")])
14241
14242 (define_expand "epilogue"
14243   [(const_int 0)]
14244   ""
14245   "ix86_expand_epilogue (1); DONE;")
14246
14247 (define_expand "sibcall_epilogue"
14248   [(const_int 0)]
14249   ""
14250   "ix86_expand_epilogue (0); DONE;")
14251
14252 (define_expand "eh_return"
14253   [(use (match_operand 0 "register_operand" ""))]
14254   ""
14255 {
14256   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14257
14258   /* Tricky bit: we write the address of the handler to which we will
14259      be returning into someone else's stack frame, one word below the
14260      stack address we wish to restore.  */
14261   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14262   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14263   tmp = gen_rtx_MEM (Pmode, tmp);
14264   emit_move_insn (tmp, ra);
14265
14266   emit_jump_insn (gen_eh_return_internal ());
14267   emit_barrier ();
14268   DONE;
14269 })
14270
14271 (define_insn_and_split "eh_return_internal"
14272   [(eh_return)]
14273   ""
14274   "#"
14275   "epilogue_completed"
14276   [(const_int 0)]
14277   "ix86_expand_epilogue (2); DONE;")
14278
14279 (define_insn "leave"
14280   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14281    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14282    (clobber (mem:BLK (scratch)))]
14283   "!TARGET_64BIT"
14284   "leave"
14285   [(set_attr "type" "leave")])
14286
14287 (define_insn "leave_rex64"
14288   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14289    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14290    (clobber (mem:BLK (scratch)))]
14291   "TARGET_64BIT"
14292   "leave"
14293   [(set_attr "type" "leave")])
14294 \f
14295 (define_expand "ffssi2"
14296   [(parallel
14297      [(set (match_operand:SI 0 "register_operand" "")
14298            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14299       (clobber (match_scratch:SI 2 ""))
14300       (clobber (reg:CC FLAGS_REG))])]
14301   ""
14302 {
14303   if (TARGET_CMOVE)
14304     {
14305       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14306       DONE;
14307     }
14308 })
14309
14310 (define_expand "ffs_cmove"
14311   [(set (match_dup 2) (const_int -1))
14312    (parallel [(set (reg:CCZ FLAGS_REG)
14313                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14314                                 (const_int 0)))
14315               (set (match_operand:SI 0 "register_operand" "")
14316                    (ctz:SI (match_dup 1)))])
14317    (set (match_dup 0) (if_then_else:SI
14318                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14319                         (match_dup 2)
14320                         (match_dup 0)))
14321    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14322               (clobber (reg:CC FLAGS_REG))])]
14323   "TARGET_CMOVE"
14324   "operands[2] = gen_reg_rtx (SImode);")
14325
14326 (define_insn_and_split "*ffs_no_cmove"
14327   [(set (match_operand:SI 0 "register_operand" "=r")
14328         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14329    (clobber (match_scratch:SI 2 "=&q"))
14330    (clobber (reg:CC FLAGS_REG))]
14331   "!TARGET_CMOVE"
14332   "#"
14333   "&& reload_completed"
14334   [(parallel [(set (reg:CCZ FLAGS_REG)
14335                    (compare:CCZ (match_dup 1) (const_int 0)))
14336               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14337    (set (strict_low_part (match_dup 3))
14338         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14339    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14340               (clobber (reg:CC FLAGS_REG))])
14341    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14342               (clobber (reg:CC FLAGS_REG))])
14343    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14344               (clobber (reg:CC FLAGS_REG))])]
14345 {
14346   operands[3] = gen_lowpart (QImode, operands[2]);
14347   ix86_expand_clear (operands[2]);
14348 })
14349
14350 (define_insn "*ffssi_1"
14351   [(set (reg:CCZ FLAGS_REG)
14352         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14353                      (const_int 0)))
14354    (set (match_operand:SI 0 "register_operand" "=r")
14355         (ctz:SI (match_dup 1)))]
14356   ""
14357   "bsf{l}\t{%1, %0|%0, %1}"
14358   [(set_attr "type" "alu1")
14359    (set_attr "prefix_0f" "1")
14360    (set_attr "mode" "SI")])
14361
14362 (define_expand "ffsdi2"
14363   [(set (match_dup 2) (const_int -1))
14364    (parallel [(set (reg:CCZ FLAGS_REG)
14365                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14366                                 (const_int 0)))
14367               (set (match_operand:DI 0 "register_operand" "")
14368                    (ctz:DI (match_dup 1)))])
14369    (set (match_dup 0) (if_then_else:DI
14370                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14371                         (match_dup 2)
14372                         (match_dup 0)))
14373    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14374               (clobber (reg:CC FLAGS_REG))])]
14375   "TARGET_64BIT"
14376   "operands[2] = gen_reg_rtx (DImode);")
14377
14378 (define_insn "*ffsdi_1"
14379   [(set (reg:CCZ FLAGS_REG)
14380         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14381                      (const_int 0)))
14382    (set (match_operand:DI 0 "register_operand" "=r")
14383         (ctz:DI (match_dup 1)))]
14384   "TARGET_64BIT"
14385   "bsf{q}\t{%1, %0|%0, %1}"
14386   [(set_attr "type" "alu1")
14387    (set_attr "prefix_0f" "1")
14388    (set_attr "mode" "DI")])
14389
14390 (define_insn "ctzsi2"
14391   [(set (match_operand:SI 0 "register_operand" "=r")
14392         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14393    (clobber (reg:CC FLAGS_REG))]
14394   ""
14395   "bsf{l}\t{%1, %0|%0, %1}"
14396   [(set_attr "type" "alu1")
14397    (set_attr "prefix_0f" "1")
14398    (set_attr "mode" "SI")])
14399
14400 (define_insn "ctzdi2"
14401   [(set (match_operand:DI 0 "register_operand" "=r")
14402         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14403    (clobber (reg:CC FLAGS_REG))]
14404   "TARGET_64BIT"
14405   "bsf{q}\t{%1, %0|%0, %1}"
14406   [(set_attr "type" "alu1")
14407    (set_attr "prefix_0f" "1")
14408    (set_attr "mode" "DI")])
14409
14410 (define_expand "clzsi2"
14411   [(parallel
14412      [(set (match_operand:SI 0 "register_operand" "")
14413            (minus:SI (const_int 31)
14414                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14415       (clobber (reg:CC FLAGS_REG))])
14416    (parallel
14417      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14418       (clobber (reg:CC FLAGS_REG))])]
14419   ""
14420 {
14421   if (TARGET_ABM)
14422     {
14423       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14424       DONE;
14425     }
14426 })
14427
14428 (define_insn "clzsi2_abm"
14429   [(set (match_operand:SI 0 "register_operand" "=r")
14430         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14431    (clobber (reg:CC FLAGS_REG))]
14432   "TARGET_ABM"
14433   "lzcnt{l}\t{%1, %0|%0, %1}"
14434   [(set_attr "prefix_rep" "1")
14435    (set_attr "type" "bitmanip")
14436    (set_attr "mode" "SI")])
14437
14438 (define_insn "bsr"
14439   [(set (match_operand:SI 0 "register_operand" "=r")
14440         (minus:SI (const_int 31)
14441                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14442    (clobber (reg:CC FLAGS_REG))]
14443   ""
14444   "bsr{l}\t{%1, %0|%0, %1}"
14445   [(set_attr "type" "alu1")
14446    (set_attr "prefix_0f" "1")
14447    (set_attr "mode" "SI")])
14448
14449 (define_insn "popcount<mode>2"
14450   [(set (match_operand:SWI248 0 "register_operand" "=r")
14451         (popcount:SWI248
14452           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14453    (clobber (reg:CC FLAGS_REG))]
14454   "TARGET_POPCNT"
14455 {
14456 #if TARGET_MACHO
14457   return "popcnt\t{%1, %0|%0, %1}";
14458 #else
14459   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14460 #endif
14461 }
14462   [(set_attr "prefix_rep" "1")
14463    (set_attr "type" "bitmanip")
14464    (set_attr "mode" "<MODE>")])
14465
14466 (define_insn "*popcount<mode>2_cmp"
14467   [(set (reg FLAGS_REG)
14468         (compare
14469           (popcount:SWI248
14470             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14471           (const_int 0)))
14472    (set (match_operand:SWI248 0 "register_operand" "=r")
14473         (popcount:SWI248 (match_dup 1)))]
14474   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14475 {
14476 #if TARGET_MACHO
14477   return "popcnt\t{%1, %0|%0, %1}";
14478 #else
14479   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14480 #endif
14481 }
14482   [(set_attr "prefix_rep" "1")
14483    (set_attr "type" "bitmanip")
14484    (set_attr "mode" "<MODE>")])
14485
14486 (define_insn "*popcountsi2_cmp_zext"
14487   [(set (reg FLAGS_REG)
14488         (compare
14489           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14490           (const_int 0)))
14491    (set (match_operand:DI 0 "register_operand" "=r")
14492         (zero_extend:DI(popcount:SI (match_dup 1))))]
14493   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14494 {
14495 #if TARGET_MACHO
14496   return "popcnt\t{%1, %0|%0, %1}";
14497 #else
14498   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14499 #endif
14500 }
14501   [(set_attr "prefix_rep" "1")
14502    (set_attr "type" "bitmanip")
14503    (set_attr "mode" "SI")])
14504
14505 (define_expand "bswapsi2"
14506   [(set (match_operand:SI 0 "register_operand" "")
14507         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14508   ""
14509 {
14510   if (!(TARGET_BSWAP || TARGET_MOVBE))
14511     {
14512       rtx x = operands[0];
14513
14514       emit_move_insn (x, operands[1]);
14515       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14516       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14517       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14518       DONE;
14519     }
14520 })
14521
14522 (define_insn "*bswapsi_movbe"
14523   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14524         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14525   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14526   "@
14527     bswap\t%0
14528     movbe\t{%1, %0|%0, %1}
14529     movbe\t{%1, %0|%0, %1}"
14530   [(set_attr "type" "*,imov,imov")
14531    (set_attr "modrm" "*,1,1")
14532    (set_attr "prefix_0f" "1")
14533    (set_attr "prefix_extra" "*,1,1")
14534    (set_attr "length" "2,*,*")
14535    (set_attr "mode" "SI")])
14536
14537 (define_insn "*bswapsi_1"
14538   [(set (match_operand:SI 0 "register_operand" "=r")
14539         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14540   "TARGET_BSWAP"
14541   "bswap\t%0"
14542   [(set_attr "prefix_0f" "1")
14543    (set_attr "length" "2")])
14544
14545 (define_insn "*bswaphi_lowpart_1"
14546   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14547         (bswap:HI (match_dup 0)))
14548    (clobber (reg:CC FLAGS_REG))]
14549   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14550   "@
14551     xchg{b}\t{%h0, %b0|%b0, %h0}
14552     rol{w}\t{$8, %0|%0, 8}"
14553   [(set_attr "length" "2,4")
14554    (set_attr "mode" "QI,HI")])
14555
14556 (define_insn "bswaphi_lowpart"
14557   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14558         (bswap:HI (match_dup 0)))
14559    (clobber (reg:CC FLAGS_REG))]
14560   ""
14561   "rol{w}\t{$8, %0|%0, 8}"
14562   [(set_attr "length" "4")
14563    (set_attr "mode" "HI")])
14564
14565 (define_expand "bswapdi2"
14566   [(set (match_operand:DI 0 "register_operand" "")
14567         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14568   "TARGET_64BIT"
14569   "")
14570
14571 (define_insn "*bswapdi_movbe"
14572   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14573         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14574   "TARGET_64BIT && TARGET_MOVBE
14575    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14576   "@
14577     bswap\t%0
14578     movbe\t{%1, %0|%0, %1}
14579     movbe\t{%1, %0|%0, %1}"
14580   [(set_attr "type" "*,imov,imov")
14581    (set_attr "modrm" "*,1,1")
14582    (set_attr "prefix_0f" "1")
14583    (set_attr "prefix_extra" "*,1,1")
14584    (set_attr "length" "3,*,*")
14585    (set_attr "mode" "DI")])
14586
14587 (define_insn "*bswapdi_1"
14588   [(set (match_operand:DI 0 "register_operand" "=r")
14589         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14590   "TARGET_64BIT"
14591   "bswap\t%0"
14592   [(set_attr "prefix_0f" "1")
14593    (set_attr "length" "3")])
14594
14595 (define_expand "clzdi2"
14596   [(parallel
14597      [(set (match_operand:DI 0 "register_operand" "")
14598            (minus:DI (const_int 63)
14599                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14600       (clobber (reg:CC FLAGS_REG))])
14601    (parallel
14602      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14603       (clobber (reg:CC FLAGS_REG))])]
14604   "TARGET_64BIT"
14605 {
14606   if (TARGET_ABM)
14607     {
14608       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14609       DONE;
14610     }
14611 })
14612
14613 (define_insn "clzdi2_abm"
14614   [(set (match_operand:DI 0 "register_operand" "=r")
14615         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14616    (clobber (reg:CC FLAGS_REG))]
14617   "TARGET_64BIT && TARGET_ABM"
14618   "lzcnt{q}\t{%1, %0|%0, %1}"
14619   [(set_attr "prefix_rep" "1")
14620    (set_attr "type" "bitmanip")
14621    (set_attr "mode" "DI")])
14622
14623 (define_insn "bsr_rex64"
14624   [(set (match_operand:DI 0 "register_operand" "=r")
14625         (minus:DI (const_int 63)
14626                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14627    (clobber (reg:CC FLAGS_REG))]
14628   "TARGET_64BIT"
14629   "bsr{q}\t{%1, %0|%0, %1}"
14630   [(set_attr "type" "alu1")
14631    (set_attr "prefix_0f" "1")
14632    (set_attr "mode" "DI")])
14633
14634 (define_expand "clzhi2"
14635   [(parallel
14636      [(set (match_operand:HI 0 "register_operand" "")
14637            (minus:HI (const_int 15)
14638                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14639       (clobber (reg:CC FLAGS_REG))])
14640    (parallel
14641      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14642       (clobber (reg:CC FLAGS_REG))])]
14643   ""
14644 {
14645   if (TARGET_ABM)
14646     {
14647       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14648       DONE;
14649     }
14650 })
14651
14652 (define_insn "clzhi2_abm"
14653   [(set (match_operand:HI 0 "register_operand" "=r")
14654         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "TARGET_ABM"
14657   "lzcnt{w}\t{%1, %0|%0, %1}"
14658   [(set_attr "prefix_rep" "1")
14659    (set_attr "type" "bitmanip")
14660    (set_attr "mode" "HI")])
14661
14662 (define_insn "*bsrhi"
14663   [(set (match_operand:HI 0 "register_operand" "=r")
14664         (minus:HI (const_int 15)
14665                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14666    (clobber (reg:CC FLAGS_REG))]
14667   ""
14668   "bsr{w}\t{%1, %0|%0, %1}"
14669   [(set_attr "type" "alu1")
14670    (set_attr "prefix_0f" "1")
14671    (set_attr "mode" "HI")])
14672
14673 (define_expand "paritydi2"
14674   [(set (match_operand:DI 0 "register_operand" "")
14675         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14676   "! TARGET_POPCNT"
14677 {
14678   rtx scratch = gen_reg_rtx (QImode);
14679   rtx cond;
14680
14681   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14682                                 NULL_RTX, operands[1]));
14683
14684   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14685                          gen_rtx_REG (CCmode, FLAGS_REG),
14686                          const0_rtx);
14687   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14688
14689   if (TARGET_64BIT)
14690     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14691   else
14692     {
14693       rtx tmp = gen_reg_rtx (SImode);
14694
14695       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14696       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14697     }
14698   DONE;
14699 })
14700
14701 (define_insn_and_split "paritydi2_cmp"
14702   [(set (reg:CC FLAGS_REG)
14703         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14704    (clobber (match_scratch:DI 0 "=r"))
14705    (clobber (match_scratch:SI 1 "=&r"))
14706    (clobber (match_scratch:HI 2 "=Q"))]
14707   "! TARGET_POPCNT"
14708   "#"
14709   "&& reload_completed"
14710   [(parallel
14711      [(set (match_dup 1)
14712            (xor:SI (match_dup 1) (match_dup 4)))
14713       (clobber (reg:CC FLAGS_REG))])
14714    (parallel
14715      [(set (reg:CC FLAGS_REG)
14716            (parity:CC (match_dup 1)))
14717       (clobber (match_dup 1))
14718       (clobber (match_dup 2))])]
14719 {
14720   operands[4] = gen_lowpart (SImode, operands[3]);
14721
14722   if (TARGET_64BIT)
14723     {
14724       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14725       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14726     }
14727   else
14728     operands[1] = gen_highpart (SImode, operands[3]);
14729 })
14730
14731 (define_expand "paritysi2"
14732   [(set (match_operand:SI 0 "register_operand" "")
14733         (parity:SI (match_operand:SI 1 "register_operand" "")))]
14734   "! TARGET_POPCNT"
14735 {
14736   rtx scratch = gen_reg_rtx (QImode);
14737   rtx cond;
14738
14739   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14740
14741   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14742                          gen_rtx_REG (CCmode, FLAGS_REG),
14743                          const0_rtx);
14744   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14745
14746   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14747   DONE;
14748 })
14749
14750 (define_insn_and_split "paritysi2_cmp"
14751   [(set (reg:CC FLAGS_REG)
14752         (parity:CC (match_operand:SI 2 "register_operand" "0")))
14753    (clobber (match_scratch:SI 0 "=r"))
14754    (clobber (match_scratch:HI 1 "=&Q"))]
14755   "! TARGET_POPCNT"
14756   "#"
14757   "&& reload_completed"
14758   [(parallel
14759      [(set (match_dup 1)
14760            (xor:HI (match_dup 1) (match_dup 3)))
14761       (clobber (reg:CC FLAGS_REG))])
14762    (parallel
14763      [(set (reg:CC FLAGS_REG)
14764            (parity:CC (match_dup 1)))
14765       (clobber (match_dup 1))])]
14766 {
14767   operands[3] = gen_lowpart (HImode, operands[2]);
14768
14769   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14770   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14771 })
14772
14773 (define_insn "*parityhi2_cmp"
14774   [(set (reg:CC FLAGS_REG)
14775         (parity:CC (match_operand:HI 1 "register_operand" "0")))
14776    (clobber (match_scratch:HI 0 "=Q"))]
14777   "! TARGET_POPCNT"
14778   "xor{b}\t{%h0, %b0|%b0, %h0}"
14779   [(set_attr "length" "2")
14780    (set_attr "mode" "HI")])
14781
14782 (define_insn "*parityqi2_cmp"
14783   [(set (reg:CC FLAGS_REG)
14784         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14785   "! TARGET_POPCNT"
14786   "test{b}\t%0, %0"
14787   [(set_attr "length" "2")
14788    (set_attr "mode" "QI")])
14789 \f
14790 ;; Thread-local storage patterns for ELF.
14791 ;;
14792 ;; Note that these code sequences must appear exactly as shown
14793 ;; in order to allow linker relaxation.
14794
14795 (define_insn "*tls_global_dynamic_32_gnu"
14796   [(set (match_operand:SI 0 "register_operand" "=a")
14797         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14798                     (match_operand:SI 2 "tls_symbolic_operand" "")
14799                     (match_operand:SI 3 "call_insn_operand" "")]
14800                     UNSPEC_TLS_GD))
14801    (clobber (match_scratch:SI 4 "=d"))
14802    (clobber (match_scratch:SI 5 "=c"))
14803    (clobber (reg:CC FLAGS_REG))]
14804   "!TARGET_64BIT && TARGET_GNU_TLS"
14805   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14806   [(set_attr "type" "multi")
14807    (set_attr "length" "12")])
14808
14809 (define_insn "*tls_global_dynamic_32_sun"
14810   [(set (match_operand:SI 0 "register_operand" "=a")
14811         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14812                     (match_operand:SI 2 "tls_symbolic_operand" "")
14813                     (match_operand:SI 3 "call_insn_operand" "")]
14814                     UNSPEC_TLS_GD))
14815    (clobber (match_scratch:SI 4 "=d"))
14816    (clobber (match_scratch:SI 5 "=c"))
14817    (clobber (reg:CC FLAGS_REG))]
14818   "!TARGET_64BIT && TARGET_SUN_TLS"
14819   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14820         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14821   [(set_attr "type" "multi")
14822    (set_attr "length" "14")])
14823
14824 (define_expand "tls_global_dynamic_32"
14825   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14826                    (unspec:SI
14827                     [(match_dup 2)
14828                      (match_operand:SI 1 "tls_symbolic_operand" "")
14829                      (match_dup 3)]
14830                     UNSPEC_TLS_GD))
14831               (clobber (match_scratch:SI 4 ""))
14832               (clobber (match_scratch:SI 5 ""))
14833               (clobber (reg:CC FLAGS_REG))])]
14834   ""
14835 {
14836   if (flag_pic)
14837     operands[2] = pic_offset_table_rtx;
14838   else
14839     {
14840       operands[2] = gen_reg_rtx (Pmode);
14841       emit_insn (gen_set_got (operands[2]));
14842     }
14843   if (TARGET_GNU2_TLS)
14844     {
14845        emit_insn (gen_tls_dynamic_gnu2_32
14846                   (operands[0], operands[1], operands[2]));
14847        DONE;
14848     }
14849   operands[3] = ix86_tls_get_addr ();
14850 })
14851
14852 (define_insn "*tls_global_dynamic_64"
14853   [(set (match_operand:DI 0 "register_operand" "=a")
14854         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14855                  (match_operand:DI 3 "" "")))
14856    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14857               UNSPEC_TLS_GD)]
14858   "TARGET_64BIT"
14859   { 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"; }
14860   [(set_attr "type" "multi")
14861    (set_attr "length" "16")])
14862
14863 (define_expand "tls_global_dynamic_64"
14864   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14865                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14866               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14867                          UNSPEC_TLS_GD)])]
14868   ""
14869 {
14870   if (TARGET_GNU2_TLS)
14871     {
14872        emit_insn (gen_tls_dynamic_gnu2_64
14873                   (operands[0], operands[1]));
14874        DONE;
14875     }
14876   operands[2] = ix86_tls_get_addr ();
14877 })
14878
14879 (define_insn "*tls_local_dynamic_base_32_gnu"
14880   [(set (match_operand:SI 0 "register_operand" "=a")
14881         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14882                     (match_operand:SI 2 "call_insn_operand" "")]
14883                    UNSPEC_TLS_LD_BASE))
14884    (clobber (match_scratch:SI 3 "=d"))
14885    (clobber (match_scratch:SI 4 "=c"))
14886    (clobber (reg:CC FLAGS_REG))]
14887   "!TARGET_64BIT && TARGET_GNU_TLS"
14888   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14889   [(set_attr "type" "multi")
14890    (set_attr "length" "11")])
14891
14892 (define_insn "*tls_local_dynamic_base_32_sun"
14893   [(set (match_operand:SI 0 "register_operand" "=a")
14894         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14895                     (match_operand:SI 2 "call_insn_operand" "")]
14896                    UNSPEC_TLS_LD_BASE))
14897    (clobber (match_scratch:SI 3 "=d"))
14898    (clobber (match_scratch:SI 4 "=c"))
14899    (clobber (reg:CC FLAGS_REG))]
14900   "!TARGET_64BIT && TARGET_SUN_TLS"
14901   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14902         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14903   [(set_attr "type" "multi")
14904    (set_attr "length" "13")])
14905
14906 (define_expand "tls_local_dynamic_base_32"
14907   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14908                    (unspec:SI [(match_dup 1) (match_dup 2)]
14909                               UNSPEC_TLS_LD_BASE))
14910               (clobber (match_scratch:SI 3 ""))
14911               (clobber (match_scratch:SI 4 ""))
14912               (clobber (reg:CC FLAGS_REG))])]
14913   ""
14914 {
14915   if (flag_pic)
14916     operands[1] = pic_offset_table_rtx;
14917   else
14918     {
14919       operands[1] = gen_reg_rtx (Pmode);
14920       emit_insn (gen_set_got (operands[1]));
14921     }
14922   if (TARGET_GNU2_TLS)
14923     {
14924        emit_insn (gen_tls_dynamic_gnu2_32
14925                   (operands[0], ix86_tls_module_base (), operands[1]));
14926        DONE;
14927     }
14928   operands[2] = ix86_tls_get_addr ();
14929 })
14930
14931 (define_insn "*tls_local_dynamic_base_64"
14932   [(set (match_operand:DI 0 "register_operand" "=a")
14933         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14934                  (match_operand:DI 2 "" "")))
14935    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14936   "TARGET_64BIT"
14937   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
14938   [(set_attr "type" "multi")
14939    (set_attr "length" "12")])
14940
14941 (define_expand "tls_local_dynamic_base_64"
14942   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14943                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14944               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14945   ""
14946 {
14947   if (TARGET_GNU2_TLS)
14948     {
14949        emit_insn (gen_tls_dynamic_gnu2_64
14950                   (operands[0], ix86_tls_module_base ()));
14951        DONE;
14952     }
14953   operands[1] = ix86_tls_get_addr ();
14954 })
14955
14956 ;; Local dynamic of a single variable is a lose.  Show combine how
14957 ;; to convert that back to global dynamic.
14958
14959 (define_insn_and_split "*tls_local_dynamic_32_once"
14960   [(set (match_operand:SI 0 "register_operand" "=a")
14961         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14962                              (match_operand:SI 2 "call_insn_operand" "")]
14963                             UNSPEC_TLS_LD_BASE)
14964                  (const:SI (unspec:SI
14965                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14966                             UNSPEC_DTPOFF))))
14967    (clobber (match_scratch:SI 4 "=d"))
14968    (clobber (match_scratch:SI 5 "=c"))
14969    (clobber (reg:CC FLAGS_REG))]
14970   ""
14971   "#"
14972   ""
14973   [(parallel [(set (match_dup 0)
14974                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14975                               UNSPEC_TLS_GD))
14976               (clobber (match_dup 4))
14977               (clobber (match_dup 5))
14978               (clobber (reg:CC FLAGS_REG))])]
14979   "")
14980
14981 ;; Load and add the thread base pointer from %gs:0.
14982
14983 (define_insn "*load_tp_si"
14984   [(set (match_operand:SI 0 "register_operand" "=r")
14985         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14986   "!TARGET_64BIT"
14987   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14988   [(set_attr "type" "imov")
14989    (set_attr "modrm" "0")
14990    (set_attr "length" "7")
14991    (set_attr "memory" "load")
14992    (set_attr "imm_disp" "false")])
14993
14994 (define_insn "*add_tp_si"
14995   [(set (match_operand:SI 0 "register_operand" "=r")
14996         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14997                  (match_operand:SI 1 "register_operand" "0")))
14998    (clobber (reg:CC FLAGS_REG))]
14999   "!TARGET_64BIT"
15000   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15001   [(set_attr "type" "alu")
15002    (set_attr "modrm" "0")
15003    (set_attr "length" "7")
15004    (set_attr "memory" "load")
15005    (set_attr "imm_disp" "false")])
15006
15007 (define_insn "*load_tp_di"
15008   [(set (match_operand:DI 0 "register_operand" "=r")
15009         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15010   "TARGET_64BIT"
15011   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15012   [(set_attr "type" "imov")
15013    (set_attr "modrm" "0")
15014    (set_attr "length" "7")
15015    (set_attr "memory" "load")
15016    (set_attr "imm_disp" "false")])
15017
15018 (define_insn "*add_tp_di"
15019   [(set (match_operand:DI 0 "register_operand" "=r")
15020         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15021                  (match_operand:DI 1 "register_operand" "0")))
15022    (clobber (reg:CC FLAGS_REG))]
15023   "TARGET_64BIT"
15024   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15025   [(set_attr "type" "alu")
15026    (set_attr "modrm" "0")
15027    (set_attr "length" "7")
15028    (set_attr "memory" "load")
15029    (set_attr "imm_disp" "false")])
15030
15031 ;; GNU2 TLS patterns can be split.
15032
15033 (define_expand "tls_dynamic_gnu2_32"
15034   [(set (match_dup 3)
15035         (plus:SI (match_operand:SI 2 "register_operand" "")
15036                  (const:SI
15037                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15038                              UNSPEC_TLSDESC))))
15039    (parallel
15040     [(set (match_operand:SI 0 "register_operand" "")
15041           (unspec:SI [(match_dup 1) (match_dup 3)
15042                       (match_dup 2) (reg:SI SP_REG)]
15043                       UNSPEC_TLSDESC))
15044      (clobber (reg:CC FLAGS_REG))])]
15045   "!TARGET_64BIT && TARGET_GNU2_TLS"
15046 {
15047   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15048   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15049 })
15050
15051 (define_insn "*tls_dynamic_lea_32"
15052   [(set (match_operand:SI 0 "register_operand" "=r")
15053         (plus:SI (match_operand:SI 1 "register_operand" "b")
15054                  (const:SI
15055                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15056                               UNSPEC_TLSDESC))))]
15057   "!TARGET_64BIT && TARGET_GNU2_TLS"
15058   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15059   [(set_attr "type" "lea")
15060    (set_attr "mode" "SI")
15061    (set_attr "length" "6")
15062    (set_attr "length_address" "4")])
15063
15064 (define_insn "*tls_dynamic_call_32"
15065   [(set (match_operand:SI 0 "register_operand" "=a")
15066         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15067                     (match_operand:SI 2 "register_operand" "0")
15068                     ;; we have to make sure %ebx still points to the GOT
15069                     (match_operand:SI 3 "register_operand" "b")
15070                     (reg:SI SP_REG)]
15071                    UNSPEC_TLSDESC))
15072    (clobber (reg:CC FLAGS_REG))]
15073   "!TARGET_64BIT && TARGET_GNU2_TLS"
15074   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15075   [(set_attr "type" "call")
15076    (set_attr "length" "2")
15077    (set_attr "length_address" "0")])
15078
15079 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15080   [(set (match_operand:SI 0 "register_operand" "=&a")
15081         (plus:SI
15082          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15083                      (match_operand:SI 4 "" "")
15084                      (match_operand:SI 2 "register_operand" "b")
15085                      (reg:SI SP_REG)]
15086                     UNSPEC_TLSDESC)
15087          (const:SI (unspec:SI
15088                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15089                     UNSPEC_DTPOFF))))
15090    (clobber (reg:CC FLAGS_REG))]
15091   "!TARGET_64BIT && TARGET_GNU2_TLS"
15092   "#"
15093   ""
15094   [(set (match_dup 0) (match_dup 5))]
15095 {
15096   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15097   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15098 })
15099
15100 (define_expand "tls_dynamic_gnu2_64"
15101   [(set (match_dup 2)
15102         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15103                    UNSPEC_TLSDESC))
15104    (parallel
15105     [(set (match_operand:DI 0 "register_operand" "")
15106           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15107                      UNSPEC_TLSDESC))
15108      (clobber (reg:CC FLAGS_REG))])]
15109   "TARGET_64BIT && TARGET_GNU2_TLS"
15110 {
15111   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15112   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15113 })
15114
15115 (define_insn "*tls_dynamic_lea_64"
15116   [(set (match_operand:DI 0 "register_operand" "=r")
15117         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15118                    UNSPEC_TLSDESC))]
15119   "TARGET_64BIT && TARGET_GNU2_TLS"
15120   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15121   [(set_attr "type" "lea")
15122    (set_attr "mode" "DI")
15123    (set_attr "length" "7")
15124    (set_attr "length_address" "4")])
15125
15126 (define_insn "*tls_dynamic_call_64"
15127   [(set (match_operand:DI 0 "register_operand" "=a")
15128         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15129                     (match_operand:DI 2 "register_operand" "0")
15130                     (reg:DI SP_REG)]
15131                    UNSPEC_TLSDESC))
15132    (clobber (reg:CC FLAGS_REG))]
15133   "TARGET_64BIT && TARGET_GNU2_TLS"
15134   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15135   [(set_attr "type" "call")
15136    (set_attr "length" "2")
15137    (set_attr "length_address" "0")])
15138
15139 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15140   [(set (match_operand:DI 0 "register_operand" "=&a")
15141         (plus:DI
15142          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15143                      (match_operand:DI 3 "" "")
15144                      (reg:DI SP_REG)]
15145                     UNSPEC_TLSDESC)
15146          (const:DI (unspec:DI
15147                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15148                     UNSPEC_DTPOFF))))
15149    (clobber (reg:CC FLAGS_REG))]
15150   "TARGET_64BIT && TARGET_GNU2_TLS"
15151   "#"
15152   ""
15153   [(set (match_dup 0) (match_dup 4))]
15154 {
15155   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15156   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15157 })
15158
15159 ;;
15160 \f
15161 ;; These patterns match the binary 387 instructions for addM3, subM3,
15162 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15163 ;; SFmode.  The first is the normal insn, the second the same insn but
15164 ;; with one operand a conversion, and the third the same insn but with
15165 ;; the other operand a conversion.  The conversion may be SFmode or
15166 ;; SImode if the target mode DFmode, but only SImode if the target mode
15167 ;; is SFmode.
15168
15169 ;; Gcc is slightly more smart about handling normal two address instructions
15170 ;; so use special patterns for add and mull.
15171
15172 (define_insn "*fop_<mode>_comm_mixed_avx"
15173   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15174         (match_operator:MODEF 3 "binary_fp_operator"
15175           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15176            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15177   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15178    && COMMUTATIVE_ARITH_P (operands[3])
15179    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15180   "* return output_387_binary_op (insn, operands);"
15181   [(set (attr "type")
15182         (if_then_else (eq_attr "alternative" "1")
15183            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15184               (const_string "ssemul")
15185               (const_string "sseadd"))
15186            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15187               (const_string "fmul")
15188               (const_string "fop"))))
15189    (set_attr "prefix" "orig,maybe_vex")
15190    (set_attr "mode" "<MODE>")])
15191
15192 (define_insn "*fop_<mode>_comm_mixed"
15193   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15194         (match_operator:MODEF 3 "binary_fp_operator"
15195           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15196            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15197   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15198    && COMMUTATIVE_ARITH_P (operands[3])
15199    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15200   "* return output_387_binary_op (insn, operands);"
15201   [(set (attr "type")
15202         (if_then_else (eq_attr "alternative" "1")
15203            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15204               (const_string "ssemul")
15205               (const_string "sseadd"))
15206            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15207               (const_string "fmul")
15208               (const_string "fop"))))
15209    (set_attr "mode" "<MODE>")])
15210
15211 (define_insn "*fop_<mode>_comm_avx"
15212   [(set (match_operand:MODEF 0 "register_operand" "=x")
15213         (match_operator:MODEF 3 "binary_fp_operator"
15214           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15215            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15216   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15217    && COMMUTATIVE_ARITH_P (operands[3])
15218    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15219   "* return output_387_binary_op (insn, operands);"
15220   [(set (attr "type")
15221         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15222            (const_string "ssemul")
15223            (const_string "sseadd")))
15224    (set_attr "prefix" "vex")
15225    (set_attr "mode" "<MODE>")])
15226
15227 (define_insn "*fop_<mode>_comm_sse"
15228   [(set (match_operand:MODEF 0 "register_operand" "=x")
15229         (match_operator:MODEF 3 "binary_fp_operator"
15230           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15231            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15232   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15233    && COMMUTATIVE_ARITH_P (operands[3])
15234    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15235   "* return output_387_binary_op (insn, operands);"
15236   [(set (attr "type")
15237         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15238            (const_string "ssemul")
15239            (const_string "sseadd")))
15240    (set_attr "mode" "<MODE>")])
15241
15242 (define_insn "*fop_<mode>_comm_i387"
15243   [(set (match_operand:MODEF 0 "register_operand" "=f")
15244         (match_operator:MODEF 3 "binary_fp_operator"
15245           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15246            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15247   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15248    && COMMUTATIVE_ARITH_P (operands[3])
15249    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15250   "* return output_387_binary_op (insn, operands);"
15251   [(set (attr "type")
15252         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15253            (const_string "fmul")
15254            (const_string "fop")))
15255    (set_attr "mode" "<MODE>")])
15256
15257 (define_insn "*fop_<mode>_1_mixed_avx"
15258   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15259         (match_operator:MODEF 3 "binary_fp_operator"
15260           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15261            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15262   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15263    && !COMMUTATIVE_ARITH_P (operands[3])
15264    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15265   "* return output_387_binary_op (insn, operands);"
15266   [(set (attr "type")
15267         (cond [(and (eq_attr "alternative" "2")
15268                     (match_operand:MODEF 3 "mult_operator" ""))
15269                  (const_string "ssemul")
15270                (and (eq_attr "alternative" "2")
15271                     (match_operand:MODEF 3 "div_operator" ""))
15272                  (const_string "ssediv")
15273                (eq_attr "alternative" "2")
15274                  (const_string "sseadd")
15275                (match_operand:MODEF 3 "mult_operator" "")
15276                  (const_string "fmul")
15277                (match_operand:MODEF 3 "div_operator" "")
15278                  (const_string "fdiv")
15279               ]
15280               (const_string "fop")))
15281    (set_attr "prefix" "orig,orig,maybe_vex")
15282    (set_attr "mode" "<MODE>")])
15283
15284 (define_insn "*fop_<mode>_1_mixed"
15285   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15286         (match_operator:MODEF 3 "binary_fp_operator"
15287           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15288            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15289   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15290    && !COMMUTATIVE_ARITH_P (operands[3])
15291    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15292   "* return output_387_binary_op (insn, operands);"
15293   [(set (attr "type")
15294         (cond [(and (eq_attr "alternative" "2")
15295                     (match_operand:MODEF 3 "mult_operator" ""))
15296                  (const_string "ssemul")
15297                (and (eq_attr "alternative" "2")
15298                     (match_operand:MODEF 3 "div_operator" ""))
15299                  (const_string "ssediv")
15300                (eq_attr "alternative" "2")
15301                  (const_string "sseadd")
15302                (match_operand:MODEF 3 "mult_operator" "")
15303                  (const_string "fmul")
15304                (match_operand:MODEF 3 "div_operator" "")
15305                  (const_string "fdiv")
15306               ]
15307               (const_string "fop")))
15308    (set_attr "mode" "<MODE>")])
15309
15310 (define_insn "*rcpsf2_sse"
15311   [(set (match_operand:SF 0 "register_operand" "=x")
15312         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15313                    UNSPEC_RCP))]
15314   "TARGET_SSE_MATH"
15315   "%vrcpss\t{%1, %d0|%d0, %1}"
15316   [(set_attr "type" "sse")
15317    (set_attr "atom_sse_attr" "rcp")
15318    (set_attr "prefix" "maybe_vex")
15319    (set_attr "mode" "SF")])
15320
15321 (define_insn "*fop_<mode>_1_avx"
15322   [(set (match_operand:MODEF 0 "register_operand" "=x")
15323         (match_operator:MODEF 3 "binary_fp_operator"
15324           [(match_operand:MODEF 1 "register_operand" "x")
15325            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15326   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15327    && !COMMUTATIVE_ARITH_P (operands[3])"
15328   "* return output_387_binary_op (insn, operands);"
15329   [(set (attr "type")
15330         (cond [(match_operand:MODEF 3 "mult_operator" "")
15331                  (const_string "ssemul")
15332                (match_operand:MODEF 3 "div_operator" "")
15333                  (const_string "ssediv")
15334               ]
15335               (const_string "sseadd")))
15336    (set_attr "prefix" "vex")
15337    (set_attr "mode" "<MODE>")])
15338
15339 (define_insn "*fop_<mode>_1_sse"
15340   [(set (match_operand:MODEF 0 "register_operand" "=x")
15341         (match_operator:MODEF 3 "binary_fp_operator"
15342           [(match_operand:MODEF 1 "register_operand" "0")
15343            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15344   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15345    && !COMMUTATIVE_ARITH_P (operands[3])"
15346   "* return output_387_binary_op (insn, operands);"
15347   [(set (attr "type")
15348         (cond [(match_operand:MODEF 3 "mult_operator" "")
15349                  (const_string "ssemul")
15350                (match_operand:MODEF 3 "div_operator" "")
15351                  (const_string "ssediv")
15352               ]
15353               (const_string "sseadd")))
15354    (set_attr "mode" "<MODE>")])
15355
15356 ;; This pattern is not fully shadowed by the pattern above.
15357 (define_insn "*fop_<mode>_1_i387"
15358   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15359         (match_operator:MODEF 3 "binary_fp_operator"
15360           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15361            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15362   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15363    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15364    && !COMMUTATIVE_ARITH_P (operands[3])
15365    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15366   "* return output_387_binary_op (insn, operands);"
15367   [(set (attr "type")
15368         (cond [(match_operand:MODEF 3 "mult_operator" "")
15369                  (const_string "fmul")
15370                (match_operand:MODEF 3 "div_operator" "")
15371                  (const_string "fdiv")
15372               ]
15373               (const_string "fop")))
15374    (set_attr "mode" "<MODE>")])
15375
15376 ;; ??? Add SSE splitters for these!
15377 (define_insn "*fop_<MODEF:mode>_2_i387"
15378   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15379         (match_operator:MODEF 3 "binary_fp_operator"
15380           [(float:MODEF
15381              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15382            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15383   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15384    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15385    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15386   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15387   [(set (attr "type")
15388         (cond [(match_operand:MODEF 3 "mult_operator" "")
15389                  (const_string "fmul")
15390                (match_operand:MODEF 3 "div_operator" "")
15391                  (const_string "fdiv")
15392               ]
15393               (const_string "fop")))
15394    (set_attr "fp_int_src" "true")
15395    (set_attr "mode" "<X87MODEI12:MODE>")])
15396
15397 (define_insn "*fop_<MODEF:mode>_3_i387"
15398   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15399         (match_operator:MODEF 3 "binary_fp_operator"
15400           [(match_operand:MODEF 1 "register_operand" "0,0")
15401            (float:MODEF
15402              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15403   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15404    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15405    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15406   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15407   [(set (attr "type")
15408         (cond [(match_operand:MODEF 3 "mult_operator" "")
15409                  (const_string "fmul")
15410                (match_operand:MODEF 3 "div_operator" "")
15411                  (const_string "fdiv")
15412               ]
15413               (const_string "fop")))
15414    (set_attr "fp_int_src" "true")
15415    (set_attr "mode" "<MODE>")])
15416
15417 (define_insn "*fop_df_4_i387"
15418   [(set (match_operand:DF 0 "register_operand" "=f,f")
15419         (match_operator:DF 3 "binary_fp_operator"
15420            [(float_extend:DF
15421              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15422             (match_operand:DF 2 "register_operand" "0,f")]))]
15423   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15424    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15425    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15426   "* return output_387_binary_op (insn, operands);"
15427   [(set (attr "type")
15428         (cond [(match_operand:DF 3 "mult_operator" "")
15429                  (const_string "fmul")
15430                (match_operand:DF 3 "div_operator" "")
15431                  (const_string "fdiv")
15432               ]
15433               (const_string "fop")))
15434    (set_attr "mode" "SF")])
15435
15436 (define_insn "*fop_df_5_i387"
15437   [(set (match_operand:DF 0 "register_operand" "=f,f")
15438         (match_operator:DF 3 "binary_fp_operator"
15439           [(match_operand:DF 1 "register_operand" "0,f")
15440            (float_extend:DF
15441             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15442   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15443    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15444   "* return output_387_binary_op (insn, operands);"
15445   [(set (attr "type")
15446         (cond [(match_operand:DF 3 "mult_operator" "")
15447                  (const_string "fmul")
15448                (match_operand:DF 3 "div_operator" "")
15449                  (const_string "fdiv")
15450               ]
15451               (const_string "fop")))
15452    (set_attr "mode" "SF")])
15453
15454 (define_insn "*fop_df_6_i387"
15455   [(set (match_operand:DF 0 "register_operand" "=f,f")
15456         (match_operator:DF 3 "binary_fp_operator"
15457           [(float_extend:DF
15458             (match_operand:SF 1 "register_operand" "0,f"))
15459            (float_extend:DF
15460             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15461   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15462    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15463   "* return output_387_binary_op (insn, operands);"
15464   [(set (attr "type")
15465         (cond [(match_operand:DF 3 "mult_operator" "")
15466                  (const_string "fmul")
15467                (match_operand:DF 3 "div_operator" "")
15468                  (const_string "fdiv")
15469               ]
15470               (const_string "fop")))
15471    (set_attr "mode" "SF")])
15472
15473 (define_insn "*fop_xf_comm_i387"
15474   [(set (match_operand:XF 0 "register_operand" "=f")
15475         (match_operator:XF 3 "binary_fp_operator"
15476                         [(match_operand:XF 1 "register_operand" "%0")
15477                          (match_operand:XF 2 "register_operand" "f")]))]
15478   "TARGET_80387
15479    && COMMUTATIVE_ARITH_P (operands[3])"
15480   "* return output_387_binary_op (insn, operands);"
15481   [(set (attr "type")
15482         (if_then_else (match_operand:XF 3 "mult_operator" "")
15483            (const_string "fmul")
15484            (const_string "fop")))
15485    (set_attr "mode" "XF")])
15486
15487 (define_insn "*fop_xf_1_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f,f")
15489         (match_operator:XF 3 "binary_fp_operator"
15490                         [(match_operand:XF 1 "register_operand" "0,f")
15491                          (match_operand:XF 2 "register_operand" "f,0")]))]
15492   "TARGET_80387
15493    && !COMMUTATIVE_ARITH_P (operands[3])"
15494   "* return output_387_binary_op (insn, operands);"
15495   [(set (attr "type")
15496         (cond [(match_operand:XF 3 "mult_operator" "")
15497                  (const_string "fmul")
15498                (match_operand:XF 3 "div_operator" "")
15499                  (const_string "fdiv")
15500               ]
15501               (const_string "fop")))
15502    (set_attr "mode" "XF")])
15503
15504 (define_insn "*fop_xf_2_i387"
15505   [(set (match_operand:XF 0 "register_operand" "=f,f")
15506         (match_operator:XF 3 "binary_fp_operator"
15507           [(float:XF
15508              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15509            (match_operand:XF 2 "register_operand" "0,0")]))]
15510   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15511   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15512   [(set (attr "type")
15513         (cond [(match_operand:XF 3 "mult_operator" "")
15514                  (const_string "fmul")
15515                (match_operand:XF 3 "div_operator" "")
15516                  (const_string "fdiv")
15517               ]
15518               (const_string "fop")))
15519    (set_attr "fp_int_src" "true")
15520    (set_attr "mode" "<MODE>")])
15521
15522 (define_insn "*fop_xf_3_i387"
15523   [(set (match_operand:XF 0 "register_operand" "=f,f")
15524         (match_operator:XF 3 "binary_fp_operator"
15525           [(match_operand:XF 1 "register_operand" "0,0")
15526            (float:XF
15527              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15528   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15529   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15530   [(set (attr "type")
15531         (cond [(match_operand:XF 3 "mult_operator" "")
15532                  (const_string "fmul")
15533                (match_operand:XF 3 "div_operator" "")
15534                  (const_string "fdiv")
15535               ]
15536               (const_string "fop")))
15537    (set_attr "fp_int_src" "true")
15538    (set_attr "mode" "<MODE>")])
15539
15540 (define_insn "*fop_xf_4_i387"
15541   [(set (match_operand:XF 0 "register_operand" "=f,f")
15542         (match_operator:XF 3 "binary_fp_operator"
15543            [(float_extend:XF
15544               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15545             (match_operand:XF 2 "register_operand" "0,f")]))]
15546   "TARGET_80387"
15547   "* return output_387_binary_op (insn, operands);"
15548   [(set (attr "type")
15549         (cond [(match_operand:XF 3 "mult_operator" "")
15550                  (const_string "fmul")
15551                (match_operand:XF 3 "div_operator" "")
15552                  (const_string "fdiv")
15553               ]
15554               (const_string "fop")))
15555    (set_attr "mode" "<MODE>")])
15556
15557 (define_insn "*fop_xf_5_i387"
15558   [(set (match_operand:XF 0 "register_operand" "=f,f")
15559         (match_operator:XF 3 "binary_fp_operator"
15560           [(match_operand:XF 1 "register_operand" "0,f")
15561            (float_extend:XF
15562              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15563   "TARGET_80387"
15564   "* return output_387_binary_op (insn, operands);"
15565   [(set (attr "type")
15566         (cond [(match_operand:XF 3 "mult_operator" "")
15567                  (const_string "fmul")
15568                (match_operand:XF 3 "div_operator" "")
15569                  (const_string "fdiv")
15570               ]
15571               (const_string "fop")))
15572    (set_attr "mode" "<MODE>")])
15573
15574 (define_insn "*fop_xf_6_i387"
15575   [(set (match_operand:XF 0 "register_operand" "=f,f")
15576         (match_operator:XF 3 "binary_fp_operator"
15577           [(float_extend:XF
15578              (match_operand:MODEF 1 "register_operand" "0,f"))
15579            (float_extend:XF
15580              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15581   "TARGET_80387"
15582   "* return output_387_binary_op (insn, operands);"
15583   [(set (attr "type")
15584         (cond [(match_operand:XF 3 "mult_operator" "")
15585                  (const_string "fmul")
15586                (match_operand:XF 3 "div_operator" "")
15587                  (const_string "fdiv")
15588               ]
15589               (const_string "fop")))
15590    (set_attr "mode" "<MODE>")])
15591
15592 (define_split
15593   [(set (match_operand 0 "register_operand" "")
15594         (match_operator 3 "binary_fp_operator"
15595            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15596             (match_operand 2 "register_operand" "")]))]
15597   "reload_completed
15598    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15599    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15600   [(const_int 0)]
15601 {
15602   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15603   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15604   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15605                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15606                                           GET_MODE (operands[3]),
15607                                           operands[4],
15608                                           operands[2])));
15609   ix86_free_from_memory (GET_MODE (operands[1]));
15610   DONE;
15611 })
15612
15613 (define_split
15614   [(set (match_operand 0 "register_operand" "")
15615         (match_operator 3 "binary_fp_operator"
15616            [(match_operand 1 "register_operand" "")
15617             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15618   "reload_completed
15619    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15620    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15621   [(const_int 0)]
15622 {
15623   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15624   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15625   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15626                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15627                                           GET_MODE (operands[3]),
15628                                           operands[1],
15629                                           operands[4])));
15630   ix86_free_from_memory (GET_MODE (operands[2]));
15631   DONE;
15632 })
15633 \f
15634 ;; FPU special functions.
15635
15636 ;; This pattern implements a no-op XFmode truncation for
15637 ;; all fancy i386 XFmode math functions.
15638
15639 (define_insn "truncxf<mode>2_i387_noop_unspec"
15640   [(set (match_operand:MODEF 0 "register_operand" "=f")
15641         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15642         UNSPEC_TRUNC_NOOP))]
15643   "TARGET_USE_FANCY_MATH_387"
15644   "* return output_387_reg_move (insn, operands);"
15645   [(set_attr "type" "fmov")
15646    (set_attr "mode" "<MODE>")])
15647
15648 (define_insn "sqrtxf2"
15649   [(set (match_operand:XF 0 "register_operand" "=f")
15650         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15651   "TARGET_USE_FANCY_MATH_387"
15652   "fsqrt"
15653   [(set_attr "type" "fpspc")
15654    (set_attr "mode" "XF")
15655    (set_attr "athlon_decode" "direct")
15656    (set_attr "amdfam10_decode" "direct")])
15657
15658 (define_insn "sqrt_extend<mode>xf2_i387"
15659   [(set (match_operand:XF 0 "register_operand" "=f")
15660         (sqrt:XF
15661           (float_extend:XF
15662             (match_operand:MODEF 1 "register_operand" "0"))))]
15663   "TARGET_USE_FANCY_MATH_387"
15664   "fsqrt"
15665   [(set_attr "type" "fpspc")
15666    (set_attr "mode" "XF")
15667    (set_attr "athlon_decode" "direct")
15668    (set_attr "amdfam10_decode" "direct")])
15669
15670 (define_insn "*rsqrtsf2_sse"
15671   [(set (match_operand:SF 0 "register_operand" "=x")
15672         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15673                    UNSPEC_RSQRT))]
15674   "TARGET_SSE_MATH"
15675   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15676   [(set_attr "type" "sse")
15677    (set_attr "atom_sse_attr" "rcp")
15678    (set_attr "prefix" "maybe_vex")
15679    (set_attr "mode" "SF")])
15680
15681 (define_expand "rsqrtsf2"
15682   [(set (match_operand:SF 0 "register_operand" "")
15683         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15684                    UNSPEC_RSQRT))]
15685   "TARGET_SSE_MATH"
15686 {
15687   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15688   DONE;
15689 })
15690
15691 (define_insn "*sqrt<mode>2_sse"
15692   [(set (match_operand:MODEF 0 "register_operand" "=x")
15693         (sqrt:MODEF
15694           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15695   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15696   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15697   [(set_attr "type" "sse")
15698    (set_attr "atom_sse_attr" "sqrt")
15699    (set_attr "prefix" "maybe_vex")
15700    (set_attr "mode" "<MODE>")
15701    (set_attr "athlon_decode" "*")
15702    (set_attr "amdfam10_decode" "*")])
15703
15704 (define_expand "sqrt<mode>2"
15705   [(set (match_operand:MODEF 0 "register_operand" "")
15706         (sqrt:MODEF
15707           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15708   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15709    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15710 {
15711   if (<MODE>mode == SFmode
15712       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15713       && flag_finite_math_only && !flag_trapping_math
15714       && flag_unsafe_math_optimizations)
15715     {
15716       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15717       DONE;
15718     }
15719
15720   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15721     {
15722       rtx op0 = gen_reg_rtx (XFmode);
15723       rtx op1 = force_reg (<MODE>mode, operands[1]);
15724
15725       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15726       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15727       DONE;
15728    }
15729 })
15730
15731 (define_insn "fpremxf4_i387"
15732   [(set (match_operand:XF 0 "register_operand" "=f")
15733         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15734                     (match_operand:XF 3 "register_operand" "1")]
15735                    UNSPEC_FPREM_F))
15736    (set (match_operand:XF 1 "register_operand" "=u")
15737         (unspec:XF [(match_dup 2) (match_dup 3)]
15738                    UNSPEC_FPREM_U))
15739    (set (reg:CCFP FPSR_REG)
15740         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15741                      UNSPEC_C2_FLAG))]
15742   "TARGET_USE_FANCY_MATH_387"
15743   "fprem"
15744   [(set_attr "type" "fpspc")
15745    (set_attr "mode" "XF")])
15746
15747 (define_expand "fmodxf3"
15748   [(use (match_operand:XF 0 "register_operand" ""))
15749    (use (match_operand:XF 1 "general_operand" ""))
15750    (use (match_operand:XF 2 "general_operand" ""))]
15751   "TARGET_USE_FANCY_MATH_387"
15752 {
15753   rtx label = gen_label_rtx ();
15754
15755   rtx op1 = gen_reg_rtx (XFmode);
15756   rtx op2 = gen_reg_rtx (XFmode);
15757
15758   emit_move_insn (op2, operands[2]);
15759   emit_move_insn (op1, operands[1]);
15760
15761   emit_label (label);
15762   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15763   ix86_emit_fp_unordered_jump (label);
15764   LABEL_NUSES (label) = 1;
15765
15766   emit_move_insn (operands[0], op1);
15767   DONE;
15768 })
15769
15770 (define_expand "fmod<mode>3"
15771   [(use (match_operand:MODEF 0 "register_operand" ""))
15772    (use (match_operand:MODEF 1 "general_operand" ""))
15773    (use (match_operand:MODEF 2 "general_operand" ""))]
15774   "TARGET_USE_FANCY_MATH_387"
15775 {
15776   rtx label = gen_label_rtx ();
15777
15778   rtx op1 = gen_reg_rtx (XFmode);
15779   rtx op2 = gen_reg_rtx (XFmode);
15780
15781   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15782   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15783
15784   emit_label (label);
15785   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15786   ix86_emit_fp_unordered_jump (label);
15787   LABEL_NUSES (label) = 1;
15788
15789   /* Truncate the result properly for strict SSE math.  */
15790   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15791       && !TARGET_MIX_SSE_I387)
15792     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15793   else
15794     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15795
15796   DONE;
15797 })
15798
15799 (define_insn "fprem1xf4_i387"
15800   [(set (match_operand:XF 0 "register_operand" "=f")
15801         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15802                     (match_operand:XF 3 "register_operand" "1")]
15803                    UNSPEC_FPREM1_F))
15804    (set (match_operand:XF 1 "register_operand" "=u")
15805         (unspec:XF [(match_dup 2) (match_dup 3)]
15806                    UNSPEC_FPREM1_U))
15807    (set (reg:CCFP FPSR_REG)
15808         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15809                      UNSPEC_C2_FLAG))]
15810   "TARGET_USE_FANCY_MATH_387"
15811   "fprem1"
15812   [(set_attr "type" "fpspc")
15813    (set_attr "mode" "XF")])
15814
15815 (define_expand "remainderxf3"
15816   [(use (match_operand:XF 0 "register_operand" ""))
15817    (use (match_operand:XF 1 "general_operand" ""))
15818    (use (match_operand:XF 2 "general_operand" ""))]
15819   "TARGET_USE_FANCY_MATH_387"
15820 {
15821   rtx label = gen_label_rtx ();
15822
15823   rtx op1 = gen_reg_rtx (XFmode);
15824   rtx op2 = gen_reg_rtx (XFmode);
15825
15826   emit_move_insn (op2, operands[2]);
15827   emit_move_insn (op1, operands[1]);
15828
15829   emit_label (label);
15830   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15831   ix86_emit_fp_unordered_jump (label);
15832   LABEL_NUSES (label) = 1;
15833
15834   emit_move_insn (operands[0], op1);
15835   DONE;
15836 })
15837
15838 (define_expand "remainder<mode>3"
15839   [(use (match_operand:MODEF 0 "register_operand" ""))
15840    (use (match_operand:MODEF 1 "general_operand" ""))
15841    (use (match_operand:MODEF 2 "general_operand" ""))]
15842   "TARGET_USE_FANCY_MATH_387"
15843 {
15844   rtx label = gen_label_rtx ();
15845
15846   rtx op1 = gen_reg_rtx (XFmode);
15847   rtx op2 = gen_reg_rtx (XFmode);
15848
15849   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15850   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15851
15852   emit_label (label);
15853
15854   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15855   ix86_emit_fp_unordered_jump (label);
15856   LABEL_NUSES (label) = 1;
15857
15858   /* Truncate the result properly for strict SSE math.  */
15859   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15860       && !TARGET_MIX_SSE_I387)
15861     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15862   else
15863     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15864
15865   DONE;
15866 })
15867
15868 (define_insn "*sinxf2_i387"
15869   [(set (match_operand:XF 0 "register_operand" "=f")
15870         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15871   "TARGET_USE_FANCY_MATH_387
15872    && flag_unsafe_math_optimizations"
15873   "fsin"
15874   [(set_attr "type" "fpspc")
15875    (set_attr "mode" "XF")])
15876
15877 (define_insn "*sin_extend<mode>xf2_i387"
15878   [(set (match_operand:XF 0 "register_operand" "=f")
15879         (unspec:XF [(float_extend:XF
15880                       (match_operand:MODEF 1 "register_operand" "0"))]
15881                    UNSPEC_SIN))]
15882   "TARGET_USE_FANCY_MATH_387
15883    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15884        || TARGET_MIX_SSE_I387)
15885    && flag_unsafe_math_optimizations"
15886   "fsin"
15887   [(set_attr "type" "fpspc")
15888    (set_attr "mode" "XF")])
15889
15890 (define_insn "*cosxf2_i387"
15891   [(set (match_operand:XF 0 "register_operand" "=f")
15892         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15893   "TARGET_USE_FANCY_MATH_387
15894    && flag_unsafe_math_optimizations"
15895   "fcos"
15896   [(set_attr "type" "fpspc")
15897    (set_attr "mode" "XF")])
15898
15899 (define_insn "*cos_extend<mode>xf2_i387"
15900   [(set (match_operand:XF 0 "register_operand" "=f")
15901         (unspec:XF [(float_extend:XF
15902                       (match_operand:MODEF 1 "register_operand" "0"))]
15903                    UNSPEC_COS))]
15904   "TARGET_USE_FANCY_MATH_387
15905    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15906        || TARGET_MIX_SSE_I387)
15907    && flag_unsafe_math_optimizations"
15908   "fcos"
15909   [(set_attr "type" "fpspc")
15910    (set_attr "mode" "XF")])
15911
15912 ;; When sincos pattern is defined, sin and cos builtin functions will be
15913 ;; expanded to sincos pattern with one of its outputs left unused.
15914 ;; CSE pass will figure out if two sincos patterns can be combined,
15915 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15916 ;; depending on the unused output.
15917
15918 (define_insn "sincosxf3"
15919   [(set (match_operand:XF 0 "register_operand" "=f")
15920         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15921                    UNSPEC_SINCOS_COS))
15922    (set (match_operand:XF 1 "register_operand" "=u")
15923         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15924   "TARGET_USE_FANCY_MATH_387
15925    && flag_unsafe_math_optimizations"
15926   "fsincos"
15927   [(set_attr "type" "fpspc")
15928    (set_attr "mode" "XF")])
15929
15930 (define_split
15931   [(set (match_operand:XF 0 "register_operand" "")
15932         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15933                    UNSPEC_SINCOS_COS))
15934    (set (match_operand:XF 1 "register_operand" "")
15935         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15936   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15937    && !(reload_completed || reload_in_progress)"
15938   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15939   "")
15940
15941 (define_split
15942   [(set (match_operand:XF 0 "register_operand" "")
15943         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15944                    UNSPEC_SINCOS_COS))
15945    (set (match_operand:XF 1 "register_operand" "")
15946         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15948    && !(reload_completed || reload_in_progress)"
15949   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15950   "")
15951
15952 (define_insn "sincos_extend<mode>xf3_i387"
15953   [(set (match_operand:XF 0 "register_operand" "=f")
15954         (unspec:XF [(float_extend:XF
15955                       (match_operand:MODEF 2 "register_operand" "0"))]
15956                    UNSPEC_SINCOS_COS))
15957    (set (match_operand:XF 1 "register_operand" "=u")
15958         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15959   "TARGET_USE_FANCY_MATH_387
15960    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15961        || TARGET_MIX_SSE_I387)
15962    && flag_unsafe_math_optimizations"
15963   "fsincos"
15964   [(set_attr "type" "fpspc")
15965    (set_attr "mode" "XF")])
15966
15967 (define_split
15968   [(set (match_operand:XF 0 "register_operand" "")
15969         (unspec:XF [(float_extend:XF
15970                       (match_operand:MODEF 2 "register_operand" ""))]
15971                    UNSPEC_SINCOS_COS))
15972    (set (match_operand:XF 1 "register_operand" "")
15973         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15974   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15975    && !(reload_completed || reload_in_progress)"
15976   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15977   "")
15978
15979 (define_split
15980   [(set (match_operand:XF 0 "register_operand" "")
15981         (unspec:XF [(float_extend:XF
15982                       (match_operand:MODEF 2 "register_operand" ""))]
15983                    UNSPEC_SINCOS_COS))
15984    (set (match_operand:XF 1 "register_operand" "")
15985         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15986   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15987    && !(reload_completed || reload_in_progress)"
15988   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15989   "")
15990
15991 (define_expand "sincos<mode>3"
15992   [(use (match_operand:MODEF 0 "register_operand" ""))
15993    (use (match_operand:MODEF 1 "register_operand" ""))
15994    (use (match_operand:MODEF 2 "register_operand" ""))]
15995   "TARGET_USE_FANCY_MATH_387
15996    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15997        || TARGET_MIX_SSE_I387)
15998    && flag_unsafe_math_optimizations"
15999 {
16000   rtx op0 = gen_reg_rtx (XFmode);
16001   rtx op1 = gen_reg_rtx (XFmode);
16002
16003   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16004   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16005   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16006   DONE;
16007 })
16008
16009 (define_insn "fptanxf4_i387"
16010   [(set (match_operand:XF 0 "register_operand" "=f")
16011         (match_operand:XF 3 "const_double_operand" "F"))
16012    (set (match_operand:XF 1 "register_operand" "=u")
16013         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16014                    UNSPEC_TAN))]
16015   "TARGET_USE_FANCY_MATH_387
16016    && flag_unsafe_math_optimizations
16017    && standard_80387_constant_p (operands[3]) == 2"
16018   "fptan"
16019   [(set_attr "type" "fpspc")
16020    (set_attr "mode" "XF")])
16021
16022 (define_insn "fptan_extend<mode>xf4_i387"
16023   [(set (match_operand:MODEF 0 "register_operand" "=f")
16024         (match_operand:MODEF 3 "const_double_operand" "F"))
16025    (set (match_operand:XF 1 "register_operand" "=u")
16026         (unspec:XF [(float_extend:XF
16027                       (match_operand:MODEF 2 "register_operand" "0"))]
16028                    UNSPEC_TAN))]
16029   "TARGET_USE_FANCY_MATH_387
16030    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16031        || TARGET_MIX_SSE_I387)
16032    && flag_unsafe_math_optimizations
16033    && standard_80387_constant_p (operands[3]) == 2"
16034   "fptan"
16035   [(set_attr "type" "fpspc")
16036    (set_attr "mode" "XF")])
16037
16038 (define_expand "tanxf2"
16039   [(use (match_operand:XF 0 "register_operand" ""))
16040    (use (match_operand:XF 1 "register_operand" ""))]
16041   "TARGET_USE_FANCY_MATH_387
16042    && flag_unsafe_math_optimizations"
16043 {
16044   rtx one = gen_reg_rtx (XFmode);
16045   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16046
16047   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16048   DONE;
16049 })
16050
16051 (define_expand "tan<mode>2"
16052   [(use (match_operand:MODEF 0 "register_operand" ""))
16053    (use (match_operand:MODEF 1 "register_operand" ""))]
16054   "TARGET_USE_FANCY_MATH_387
16055    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16056        || TARGET_MIX_SSE_I387)
16057    && flag_unsafe_math_optimizations"
16058 {
16059   rtx op0 = gen_reg_rtx (XFmode);
16060
16061   rtx one = gen_reg_rtx (<MODE>mode);
16062   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16063
16064   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16065                                              operands[1], op2));
16066   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16067   DONE;
16068 })
16069
16070 (define_insn "*fpatanxf3_i387"
16071   [(set (match_operand:XF 0 "register_operand" "=f")
16072         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16073                     (match_operand:XF 2 "register_operand" "u")]
16074                    UNSPEC_FPATAN))
16075    (clobber (match_scratch:XF 3 "=2"))]
16076   "TARGET_USE_FANCY_MATH_387
16077    && flag_unsafe_math_optimizations"
16078   "fpatan"
16079   [(set_attr "type" "fpspc")
16080    (set_attr "mode" "XF")])
16081
16082 (define_insn "fpatan_extend<mode>xf3_i387"
16083   [(set (match_operand:XF 0 "register_operand" "=f")
16084         (unspec:XF [(float_extend:XF
16085                       (match_operand:MODEF 1 "register_operand" "0"))
16086                     (float_extend:XF
16087                       (match_operand:MODEF 2 "register_operand" "u"))]
16088                    UNSPEC_FPATAN))
16089    (clobber (match_scratch:XF 3 "=2"))]
16090   "TARGET_USE_FANCY_MATH_387
16091    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16092        || TARGET_MIX_SSE_I387)
16093    && flag_unsafe_math_optimizations"
16094   "fpatan"
16095   [(set_attr "type" "fpspc")
16096    (set_attr "mode" "XF")])
16097
16098 (define_expand "atan2xf3"
16099   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16100                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16101                                (match_operand:XF 1 "register_operand" "")]
16102                               UNSPEC_FPATAN))
16103               (clobber (match_scratch:XF 3 ""))])]
16104   "TARGET_USE_FANCY_MATH_387
16105    && flag_unsafe_math_optimizations"
16106   "")
16107
16108 (define_expand "atan2<mode>3"
16109   [(use (match_operand:MODEF 0 "register_operand" ""))
16110    (use (match_operand:MODEF 1 "register_operand" ""))
16111    (use (match_operand:MODEF 2 "register_operand" ""))]
16112   "TARGET_USE_FANCY_MATH_387
16113    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16114        || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16116 {
16117   rtx op0 = gen_reg_rtx (XFmode);
16118
16119   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16120   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16121   DONE;
16122 })
16123
16124 (define_expand "atanxf2"
16125   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16126                    (unspec:XF [(match_dup 2)
16127                                (match_operand:XF 1 "register_operand" "")]
16128                               UNSPEC_FPATAN))
16129               (clobber (match_scratch:XF 3 ""))])]
16130   "TARGET_USE_FANCY_MATH_387
16131    && flag_unsafe_math_optimizations"
16132 {
16133   operands[2] = gen_reg_rtx (XFmode);
16134   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16135 })
16136
16137 (define_expand "atan<mode>2"
16138   [(use (match_operand:MODEF 0 "register_operand" ""))
16139    (use (match_operand:MODEF 1 "register_operand" ""))]
16140   "TARGET_USE_FANCY_MATH_387
16141    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16142        || TARGET_MIX_SSE_I387)
16143    && flag_unsafe_math_optimizations"
16144 {
16145   rtx op0 = gen_reg_rtx (XFmode);
16146
16147   rtx op2 = gen_reg_rtx (<MODE>mode);
16148   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16149
16150   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16151   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16152   DONE;
16153 })
16154
16155 (define_expand "asinxf2"
16156   [(set (match_dup 2)
16157         (mult:XF (match_operand:XF 1 "register_operand" "")
16158                  (match_dup 1)))
16159    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16160    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16161    (parallel [(set (match_operand:XF 0 "register_operand" "")
16162                    (unspec:XF [(match_dup 5) (match_dup 1)]
16163                               UNSPEC_FPATAN))
16164               (clobber (match_scratch:XF 6 ""))])]
16165   "TARGET_USE_FANCY_MATH_387
16166    && flag_unsafe_math_optimizations"
16167 {
16168   int i;
16169
16170   if (optimize_insn_for_size_p ())
16171     FAIL;
16172
16173   for (i = 2; i < 6; i++)
16174     operands[i] = gen_reg_rtx (XFmode);
16175
16176   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16177 })
16178
16179 (define_expand "asin<mode>2"
16180   [(use (match_operand:MODEF 0 "register_operand" ""))
16181    (use (match_operand:MODEF 1 "general_operand" ""))]
16182  "TARGET_USE_FANCY_MATH_387
16183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16184        || TARGET_MIX_SSE_I387)
16185    && flag_unsafe_math_optimizations"
16186 {
16187   rtx op0 = gen_reg_rtx (XFmode);
16188   rtx op1 = gen_reg_rtx (XFmode);
16189
16190   if (optimize_insn_for_size_p ())
16191     FAIL;
16192
16193   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16194   emit_insn (gen_asinxf2 (op0, op1));
16195   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16196   DONE;
16197 })
16198
16199 (define_expand "acosxf2"
16200   [(set (match_dup 2)
16201         (mult:XF (match_operand:XF 1 "register_operand" "")
16202                  (match_dup 1)))
16203    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16204    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16205    (parallel [(set (match_operand:XF 0 "register_operand" "")
16206                    (unspec:XF [(match_dup 1) (match_dup 5)]
16207                               UNSPEC_FPATAN))
16208               (clobber (match_scratch:XF 6 ""))])]
16209   "TARGET_USE_FANCY_MATH_387
16210    && flag_unsafe_math_optimizations"
16211 {
16212   int i;
16213
16214   if (optimize_insn_for_size_p ())
16215     FAIL;
16216
16217   for (i = 2; i < 6; i++)
16218     operands[i] = gen_reg_rtx (XFmode);
16219
16220   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16221 })
16222
16223 (define_expand "acos<mode>2"
16224   [(use (match_operand:MODEF 0 "register_operand" ""))
16225    (use (match_operand:MODEF 1 "general_operand" ""))]
16226  "TARGET_USE_FANCY_MATH_387
16227    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16228        || TARGET_MIX_SSE_I387)
16229    && flag_unsafe_math_optimizations"
16230 {
16231   rtx op0 = gen_reg_rtx (XFmode);
16232   rtx op1 = gen_reg_rtx (XFmode);
16233
16234   if (optimize_insn_for_size_p ())
16235     FAIL;
16236
16237   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16238   emit_insn (gen_acosxf2 (op0, op1));
16239   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16240   DONE;
16241 })
16242
16243 (define_insn "fyl2xxf3_i387"
16244   [(set (match_operand:XF 0 "register_operand" "=f")
16245         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16246                     (match_operand:XF 2 "register_operand" "u")]
16247                    UNSPEC_FYL2X))
16248    (clobber (match_scratch:XF 3 "=2"))]
16249   "TARGET_USE_FANCY_MATH_387
16250    && flag_unsafe_math_optimizations"
16251   "fyl2x"
16252   [(set_attr "type" "fpspc")
16253    (set_attr "mode" "XF")])
16254
16255 (define_insn "fyl2x_extend<mode>xf3_i387"
16256   [(set (match_operand:XF 0 "register_operand" "=f")
16257         (unspec:XF [(float_extend:XF
16258                       (match_operand:MODEF 1 "register_operand" "0"))
16259                     (match_operand:XF 2 "register_operand" "u")]
16260                    UNSPEC_FYL2X))
16261    (clobber (match_scratch:XF 3 "=2"))]
16262   "TARGET_USE_FANCY_MATH_387
16263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16264        || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16266   "fyl2x"
16267   [(set_attr "type" "fpspc")
16268    (set_attr "mode" "XF")])
16269
16270 (define_expand "logxf2"
16271   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16272                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16273                                (match_dup 2)] UNSPEC_FYL2X))
16274               (clobber (match_scratch:XF 3 ""))])]
16275   "TARGET_USE_FANCY_MATH_387
16276    && flag_unsafe_math_optimizations"
16277 {
16278   operands[2] = gen_reg_rtx (XFmode);
16279   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16280 })
16281
16282 (define_expand "log<mode>2"
16283   [(use (match_operand:MODEF 0 "register_operand" ""))
16284    (use (match_operand:MODEF 1 "register_operand" ""))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16287        || TARGET_MIX_SSE_I387)
16288    && flag_unsafe_math_optimizations"
16289 {
16290   rtx op0 = gen_reg_rtx (XFmode);
16291
16292   rtx op2 = gen_reg_rtx (XFmode);
16293   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16294
16295   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16296   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16297   DONE;
16298 })
16299
16300 (define_expand "log10xf2"
16301   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16302                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16303                                (match_dup 2)] UNSPEC_FYL2X))
16304               (clobber (match_scratch:XF 3 ""))])]
16305   "TARGET_USE_FANCY_MATH_387
16306    && flag_unsafe_math_optimizations"
16307 {
16308   operands[2] = gen_reg_rtx (XFmode);
16309   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16310 })
16311
16312 (define_expand "log10<mode>2"
16313   [(use (match_operand:MODEF 0 "register_operand" ""))
16314    (use (match_operand:MODEF 1 "register_operand" ""))]
16315   "TARGET_USE_FANCY_MATH_387
16316    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16317        || TARGET_MIX_SSE_I387)
16318    && flag_unsafe_math_optimizations"
16319 {
16320   rtx op0 = gen_reg_rtx (XFmode);
16321
16322   rtx op2 = gen_reg_rtx (XFmode);
16323   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16324
16325   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16326   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16327   DONE;
16328 })
16329
16330 (define_expand "log2xf2"
16331   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16332                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16333                                (match_dup 2)] UNSPEC_FYL2X))
16334               (clobber (match_scratch:XF 3 ""))])]
16335   "TARGET_USE_FANCY_MATH_387
16336    && flag_unsafe_math_optimizations"
16337 {
16338   operands[2] = gen_reg_rtx (XFmode);
16339   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16340 })
16341
16342 (define_expand "log2<mode>2"
16343   [(use (match_operand:MODEF 0 "register_operand" ""))
16344    (use (match_operand:MODEF 1 "register_operand" ""))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16347        || TARGET_MIX_SSE_I387)
16348    && flag_unsafe_math_optimizations"
16349 {
16350   rtx op0 = gen_reg_rtx (XFmode);
16351
16352   rtx op2 = gen_reg_rtx (XFmode);
16353   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16354
16355   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16356   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16357   DONE;
16358 })
16359
16360 (define_insn "fyl2xp1xf3_i387"
16361   [(set (match_operand:XF 0 "register_operand" "=f")
16362         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16363                     (match_operand:XF 2 "register_operand" "u")]
16364                    UNSPEC_FYL2XP1))
16365    (clobber (match_scratch:XF 3 "=2"))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && flag_unsafe_math_optimizations"
16368   "fyl2xp1"
16369   [(set_attr "type" "fpspc")
16370    (set_attr "mode" "XF")])
16371
16372 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16373   [(set (match_operand:XF 0 "register_operand" "=f")
16374         (unspec:XF [(float_extend:XF
16375                       (match_operand:MODEF 1 "register_operand" "0"))
16376                     (match_operand:XF 2 "register_operand" "u")]
16377                    UNSPEC_FYL2XP1))
16378    (clobber (match_scratch:XF 3 "=2"))]
16379   "TARGET_USE_FANCY_MATH_387
16380    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16381        || TARGET_MIX_SSE_I387)
16382    && flag_unsafe_math_optimizations"
16383   "fyl2xp1"
16384   [(set_attr "type" "fpspc")
16385    (set_attr "mode" "XF")])
16386
16387 (define_expand "log1pxf2"
16388   [(use (match_operand:XF 0 "register_operand" ""))
16389    (use (match_operand:XF 1 "register_operand" ""))]
16390   "TARGET_USE_FANCY_MATH_387
16391    && flag_unsafe_math_optimizations"
16392 {
16393   if (optimize_insn_for_size_p ())
16394     FAIL;
16395
16396   ix86_emit_i387_log1p (operands[0], operands[1]);
16397   DONE;
16398 })
16399
16400 (define_expand "log1p<mode>2"
16401   [(use (match_operand:MODEF 0 "register_operand" ""))
16402    (use (match_operand:MODEF 1 "register_operand" ""))]
16403   "TARGET_USE_FANCY_MATH_387
16404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16405        || TARGET_MIX_SSE_I387)
16406    && flag_unsafe_math_optimizations"
16407 {
16408   rtx op0;
16409
16410   if (optimize_insn_for_size_p ())
16411     FAIL;
16412
16413   op0 = gen_reg_rtx (XFmode);
16414
16415   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16416
16417   ix86_emit_i387_log1p (op0, operands[1]);
16418   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16419   DONE;
16420 })
16421
16422 (define_insn "fxtractxf3_i387"
16423   [(set (match_operand:XF 0 "register_operand" "=f")
16424         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16425                    UNSPEC_XTRACT_FRACT))
16426    (set (match_operand:XF 1 "register_operand" "=u")
16427         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16428   "TARGET_USE_FANCY_MATH_387
16429    && flag_unsafe_math_optimizations"
16430   "fxtract"
16431   [(set_attr "type" "fpspc")
16432    (set_attr "mode" "XF")])
16433
16434 (define_insn "fxtract_extend<mode>xf3_i387"
16435   [(set (match_operand:XF 0 "register_operand" "=f")
16436         (unspec:XF [(float_extend:XF
16437                       (match_operand:MODEF 2 "register_operand" "0"))]
16438                    UNSPEC_XTRACT_FRACT))
16439    (set (match_operand:XF 1 "register_operand" "=u")
16440         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16441   "TARGET_USE_FANCY_MATH_387
16442    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16443        || TARGET_MIX_SSE_I387)
16444    && flag_unsafe_math_optimizations"
16445   "fxtract"
16446   [(set_attr "type" "fpspc")
16447    (set_attr "mode" "XF")])
16448
16449 (define_expand "logbxf2"
16450   [(parallel [(set (match_dup 2)
16451                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16452                               UNSPEC_XTRACT_FRACT))
16453               (set (match_operand:XF 0 "register_operand" "")
16454                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16455   "TARGET_USE_FANCY_MATH_387
16456    && flag_unsafe_math_optimizations"
16457 {
16458   operands[2] = gen_reg_rtx (XFmode);
16459 })
16460
16461 (define_expand "logb<mode>2"
16462   [(use (match_operand:MODEF 0 "register_operand" ""))
16463    (use (match_operand:MODEF 1 "register_operand" ""))]
16464   "TARGET_USE_FANCY_MATH_387
16465    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16466        || TARGET_MIX_SSE_I387)
16467    && flag_unsafe_math_optimizations"
16468 {
16469   rtx op0 = gen_reg_rtx (XFmode);
16470   rtx op1 = gen_reg_rtx (XFmode);
16471
16472   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16473   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16474   DONE;
16475 })
16476
16477 (define_expand "ilogbxf2"
16478   [(use (match_operand:SI 0 "register_operand" ""))
16479    (use (match_operand:XF 1 "register_operand" ""))]
16480   "TARGET_USE_FANCY_MATH_387
16481    && flag_unsafe_math_optimizations"
16482 {
16483   rtx op0, op1;
16484
16485   if (optimize_insn_for_size_p ())
16486     FAIL;
16487
16488   op0 = gen_reg_rtx (XFmode);
16489   op1 = gen_reg_rtx (XFmode);
16490
16491   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16492   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16493   DONE;
16494 })
16495
16496 (define_expand "ilogb<mode>2"
16497   [(use (match_operand:SI 0 "register_operand" ""))
16498    (use (match_operand:MODEF 1 "register_operand" ""))]
16499   "TARGET_USE_FANCY_MATH_387
16500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16501        || TARGET_MIX_SSE_I387)
16502    && flag_unsafe_math_optimizations"
16503 {
16504   rtx op0, op1;
16505
16506   if (optimize_insn_for_size_p ())
16507     FAIL;
16508
16509   op0 = gen_reg_rtx (XFmode);
16510   op1 = gen_reg_rtx (XFmode);
16511
16512   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16513   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16514   DONE;
16515 })
16516
16517 (define_insn "*f2xm1xf2_i387"
16518   [(set (match_operand:XF 0 "register_operand" "=f")
16519         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16520                    UNSPEC_F2XM1))]
16521   "TARGET_USE_FANCY_MATH_387
16522    && flag_unsafe_math_optimizations"
16523   "f2xm1"
16524   [(set_attr "type" "fpspc")
16525    (set_attr "mode" "XF")])
16526
16527 (define_insn "*fscalexf4_i387"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16530                     (match_operand:XF 3 "register_operand" "1")]
16531                    UNSPEC_FSCALE_FRACT))
16532    (set (match_operand:XF 1 "register_operand" "=u")
16533         (unspec:XF [(match_dup 2) (match_dup 3)]
16534                    UNSPEC_FSCALE_EXP))]
16535   "TARGET_USE_FANCY_MATH_387
16536    && flag_unsafe_math_optimizations"
16537   "fscale"
16538   [(set_attr "type" "fpspc")
16539    (set_attr "mode" "XF")])
16540
16541 (define_expand "expNcorexf3"
16542   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16543                                (match_operand:XF 2 "register_operand" "")))
16544    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16545    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16546    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16547    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16548    (parallel [(set (match_operand:XF 0 "register_operand" "")
16549                    (unspec:XF [(match_dup 8) (match_dup 4)]
16550                               UNSPEC_FSCALE_FRACT))
16551               (set (match_dup 9)
16552                    (unspec:XF [(match_dup 8) (match_dup 4)]
16553                               UNSPEC_FSCALE_EXP))])]
16554   "TARGET_USE_FANCY_MATH_387
16555    && flag_unsafe_math_optimizations"
16556 {
16557   int i;
16558
16559   if (optimize_insn_for_size_p ())
16560     FAIL;
16561
16562   for (i = 3; i < 10; i++)
16563     operands[i] = gen_reg_rtx (XFmode);
16564
16565   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16566 })
16567
16568 (define_expand "expxf2"
16569   [(use (match_operand:XF 0 "register_operand" ""))
16570    (use (match_operand:XF 1 "register_operand" ""))]
16571   "TARGET_USE_FANCY_MATH_387
16572    && flag_unsafe_math_optimizations"
16573 {
16574   rtx op2;
16575
16576   if (optimize_insn_for_size_p ())
16577     FAIL;
16578
16579   op2 = gen_reg_rtx (XFmode);
16580   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16581
16582   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16583   DONE;
16584 })
16585
16586 (define_expand "exp<mode>2"
16587   [(use (match_operand:MODEF 0 "register_operand" ""))
16588    (use (match_operand:MODEF 1 "general_operand" ""))]
16589  "TARGET_USE_FANCY_MATH_387
16590    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16591        || TARGET_MIX_SSE_I387)
16592    && flag_unsafe_math_optimizations"
16593 {
16594   rtx op0, op1;
16595
16596   if (optimize_insn_for_size_p ())
16597     FAIL;
16598
16599   op0 = gen_reg_rtx (XFmode);
16600   op1 = gen_reg_rtx (XFmode);
16601
16602   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16603   emit_insn (gen_expxf2 (op0, op1));
16604   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16605   DONE;
16606 })
16607
16608 (define_expand "exp10xf2"
16609   [(use (match_operand:XF 0 "register_operand" ""))
16610    (use (match_operand:XF 1 "register_operand" ""))]
16611   "TARGET_USE_FANCY_MATH_387
16612    && flag_unsafe_math_optimizations"
16613 {
16614   rtx op2;
16615
16616   if (optimize_insn_for_size_p ())
16617     FAIL;
16618
16619   op2 = gen_reg_rtx (XFmode);
16620   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16621
16622   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16623   DONE;
16624 })
16625
16626 (define_expand "exp10<mode>2"
16627   [(use (match_operand:MODEF 0 "register_operand" ""))
16628    (use (match_operand:MODEF 1 "general_operand" ""))]
16629  "TARGET_USE_FANCY_MATH_387
16630    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16631        || TARGET_MIX_SSE_I387)
16632    && flag_unsafe_math_optimizations"
16633 {
16634   rtx op0, op1;
16635
16636   if (optimize_insn_for_size_p ())
16637     FAIL;
16638
16639   op0 = gen_reg_rtx (XFmode);
16640   op1 = gen_reg_rtx (XFmode);
16641
16642   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16643   emit_insn (gen_exp10xf2 (op0, op1));
16644   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16645   DONE;
16646 })
16647
16648 (define_expand "exp2xf2"
16649   [(use (match_operand:XF 0 "register_operand" ""))
16650    (use (match_operand:XF 1 "register_operand" ""))]
16651   "TARGET_USE_FANCY_MATH_387
16652    && flag_unsafe_math_optimizations"
16653 {
16654   rtx op2;
16655
16656   if (optimize_insn_for_size_p ())
16657     FAIL;
16658
16659   op2 = gen_reg_rtx (XFmode);
16660   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16661
16662   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16663   DONE;
16664 })
16665
16666 (define_expand "exp2<mode>2"
16667   [(use (match_operand:MODEF 0 "register_operand" ""))
16668    (use (match_operand:MODEF 1 "general_operand" ""))]
16669  "TARGET_USE_FANCY_MATH_387
16670    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671        || TARGET_MIX_SSE_I387)
16672    && flag_unsafe_math_optimizations"
16673 {
16674   rtx op0, op1;
16675
16676   if (optimize_insn_for_size_p ())
16677     FAIL;
16678
16679   op0 = gen_reg_rtx (XFmode);
16680   op1 = gen_reg_rtx (XFmode);
16681
16682   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16683   emit_insn (gen_exp2xf2 (op0, op1));
16684   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16685   DONE;
16686 })
16687
16688 (define_expand "expm1xf2"
16689   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16690                                (match_dup 2)))
16691    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16692    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16693    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16694    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16695    (parallel [(set (match_dup 7)
16696                    (unspec:XF [(match_dup 6) (match_dup 4)]
16697                               UNSPEC_FSCALE_FRACT))
16698               (set (match_dup 8)
16699                    (unspec:XF [(match_dup 6) (match_dup 4)]
16700                               UNSPEC_FSCALE_EXP))])
16701    (parallel [(set (match_dup 10)
16702                    (unspec:XF [(match_dup 9) (match_dup 8)]
16703                               UNSPEC_FSCALE_FRACT))
16704               (set (match_dup 11)
16705                    (unspec:XF [(match_dup 9) (match_dup 8)]
16706                               UNSPEC_FSCALE_EXP))])
16707    (set (match_dup 12) (minus:XF (match_dup 10)
16708                                  (float_extend:XF (match_dup 13))))
16709    (set (match_operand:XF 0 "register_operand" "")
16710         (plus:XF (match_dup 12) (match_dup 7)))]
16711   "TARGET_USE_FANCY_MATH_387
16712    && flag_unsafe_math_optimizations"
16713 {
16714   int i;
16715
16716   if (optimize_insn_for_size_p ())
16717     FAIL;
16718
16719   for (i = 2; i < 13; i++)
16720     operands[i] = gen_reg_rtx (XFmode);
16721
16722   operands[13]
16723     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16724
16725   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16726 })
16727
16728 (define_expand "expm1<mode>2"
16729   [(use (match_operand:MODEF 0 "register_operand" ""))
16730    (use (match_operand:MODEF 1 "general_operand" ""))]
16731  "TARGET_USE_FANCY_MATH_387
16732    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16733        || TARGET_MIX_SSE_I387)
16734    && flag_unsafe_math_optimizations"
16735 {
16736   rtx op0, op1;
16737
16738   if (optimize_insn_for_size_p ())
16739     FAIL;
16740
16741   op0 = gen_reg_rtx (XFmode);
16742   op1 = gen_reg_rtx (XFmode);
16743
16744   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16745   emit_insn (gen_expm1xf2 (op0, op1));
16746   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16747   DONE;
16748 })
16749
16750 (define_expand "ldexpxf3"
16751   [(set (match_dup 3)
16752         (float:XF (match_operand:SI 2 "register_operand" "")))
16753    (parallel [(set (match_operand:XF 0 " register_operand" "")
16754                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16755                                (match_dup 3)]
16756                               UNSPEC_FSCALE_FRACT))
16757               (set (match_dup 4)
16758                    (unspec:XF [(match_dup 1) (match_dup 3)]
16759                               UNSPEC_FSCALE_EXP))])]
16760   "TARGET_USE_FANCY_MATH_387
16761    && flag_unsafe_math_optimizations"
16762 {
16763   if (optimize_insn_for_size_p ())
16764     FAIL;
16765
16766   operands[3] = gen_reg_rtx (XFmode);
16767   operands[4] = gen_reg_rtx (XFmode);
16768 })
16769
16770 (define_expand "ldexp<mode>3"
16771   [(use (match_operand:MODEF 0 "register_operand" ""))
16772    (use (match_operand:MODEF 1 "general_operand" ""))
16773    (use (match_operand:SI 2 "register_operand" ""))]
16774  "TARGET_USE_FANCY_MATH_387
16775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16776        || TARGET_MIX_SSE_I387)
16777    && flag_unsafe_math_optimizations"
16778 {
16779   rtx op0, op1;
16780
16781   if (optimize_insn_for_size_p ())
16782     FAIL;
16783
16784   op0 = gen_reg_rtx (XFmode);
16785   op1 = gen_reg_rtx (XFmode);
16786
16787   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16788   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16789   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16790   DONE;
16791 })
16792
16793 (define_expand "scalbxf3"
16794   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16795                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16796                                (match_operand:XF 2 "register_operand" "")]
16797                               UNSPEC_FSCALE_FRACT))
16798               (set (match_dup 3)
16799                    (unspec:XF [(match_dup 1) (match_dup 2)]
16800                               UNSPEC_FSCALE_EXP))])]
16801   "TARGET_USE_FANCY_MATH_387
16802    && flag_unsafe_math_optimizations"
16803 {
16804   if (optimize_insn_for_size_p ())
16805     FAIL;
16806
16807   operands[3] = gen_reg_rtx (XFmode);
16808 })
16809
16810 (define_expand "scalb<mode>3"
16811   [(use (match_operand:MODEF 0 "register_operand" ""))
16812    (use (match_operand:MODEF 1 "general_operand" ""))
16813    (use (match_operand:MODEF 2 "general_operand" ""))]
16814  "TARGET_USE_FANCY_MATH_387
16815    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16816        || TARGET_MIX_SSE_I387)
16817    && flag_unsafe_math_optimizations"
16818 {
16819   rtx op0, op1, op2;
16820
16821   if (optimize_insn_for_size_p ())
16822     FAIL;
16823
16824   op0 = gen_reg_rtx (XFmode);
16825   op1 = gen_reg_rtx (XFmode);
16826   op2 = gen_reg_rtx (XFmode);
16827
16828   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16829   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16830   emit_insn (gen_scalbxf3 (op0, op1, op2));
16831   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16832   DONE;
16833 })
16834
16835 (define_expand "significandxf2"
16836   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16837                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16838                               UNSPEC_XTRACT_FRACT))
16839               (set (match_dup 2)
16840                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16841   "TARGET_USE_FANCY_MATH_387
16842    && flag_unsafe_math_optimizations"
16843 {
16844   operands[2] = gen_reg_rtx (XFmode);
16845 })
16846
16847 (define_expand "significand<mode>2"
16848   [(use (match_operand:MODEF 0 "register_operand" ""))
16849    (use (match_operand:MODEF 1 "register_operand" ""))]
16850   "TARGET_USE_FANCY_MATH_387
16851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16852        || TARGET_MIX_SSE_I387)
16853    && flag_unsafe_math_optimizations"
16854 {
16855   rtx op0 = gen_reg_rtx (XFmode);
16856   rtx op1 = gen_reg_rtx (XFmode);
16857
16858   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16859   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16860   DONE;
16861 })
16862 \f
16863
16864 (define_insn "sse4_1_round<mode>2"
16865   [(set (match_operand:MODEF 0 "register_operand" "=x")
16866         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16867                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
16868                       UNSPEC_ROUND))]
16869   "TARGET_ROUND"
16870   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16871   [(set_attr "type" "ssecvt")
16872    (set_attr "prefix_extra" "1")
16873    (set_attr "prefix" "maybe_vex")
16874    (set_attr "mode" "<MODE>")])
16875
16876 (define_insn "rintxf2"
16877   [(set (match_operand:XF 0 "register_operand" "=f")
16878         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16879                    UNSPEC_FRNDINT))]
16880   "TARGET_USE_FANCY_MATH_387
16881    && flag_unsafe_math_optimizations"
16882   "frndint"
16883   [(set_attr "type" "fpspc")
16884    (set_attr "mode" "XF")])
16885
16886 (define_expand "rint<mode>2"
16887   [(use (match_operand:MODEF 0 "register_operand" ""))
16888    (use (match_operand:MODEF 1 "register_operand" ""))]
16889   "(TARGET_USE_FANCY_MATH_387
16890     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16891         || TARGET_MIX_SSE_I387)
16892     && flag_unsafe_math_optimizations)
16893    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16894        && !flag_trapping_math)"
16895 {
16896   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16897       && !flag_trapping_math)
16898     {
16899       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16900         FAIL;
16901       if (TARGET_ROUND)
16902         emit_insn (gen_sse4_1_round<mode>2
16903                    (operands[0], operands[1], GEN_INT (0x04)));
16904       else
16905         ix86_expand_rint (operand0, operand1);
16906     }
16907   else
16908     {
16909       rtx op0 = gen_reg_rtx (XFmode);
16910       rtx op1 = gen_reg_rtx (XFmode);
16911
16912       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16913       emit_insn (gen_rintxf2 (op0, op1));
16914
16915       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16916     }
16917   DONE;
16918 })
16919
16920 (define_expand "round<mode>2"
16921   [(match_operand:MODEF 0 "register_operand" "")
16922    (match_operand:MODEF 1 "nonimmediate_operand" "")]
16923   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16924    && !flag_trapping_math && !flag_rounding_math"
16925 {
16926   if (optimize_insn_for_size_p ())
16927     FAIL;
16928   if (TARGET_64BIT || (<MODE>mode != DFmode))
16929     ix86_expand_round (operand0, operand1);
16930   else
16931     ix86_expand_rounddf_32 (operand0, operand1);
16932   DONE;
16933 })
16934
16935 (define_insn_and_split "*fistdi2_1"
16936   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16937         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16938                    UNSPEC_FIST))]
16939   "TARGET_USE_FANCY_MATH_387
16940    && can_create_pseudo_p ()"
16941   "#"
16942   "&& 1"
16943   [(const_int 0)]
16944 {
16945   if (memory_operand (operands[0], VOIDmode))
16946     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16947   else
16948     {
16949       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16950       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16951                                          operands[2]));
16952     }
16953   DONE;
16954 }
16955   [(set_attr "type" "fpspc")
16956    (set_attr "mode" "DI")])
16957
16958 (define_insn "fistdi2"
16959   [(set (match_operand:DI 0 "memory_operand" "=m")
16960         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16961                    UNSPEC_FIST))
16962    (clobber (match_scratch:XF 2 "=&1f"))]
16963   "TARGET_USE_FANCY_MATH_387"
16964   "* return output_fix_trunc (insn, operands, 0);"
16965   [(set_attr "type" "fpspc")
16966    (set_attr "mode" "DI")])
16967
16968 (define_insn "fistdi2_with_temp"
16969   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16970         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16971                    UNSPEC_FIST))
16972    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16973    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16974   "TARGET_USE_FANCY_MATH_387"
16975   "#"
16976   [(set_attr "type" "fpspc")
16977    (set_attr "mode" "DI")])
16978
16979 (define_split
16980   [(set (match_operand:DI 0 "register_operand" "")
16981         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16982                    UNSPEC_FIST))
16983    (clobber (match_operand:DI 2 "memory_operand" ""))
16984    (clobber (match_scratch 3 ""))]
16985   "reload_completed"
16986   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16987               (clobber (match_dup 3))])
16988    (set (match_dup 0) (match_dup 2))]
16989   "")
16990
16991 (define_split
16992   [(set (match_operand:DI 0 "memory_operand" "")
16993         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16994                    UNSPEC_FIST))
16995    (clobber (match_operand:DI 2 "memory_operand" ""))
16996    (clobber (match_scratch 3 ""))]
16997   "reload_completed"
16998   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16999               (clobber (match_dup 3))])]
17000   "")
17001
17002 (define_insn_and_split "*fist<mode>2_1"
17003   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17004         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17005                            UNSPEC_FIST))]
17006   "TARGET_USE_FANCY_MATH_387
17007    && can_create_pseudo_p ()"
17008   "#"
17009   "&& 1"
17010   [(const_int 0)]
17011 {
17012   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17013   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17014                                         operands[2]));
17015   DONE;
17016 }
17017   [(set_attr "type" "fpspc")
17018    (set_attr "mode" "<MODE>")])
17019
17020 (define_insn "fist<mode>2"
17021   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17022         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17023                            UNSPEC_FIST))]
17024   "TARGET_USE_FANCY_MATH_387"
17025   "* return output_fix_trunc (insn, operands, 0);"
17026   [(set_attr "type" "fpspc")
17027    (set_attr "mode" "<MODE>")])
17028
17029 (define_insn "fist<mode>2_with_temp"
17030   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17031         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17032                            UNSPEC_FIST))
17033    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17034   "TARGET_USE_FANCY_MATH_387"
17035   "#"
17036   [(set_attr "type" "fpspc")
17037    (set_attr "mode" "<MODE>")])
17038
17039 (define_split
17040   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17041         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17042                            UNSPEC_FIST))
17043    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17044   "reload_completed"
17045   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17046    (set (match_dup 0) (match_dup 2))]
17047   "")
17048
17049 (define_split
17050   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17051         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17052                            UNSPEC_FIST))
17053    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17054   "reload_completed"
17055   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17056   "")
17057
17058 (define_expand "lrintxf<mode>2"
17059   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17060      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17061                       UNSPEC_FIST))]
17062   "TARGET_USE_FANCY_MATH_387"
17063   "")
17064
17065 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17066   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17067      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17068                         UNSPEC_FIX_NOTRUNC))]
17069   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17070    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17071   "")
17072
17073 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17074   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17075    (match_operand:MODEF 1 "register_operand" "")]
17076   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17077    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17078    && !flag_trapping_math && !flag_rounding_math"
17079 {
17080   if (optimize_insn_for_size_p ())
17081     FAIL;
17082   ix86_expand_lround (operand0, operand1);
17083   DONE;
17084 })
17085
17086 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17087 (define_insn_and_split "frndintxf2_floor"
17088   [(set (match_operand:XF 0 "register_operand" "")
17089         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17090          UNSPEC_FRNDINT_FLOOR))
17091    (clobber (reg:CC FLAGS_REG))]
17092   "TARGET_USE_FANCY_MATH_387
17093    && flag_unsafe_math_optimizations
17094    && can_create_pseudo_p ()"
17095   "#"
17096   "&& 1"
17097   [(const_int 0)]
17098 {
17099   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17100
17101   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17102   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17103
17104   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17105                                         operands[2], operands[3]));
17106   DONE;
17107 }
17108   [(set_attr "type" "frndint")
17109    (set_attr "i387_cw" "floor")
17110    (set_attr "mode" "XF")])
17111
17112 (define_insn "frndintxf2_floor_i387"
17113   [(set (match_operand:XF 0 "register_operand" "=f")
17114         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17115          UNSPEC_FRNDINT_FLOOR))
17116    (use (match_operand:HI 2 "memory_operand" "m"))
17117    (use (match_operand:HI 3 "memory_operand" "m"))]
17118   "TARGET_USE_FANCY_MATH_387
17119    && flag_unsafe_math_optimizations"
17120   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17121   [(set_attr "type" "frndint")
17122    (set_attr "i387_cw" "floor")
17123    (set_attr "mode" "XF")])
17124
17125 (define_expand "floorxf2"
17126   [(use (match_operand:XF 0 "register_operand" ""))
17127    (use (match_operand:XF 1 "register_operand" ""))]
17128   "TARGET_USE_FANCY_MATH_387
17129    && flag_unsafe_math_optimizations"
17130 {
17131   if (optimize_insn_for_size_p ())
17132     FAIL;
17133   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17134   DONE;
17135 })
17136
17137 (define_expand "floor<mode>2"
17138   [(use (match_operand:MODEF 0 "register_operand" ""))
17139    (use (match_operand:MODEF 1 "register_operand" ""))]
17140   "(TARGET_USE_FANCY_MATH_387
17141     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17142         || TARGET_MIX_SSE_I387)
17143     && flag_unsafe_math_optimizations)
17144    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17145        && !flag_trapping_math)"
17146 {
17147   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17148       && !flag_trapping_math
17149       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17150     {
17151       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17152         FAIL;
17153       if (TARGET_ROUND)
17154         emit_insn (gen_sse4_1_round<mode>2
17155                    (operands[0], operands[1], GEN_INT (0x01)));
17156       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17157         ix86_expand_floorceil (operand0, operand1, true);
17158       else
17159         ix86_expand_floorceildf_32 (operand0, operand1, true);
17160     }
17161   else
17162     {
17163       rtx op0, op1;
17164
17165       if (optimize_insn_for_size_p ())
17166         FAIL;
17167
17168       op0 = gen_reg_rtx (XFmode);
17169       op1 = gen_reg_rtx (XFmode);
17170       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17171       emit_insn (gen_frndintxf2_floor (op0, op1));
17172
17173       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17174     }
17175   DONE;
17176 })
17177
17178 (define_insn_and_split "*fist<mode>2_floor_1"
17179   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17180         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17181          UNSPEC_FIST_FLOOR))
17182    (clobber (reg:CC FLAGS_REG))]
17183   "TARGET_USE_FANCY_MATH_387
17184    && flag_unsafe_math_optimizations
17185    && can_create_pseudo_p ()"
17186   "#"
17187   "&& 1"
17188   [(const_int 0)]
17189 {
17190   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17191
17192   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17193   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17194   if (memory_operand (operands[0], VOIDmode))
17195     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17196                                       operands[2], operands[3]));
17197   else
17198     {
17199       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17200       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17201                                                   operands[2], operands[3],
17202                                                   operands[4]));
17203     }
17204   DONE;
17205 }
17206   [(set_attr "type" "fistp")
17207    (set_attr "i387_cw" "floor")
17208    (set_attr "mode" "<MODE>")])
17209
17210 (define_insn "fistdi2_floor"
17211   [(set (match_operand:DI 0 "memory_operand" "=m")
17212         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17213          UNSPEC_FIST_FLOOR))
17214    (use (match_operand:HI 2 "memory_operand" "m"))
17215    (use (match_operand:HI 3 "memory_operand" "m"))
17216    (clobber (match_scratch:XF 4 "=&1f"))]
17217   "TARGET_USE_FANCY_MATH_387
17218    && flag_unsafe_math_optimizations"
17219   "* return output_fix_trunc (insn, operands, 0);"
17220   [(set_attr "type" "fistp")
17221    (set_attr "i387_cw" "floor")
17222    (set_attr "mode" "DI")])
17223
17224 (define_insn "fistdi2_floor_with_temp"
17225   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17226         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17227          UNSPEC_FIST_FLOOR))
17228    (use (match_operand:HI 2 "memory_operand" "m,m"))
17229    (use (match_operand:HI 3 "memory_operand" "m,m"))
17230    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17231    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17232   "TARGET_USE_FANCY_MATH_387
17233    && flag_unsafe_math_optimizations"
17234   "#"
17235   [(set_attr "type" "fistp")
17236    (set_attr "i387_cw" "floor")
17237    (set_attr "mode" "DI")])
17238
17239 (define_split
17240   [(set (match_operand:DI 0 "register_operand" "")
17241         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17242          UNSPEC_FIST_FLOOR))
17243    (use (match_operand:HI 2 "memory_operand" ""))
17244    (use (match_operand:HI 3 "memory_operand" ""))
17245    (clobber (match_operand:DI 4 "memory_operand" ""))
17246    (clobber (match_scratch 5 ""))]
17247   "reload_completed"
17248   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17249               (use (match_dup 2))
17250               (use (match_dup 3))
17251               (clobber (match_dup 5))])
17252    (set (match_dup 0) (match_dup 4))]
17253   "")
17254
17255 (define_split
17256   [(set (match_operand:DI 0 "memory_operand" "")
17257         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17258          UNSPEC_FIST_FLOOR))
17259    (use (match_operand:HI 2 "memory_operand" ""))
17260    (use (match_operand:HI 3 "memory_operand" ""))
17261    (clobber (match_operand:DI 4 "memory_operand" ""))
17262    (clobber (match_scratch 5 ""))]
17263   "reload_completed"
17264   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17265               (use (match_dup 2))
17266               (use (match_dup 3))
17267               (clobber (match_dup 5))])]
17268   "")
17269
17270 (define_insn "fist<mode>2_floor"
17271   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17272         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17273          UNSPEC_FIST_FLOOR))
17274    (use (match_operand:HI 2 "memory_operand" "m"))
17275    (use (match_operand:HI 3 "memory_operand" "m"))]
17276   "TARGET_USE_FANCY_MATH_387
17277    && flag_unsafe_math_optimizations"
17278   "* return output_fix_trunc (insn, operands, 0);"
17279   [(set_attr "type" "fistp")
17280    (set_attr "i387_cw" "floor")
17281    (set_attr "mode" "<MODE>")])
17282
17283 (define_insn "fist<mode>2_floor_with_temp"
17284   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17285         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17286          UNSPEC_FIST_FLOOR))
17287    (use (match_operand:HI 2 "memory_operand" "m,m"))
17288    (use (match_operand:HI 3 "memory_operand" "m,m"))
17289    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17290   "TARGET_USE_FANCY_MATH_387
17291    && flag_unsafe_math_optimizations"
17292   "#"
17293   [(set_attr "type" "fistp")
17294    (set_attr "i387_cw" "floor")
17295    (set_attr "mode" "<MODE>")])
17296
17297 (define_split
17298   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17299         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17300          UNSPEC_FIST_FLOOR))
17301    (use (match_operand:HI 2 "memory_operand" ""))
17302    (use (match_operand:HI 3 "memory_operand" ""))
17303    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17304   "reload_completed"
17305   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17306                                   UNSPEC_FIST_FLOOR))
17307               (use (match_dup 2))
17308               (use (match_dup 3))])
17309    (set (match_dup 0) (match_dup 4))]
17310   "")
17311
17312 (define_split
17313   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17314         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17315          UNSPEC_FIST_FLOOR))
17316    (use (match_operand:HI 2 "memory_operand" ""))
17317    (use (match_operand:HI 3 "memory_operand" ""))
17318    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17319   "reload_completed"
17320   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17321                                   UNSPEC_FIST_FLOOR))
17322               (use (match_dup 2))
17323               (use (match_dup 3))])]
17324   "")
17325
17326 (define_expand "lfloorxf<mode>2"
17327   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17328                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17329                     UNSPEC_FIST_FLOOR))
17330               (clobber (reg:CC FLAGS_REG))])]
17331   "TARGET_USE_FANCY_MATH_387
17332    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17333    && flag_unsafe_math_optimizations"
17334   "")
17335
17336 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17337   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17338    (match_operand:MODEF 1 "register_operand" "")]
17339   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17340    && !flag_trapping_math"
17341 {
17342   if (TARGET_64BIT && optimize_insn_for_size_p ())
17343     FAIL;
17344   ix86_expand_lfloorceil (operand0, operand1, true);
17345   DONE;
17346 })
17347
17348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17349 (define_insn_and_split "frndintxf2_ceil"
17350   [(set (match_operand:XF 0 "register_operand" "")
17351         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17352          UNSPEC_FRNDINT_CEIL))
17353    (clobber (reg:CC FLAGS_REG))]
17354   "TARGET_USE_FANCY_MATH_387
17355    && flag_unsafe_math_optimizations
17356    && can_create_pseudo_p ()"
17357   "#"
17358   "&& 1"
17359   [(const_int 0)]
17360 {
17361   ix86_optimize_mode_switching[I387_CEIL] = 1;
17362
17363   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17364   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17365
17366   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17367                                        operands[2], operands[3]));
17368   DONE;
17369 }
17370   [(set_attr "type" "frndint")
17371    (set_attr "i387_cw" "ceil")
17372    (set_attr "mode" "XF")])
17373
17374 (define_insn "frndintxf2_ceil_i387"
17375   [(set (match_operand:XF 0 "register_operand" "=f")
17376         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17377          UNSPEC_FRNDINT_CEIL))
17378    (use (match_operand:HI 2 "memory_operand" "m"))
17379    (use (match_operand:HI 3 "memory_operand" "m"))]
17380   "TARGET_USE_FANCY_MATH_387
17381    && flag_unsafe_math_optimizations"
17382   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17383   [(set_attr "type" "frndint")
17384    (set_attr "i387_cw" "ceil")
17385    (set_attr "mode" "XF")])
17386
17387 (define_expand "ceilxf2"
17388   [(use (match_operand:XF 0 "register_operand" ""))
17389    (use (match_operand:XF 1 "register_operand" ""))]
17390   "TARGET_USE_FANCY_MATH_387
17391    && flag_unsafe_math_optimizations"
17392 {
17393   if (optimize_insn_for_size_p ())
17394     FAIL;
17395   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17396   DONE;
17397 })
17398
17399 (define_expand "ceil<mode>2"
17400   [(use (match_operand:MODEF 0 "register_operand" ""))
17401    (use (match_operand:MODEF 1 "register_operand" ""))]
17402   "(TARGET_USE_FANCY_MATH_387
17403     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17404         || TARGET_MIX_SSE_I387)
17405     && flag_unsafe_math_optimizations)
17406    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17407        && !flag_trapping_math)"
17408 {
17409   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17410       && !flag_trapping_math
17411       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17412     {
17413       if (TARGET_ROUND)
17414         emit_insn (gen_sse4_1_round<mode>2
17415                    (operands[0], operands[1], GEN_INT (0x02)));
17416       else if (optimize_insn_for_size_p ())
17417         FAIL;
17418       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17419         ix86_expand_floorceil (operand0, operand1, false);
17420       else
17421         ix86_expand_floorceildf_32 (operand0, operand1, false);
17422     }
17423   else
17424     {
17425       rtx op0, op1;
17426
17427       if (optimize_insn_for_size_p ())
17428         FAIL;
17429
17430       op0 = gen_reg_rtx (XFmode);
17431       op1 = gen_reg_rtx (XFmode);
17432       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17433       emit_insn (gen_frndintxf2_ceil (op0, op1));
17434
17435       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17436     }
17437   DONE;
17438 })
17439
17440 (define_insn_and_split "*fist<mode>2_ceil_1"
17441   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17442         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17443          UNSPEC_FIST_CEIL))
17444    (clobber (reg:CC FLAGS_REG))]
17445   "TARGET_USE_FANCY_MATH_387
17446    && flag_unsafe_math_optimizations
17447    && can_create_pseudo_p ()"
17448   "#"
17449   "&& 1"
17450   [(const_int 0)]
17451 {
17452   ix86_optimize_mode_switching[I387_CEIL] = 1;
17453
17454   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17455   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17456   if (memory_operand (operands[0], VOIDmode))
17457     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17458                                      operands[2], operands[3]));
17459   else
17460     {
17461       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17462       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17463                                                  operands[2], operands[3],
17464                                                  operands[4]));
17465     }
17466   DONE;
17467 }
17468   [(set_attr "type" "fistp")
17469    (set_attr "i387_cw" "ceil")
17470    (set_attr "mode" "<MODE>")])
17471
17472 (define_insn "fistdi2_ceil"
17473   [(set (match_operand:DI 0 "memory_operand" "=m")
17474         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17475          UNSPEC_FIST_CEIL))
17476    (use (match_operand:HI 2 "memory_operand" "m"))
17477    (use (match_operand:HI 3 "memory_operand" "m"))
17478    (clobber (match_scratch:XF 4 "=&1f"))]
17479   "TARGET_USE_FANCY_MATH_387
17480    && flag_unsafe_math_optimizations"
17481   "* return output_fix_trunc (insn, operands, 0);"
17482   [(set_attr "type" "fistp")
17483    (set_attr "i387_cw" "ceil")
17484    (set_attr "mode" "DI")])
17485
17486 (define_insn "fistdi2_ceil_with_temp"
17487   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17488         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17489          UNSPEC_FIST_CEIL))
17490    (use (match_operand:HI 2 "memory_operand" "m,m"))
17491    (use (match_operand:HI 3 "memory_operand" "m,m"))
17492    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17493    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17494   "TARGET_USE_FANCY_MATH_387
17495    && flag_unsafe_math_optimizations"
17496   "#"
17497   [(set_attr "type" "fistp")
17498    (set_attr "i387_cw" "ceil")
17499    (set_attr "mode" "DI")])
17500
17501 (define_split
17502   [(set (match_operand:DI 0 "register_operand" "")
17503         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17504          UNSPEC_FIST_CEIL))
17505    (use (match_operand:HI 2 "memory_operand" ""))
17506    (use (match_operand:HI 3 "memory_operand" ""))
17507    (clobber (match_operand:DI 4 "memory_operand" ""))
17508    (clobber (match_scratch 5 ""))]
17509   "reload_completed"
17510   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17511               (use (match_dup 2))
17512               (use (match_dup 3))
17513               (clobber (match_dup 5))])
17514    (set (match_dup 0) (match_dup 4))]
17515   "")
17516
17517 (define_split
17518   [(set (match_operand:DI 0 "memory_operand" "")
17519         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17520          UNSPEC_FIST_CEIL))
17521    (use (match_operand:HI 2 "memory_operand" ""))
17522    (use (match_operand:HI 3 "memory_operand" ""))
17523    (clobber (match_operand:DI 4 "memory_operand" ""))
17524    (clobber (match_scratch 5 ""))]
17525   "reload_completed"
17526   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17527               (use (match_dup 2))
17528               (use (match_dup 3))
17529               (clobber (match_dup 5))])]
17530   "")
17531
17532 (define_insn "fist<mode>2_ceil"
17533   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17534         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17535          UNSPEC_FIST_CEIL))
17536    (use (match_operand:HI 2 "memory_operand" "m"))
17537    (use (match_operand:HI 3 "memory_operand" "m"))]
17538   "TARGET_USE_FANCY_MATH_387
17539    && flag_unsafe_math_optimizations"
17540   "* return output_fix_trunc (insn, operands, 0);"
17541   [(set_attr "type" "fistp")
17542    (set_attr "i387_cw" "ceil")
17543    (set_attr "mode" "<MODE>")])
17544
17545 (define_insn "fist<mode>2_ceil_with_temp"
17546   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17547         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17548          UNSPEC_FIST_CEIL))
17549    (use (match_operand:HI 2 "memory_operand" "m,m"))
17550    (use (match_operand:HI 3 "memory_operand" "m,m"))
17551    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17552   "TARGET_USE_FANCY_MATH_387
17553    && flag_unsafe_math_optimizations"
17554   "#"
17555   [(set_attr "type" "fistp")
17556    (set_attr "i387_cw" "ceil")
17557    (set_attr "mode" "<MODE>")])
17558
17559 (define_split
17560   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17561         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17562          UNSPEC_FIST_CEIL))
17563    (use (match_operand:HI 2 "memory_operand" ""))
17564    (use (match_operand:HI 3 "memory_operand" ""))
17565    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17566   "reload_completed"
17567   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17568                                   UNSPEC_FIST_CEIL))
17569               (use (match_dup 2))
17570               (use (match_dup 3))])
17571    (set (match_dup 0) (match_dup 4))]
17572   "")
17573
17574 (define_split
17575   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17576         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17577          UNSPEC_FIST_CEIL))
17578    (use (match_operand:HI 2 "memory_operand" ""))
17579    (use (match_operand:HI 3 "memory_operand" ""))
17580    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17581   "reload_completed"
17582   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17583                                   UNSPEC_FIST_CEIL))
17584               (use (match_dup 2))
17585               (use (match_dup 3))])]
17586   "")
17587
17588 (define_expand "lceilxf<mode>2"
17589   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17590                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17591                     UNSPEC_FIST_CEIL))
17592               (clobber (reg:CC FLAGS_REG))])]
17593   "TARGET_USE_FANCY_MATH_387
17594    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17595    && flag_unsafe_math_optimizations"
17596   "")
17597
17598 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17599   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17600    (match_operand:MODEF 1 "register_operand" "")]
17601   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17602    && !flag_trapping_math"
17603 {
17604   ix86_expand_lfloorceil (operand0, operand1, false);
17605   DONE;
17606 })
17607
17608 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17609 (define_insn_and_split "frndintxf2_trunc"
17610   [(set (match_operand:XF 0 "register_operand" "")
17611         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17612          UNSPEC_FRNDINT_TRUNC))
17613    (clobber (reg:CC FLAGS_REG))]
17614   "TARGET_USE_FANCY_MATH_387
17615    && flag_unsafe_math_optimizations
17616    && can_create_pseudo_p ()"
17617   "#"
17618   "&& 1"
17619   [(const_int 0)]
17620 {
17621   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17622
17623   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17624   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17625
17626   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17627                                         operands[2], operands[3]));
17628   DONE;
17629 }
17630   [(set_attr "type" "frndint")
17631    (set_attr "i387_cw" "trunc")
17632    (set_attr "mode" "XF")])
17633
17634 (define_insn "frndintxf2_trunc_i387"
17635   [(set (match_operand:XF 0 "register_operand" "=f")
17636         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17637          UNSPEC_FRNDINT_TRUNC))
17638    (use (match_operand:HI 2 "memory_operand" "m"))
17639    (use (match_operand:HI 3 "memory_operand" "m"))]
17640   "TARGET_USE_FANCY_MATH_387
17641    && flag_unsafe_math_optimizations"
17642   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17643   [(set_attr "type" "frndint")
17644    (set_attr "i387_cw" "trunc")
17645    (set_attr "mode" "XF")])
17646
17647 (define_expand "btruncxf2"
17648   [(use (match_operand:XF 0 "register_operand" ""))
17649    (use (match_operand:XF 1 "register_operand" ""))]
17650   "TARGET_USE_FANCY_MATH_387
17651    && flag_unsafe_math_optimizations"
17652 {
17653   if (optimize_insn_for_size_p ())
17654     FAIL;
17655   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17656   DONE;
17657 })
17658
17659 (define_expand "btrunc<mode>2"
17660   [(use (match_operand:MODEF 0 "register_operand" ""))
17661    (use (match_operand:MODEF 1 "register_operand" ""))]
17662   "(TARGET_USE_FANCY_MATH_387
17663     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17664         || TARGET_MIX_SSE_I387)
17665     && flag_unsafe_math_optimizations)
17666    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17667        && !flag_trapping_math)"
17668 {
17669   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17670       && !flag_trapping_math
17671       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17672     {
17673       if (TARGET_ROUND)
17674         emit_insn (gen_sse4_1_round<mode>2
17675                    (operands[0], operands[1], GEN_INT (0x03)));
17676       else if (optimize_insn_for_size_p ())
17677         FAIL;
17678       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17679         ix86_expand_trunc (operand0, operand1);
17680       else
17681         ix86_expand_truncdf_32 (operand0, operand1);
17682     }
17683   else
17684     {
17685       rtx op0, op1;
17686
17687       if (optimize_insn_for_size_p ())
17688         FAIL;
17689
17690       op0 = gen_reg_rtx (XFmode);
17691       op1 = gen_reg_rtx (XFmode);
17692       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17693       emit_insn (gen_frndintxf2_trunc (op0, op1));
17694
17695       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17696     }
17697   DONE;
17698 })
17699
17700 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17701 (define_insn_and_split "frndintxf2_mask_pm"
17702   [(set (match_operand:XF 0 "register_operand" "")
17703         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17704          UNSPEC_FRNDINT_MASK_PM))
17705    (clobber (reg:CC FLAGS_REG))]
17706   "TARGET_USE_FANCY_MATH_387
17707    && flag_unsafe_math_optimizations
17708    && can_create_pseudo_p ()"
17709   "#"
17710   "&& 1"
17711   [(const_int 0)]
17712 {
17713   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17714
17715   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17716   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17717
17718   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17719                                           operands[2], operands[3]));
17720   DONE;
17721 }
17722   [(set_attr "type" "frndint")
17723    (set_attr "i387_cw" "mask_pm")
17724    (set_attr "mode" "XF")])
17725
17726 (define_insn "frndintxf2_mask_pm_i387"
17727   [(set (match_operand:XF 0 "register_operand" "=f")
17728         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17729          UNSPEC_FRNDINT_MASK_PM))
17730    (use (match_operand:HI 2 "memory_operand" "m"))
17731    (use (match_operand:HI 3 "memory_operand" "m"))]
17732   "TARGET_USE_FANCY_MATH_387
17733    && flag_unsafe_math_optimizations"
17734   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17735   [(set_attr "type" "frndint")
17736    (set_attr "i387_cw" "mask_pm")
17737    (set_attr "mode" "XF")])
17738
17739 (define_expand "nearbyintxf2"
17740   [(use (match_operand:XF 0 "register_operand" ""))
17741    (use (match_operand:XF 1 "register_operand" ""))]
17742   "TARGET_USE_FANCY_MATH_387
17743    && flag_unsafe_math_optimizations"
17744 {
17745   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17746
17747   DONE;
17748 })
17749
17750 (define_expand "nearbyint<mode>2"
17751   [(use (match_operand:MODEF 0 "register_operand" ""))
17752    (use (match_operand:MODEF 1 "register_operand" ""))]
17753   "TARGET_USE_FANCY_MATH_387
17754    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17755        || TARGET_MIX_SSE_I387)
17756    && flag_unsafe_math_optimizations"
17757 {
17758   rtx op0 = gen_reg_rtx (XFmode);
17759   rtx op1 = gen_reg_rtx (XFmode);
17760
17761   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17762   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17763
17764   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17765   DONE;
17766 })
17767
17768 (define_insn "fxam<mode>2_i387"
17769   [(set (match_operand:HI 0 "register_operand" "=a")
17770         (unspec:HI
17771           [(match_operand:X87MODEF 1 "register_operand" "f")]
17772           UNSPEC_FXAM))]
17773   "TARGET_USE_FANCY_MATH_387"
17774   "fxam\n\tfnstsw\t%0"
17775   [(set_attr "type" "multi")
17776    (set_attr "length" "4")
17777    (set_attr "unit" "i387")
17778    (set_attr "mode" "<MODE>")])
17779
17780 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17781   [(set (match_operand:HI 0 "register_operand" "")
17782         (unspec:HI
17783           [(match_operand:MODEF 1 "memory_operand" "")]
17784           UNSPEC_FXAM_MEM))]
17785   "TARGET_USE_FANCY_MATH_387
17786    && can_create_pseudo_p ()"
17787   "#"
17788   "&& 1"
17789   [(set (match_dup 2)(match_dup 1))
17790    (set (match_dup 0)
17791         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17792 {
17793   operands[2] = gen_reg_rtx (<MODE>mode);
17794
17795   MEM_VOLATILE_P (operands[1]) = 1;
17796 }
17797   [(set_attr "type" "multi")
17798    (set_attr "unit" "i387")
17799    (set_attr "mode" "<MODE>")])
17800
17801 (define_expand "isinfxf2"
17802   [(use (match_operand:SI 0 "register_operand" ""))
17803    (use (match_operand:XF 1 "register_operand" ""))]
17804   "TARGET_USE_FANCY_MATH_387
17805    && TARGET_C99_FUNCTIONS"
17806 {
17807   rtx mask = GEN_INT (0x45);
17808   rtx val = GEN_INT (0x05);
17809
17810   rtx cond;
17811
17812   rtx scratch = gen_reg_rtx (HImode);
17813   rtx res = gen_reg_rtx (QImode);
17814
17815   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17816
17817   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17818   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17819   cond = gen_rtx_fmt_ee (EQ, QImode,
17820                          gen_rtx_REG (CCmode, FLAGS_REG),
17821                          const0_rtx);
17822   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17823   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17824   DONE;
17825 })
17826
17827 (define_expand "isinf<mode>2"
17828   [(use (match_operand:SI 0 "register_operand" ""))
17829    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17830   "TARGET_USE_FANCY_MATH_387
17831    && TARGET_C99_FUNCTIONS
17832    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17833 {
17834   rtx mask = GEN_INT (0x45);
17835   rtx val = GEN_INT (0x05);
17836
17837   rtx cond;
17838
17839   rtx scratch = gen_reg_rtx (HImode);
17840   rtx res = gen_reg_rtx (QImode);
17841
17842   /* Remove excess precision by forcing value through memory. */
17843   if (memory_operand (operands[1], VOIDmode))
17844     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17845   else
17846     {
17847       enum ix86_stack_slot slot = (virtuals_instantiated
17848                                    ? SLOT_TEMP
17849                                    : SLOT_VIRTUAL);
17850       rtx temp = assign_386_stack_local (<MODE>mode, slot);
17851
17852       emit_move_insn (temp, operands[1]);
17853       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17854     }
17855
17856   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17857   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17858   cond = gen_rtx_fmt_ee (EQ, QImode,
17859                          gen_rtx_REG (CCmode, FLAGS_REG),
17860                          const0_rtx);
17861   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17862   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17863   DONE;
17864 })
17865
17866 (define_expand "signbit<mode>2"
17867   [(use (match_operand:SI 0 "register_operand" ""))
17868    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17869   "TARGET_USE_FANCY_MATH_387
17870    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17871 {
17872   rtx mask = GEN_INT (0x0200);
17873
17874   rtx scratch = gen_reg_rtx (HImode);
17875
17876   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17877   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17878   DONE;
17879 })
17880 \f
17881 ;; Block operation instructions
17882
17883 (define_insn "cld"
17884   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17885   ""
17886   "cld"
17887   [(set_attr "length" "1")
17888    (set_attr "length_immediate" "0")
17889    (set_attr "modrm" "0")])
17890
17891 (define_expand "movmemsi"
17892   [(use (match_operand:BLK 0 "memory_operand" ""))
17893    (use (match_operand:BLK 1 "memory_operand" ""))
17894    (use (match_operand:SI 2 "nonmemory_operand" ""))
17895    (use (match_operand:SI 3 "const_int_operand" ""))
17896    (use (match_operand:SI 4 "const_int_operand" ""))
17897    (use (match_operand:SI 5 "const_int_operand" ""))]
17898   ""
17899 {
17900  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17901                          operands[4], operands[5]))
17902    DONE;
17903  else
17904    FAIL;
17905 })
17906
17907 (define_expand "movmemdi"
17908   [(use (match_operand:BLK 0 "memory_operand" ""))
17909    (use (match_operand:BLK 1 "memory_operand" ""))
17910    (use (match_operand:DI 2 "nonmemory_operand" ""))
17911    (use (match_operand:DI 3 "const_int_operand" ""))
17912    (use (match_operand:SI 4 "const_int_operand" ""))
17913    (use (match_operand:SI 5 "const_int_operand" ""))]
17914   "TARGET_64BIT"
17915 {
17916  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17917                          operands[4], operands[5]))
17918    DONE;
17919  else
17920    FAIL;
17921 })
17922
17923 ;; Most CPUs don't like single string operations
17924 ;; Handle this case here to simplify previous expander.
17925
17926 (define_expand "strmov"
17927   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17928    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17929    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17930               (clobber (reg:CC FLAGS_REG))])
17931    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17932               (clobber (reg:CC FLAGS_REG))])]
17933   ""
17934 {
17935   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17936
17937   /* If .md ever supports :P for Pmode, these can be directly
17938      in the pattern above.  */
17939   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17940   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17941
17942   /* Can't use this if the user has appropriated esi or edi.  */
17943   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17944       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17945     {
17946       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17947                                       operands[2], operands[3],
17948                                       operands[5], operands[6]));
17949       DONE;
17950     }
17951
17952   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17953 })
17954
17955 (define_expand "strmov_singleop"
17956   [(parallel [(set (match_operand 1 "memory_operand" "")
17957                    (match_operand 3 "memory_operand" ""))
17958               (set (match_operand 0 "register_operand" "")
17959                    (match_operand 4 "" ""))
17960               (set (match_operand 2 "register_operand" "")
17961                    (match_operand 5 "" ""))])]
17962   ""
17963   "ix86_current_function_needs_cld = 1;")
17964
17965 (define_insn "*strmovdi_rex_1"
17966   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17967         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17968    (set (match_operand:DI 0 "register_operand" "=D")
17969         (plus:DI (match_dup 2)
17970                  (const_int 8)))
17971    (set (match_operand:DI 1 "register_operand" "=S")
17972         (plus:DI (match_dup 3)
17973                  (const_int 8)))]
17974   "TARGET_64BIT"
17975   "movsq"
17976   [(set_attr "type" "str")
17977    (set_attr "mode" "DI")
17978    (set_attr "memory" "both")])
17979
17980 (define_insn "*strmovsi_1"
17981   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17982         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17983    (set (match_operand:SI 0 "register_operand" "=D")
17984         (plus:SI (match_dup 2)
17985                  (const_int 4)))
17986    (set (match_operand:SI 1 "register_operand" "=S")
17987         (plus:SI (match_dup 3)
17988                  (const_int 4)))]
17989   "!TARGET_64BIT"
17990   "movs{l|d}"
17991   [(set_attr "type" "str")
17992    (set_attr "mode" "SI")
17993    (set_attr "memory" "both")])
17994
17995 (define_insn "*strmovsi_rex_1"
17996   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17997         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17998    (set (match_operand:DI 0 "register_operand" "=D")
17999         (plus:DI (match_dup 2)
18000                  (const_int 4)))
18001    (set (match_operand:DI 1 "register_operand" "=S")
18002         (plus:DI (match_dup 3)
18003                  (const_int 4)))]
18004   "TARGET_64BIT"
18005   "movs{l|d}"
18006   [(set_attr "type" "str")
18007    (set_attr "mode" "SI")
18008    (set_attr "memory" "both")])
18009
18010 (define_insn "*strmovhi_1"
18011   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18012         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18013    (set (match_operand:SI 0 "register_operand" "=D")
18014         (plus:SI (match_dup 2)
18015                  (const_int 2)))
18016    (set (match_operand:SI 1 "register_operand" "=S")
18017         (plus:SI (match_dup 3)
18018                  (const_int 2)))]
18019   "!TARGET_64BIT"
18020   "movsw"
18021   [(set_attr "type" "str")
18022    (set_attr "memory" "both")
18023    (set_attr "mode" "HI")])
18024
18025 (define_insn "*strmovhi_rex_1"
18026   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18027         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18028    (set (match_operand:DI 0 "register_operand" "=D")
18029         (plus:DI (match_dup 2)
18030                  (const_int 2)))
18031    (set (match_operand:DI 1 "register_operand" "=S")
18032         (plus:DI (match_dup 3)
18033                  (const_int 2)))]
18034   "TARGET_64BIT"
18035   "movsw"
18036   [(set_attr "type" "str")
18037    (set_attr "memory" "both")
18038    (set_attr "mode" "HI")])
18039
18040 (define_insn "*strmovqi_1"
18041   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18042         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18043    (set (match_operand:SI 0 "register_operand" "=D")
18044         (plus:SI (match_dup 2)
18045                  (const_int 1)))
18046    (set (match_operand:SI 1 "register_operand" "=S")
18047         (plus:SI (match_dup 3)
18048                  (const_int 1)))]
18049   "!TARGET_64BIT"
18050   "movsb"
18051   [(set_attr "type" "str")
18052    (set_attr "memory" "both")
18053    (set_attr "mode" "QI")])
18054
18055 (define_insn "*strmovqi_rex_1"
18056   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18057         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18058    (set (match_operand:DI 0 "register_operand" "=D")
18059         (plus:DI (match_dup 2)
18060                  (const_int 1)))
18061    (set (match_operand:DI 1 "register_operand" "=S")
18062         (plus:DI (match_dup 3)
18063                  (const_int 1)))]
18064   "TARGET_64BIT"
18065   "movsb"
18066   [(set_attr "type" "str")
18067    (set_attr "memory" "both")
18068    (set_attr "prefix_rex" "0")
18069    (set_attr "mode" "QI")])
18070
18071 (define_expand "rep_mov"
18072   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18073               (set (match_operand 0 "register_operand" "")
18074                    (match_operand 5 "" ""))
18075               (set (match_operand 2 "register_operand" "")
18076                    (match_operand 6 "" ""))
18077               (set (match_operand 1 "memory_operand" "")
18078                    (match_operand 3 "memory_operand" ""))
18079               (use (match_dup 4))])]
18080   ""
18081   "ix86_current_function_needs_cld = 1;")
18082
18083 (define_insn "*rep_movdi_rex64"
18084   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18085    (set (match_operand:DI 0 "register_operand" "=D")
18086         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18087                             (const_int 3))
18088                  (match_operand:DI 3 "register_operand" "0")))
18089    (set (match_operand:DI 1 "register_operand" "=S")
18090         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18091                  (match_operand:DI 4 "register_operand" "1")))
18092    (set (mem:BLK (match_dup 3))
18093         (mem:BLK (match_dup 4)))
18094    (use (match_dup 5))]
18095   "TARGET_64BIT"
18096   "rep movsq"
18097   [(set_attr "type" "str")
18098    (set_attr "prefix_rep" "1")
18099    (set_attr "memory" "both")
18100    (set_attr "mode" "DI")])
18101
18102 (define_insn "*rep_movsi"
18103   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18104    (set (match_operand:SI 0 "register_operand" "=D")
18105         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18106                             (const_int 2))
18107                  (match_operand:SI 3 "register_operand" "0")))
18108    (set (match_operand:SI 1 "register_operand" "=S")
18109         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18110                  (match_operand:SI 4 "register_operand" "1")))
18111    (set (mem:BLK (match_dup 3))
18112         (mem:BLK (match_dup 4)))
18113    (use (match_dup 5))]
18114   "!TARGET_64BIT"
18115   "rep movs{l|d}"
18116   [(set_attr "type" "str")
18117    (set_attr "prefix_rep" "1")
18118    (set_attr "memory" "both")
18119    (set_attr "mode" "SI")])
18120
18121 (define_insn "*rep_movsi_rex64"
18122   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18123    (set (match_operand:DI 0 "register_operand" "=D")
18124         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18125                             (const_int 2))
18126                  (match_operand:DI 3 "register_operand" "0")))
18127    (set (match_operand:DI 1 "register_operand" "=S")
18128         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18129                  (match_operand:DI 4 "register_operand" "1")))
18130    (set (mem:BLK (match_dup 3))
18131         (mem:BLK (match_dup 4)))
18132    (use (match_dup 5))]
18133   "TARGET_64BIT"
18134   "rep movs{l|d}"
18135   [(set_attr "type" "str")
18136    (set_attr "prefix_rep" "1")
18137    (set_attr "memory" "both")
18138    (set_attr "mode" "SI")])
18139
18140 (define_insn "*rep_movqi"
18141   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18142    (set (match_operand:SI 0 "register_operand" "=D")
18143         (plus:SI (match_operand:SI 3 "register_operand" "0")
18144                  (match_operand:SI 5 "register_operand" "2")))
18145    (set (match_operand:SI 1 "register_operand" "=S")
18146         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18147    (set (mem:BLK (match_dup 3))
18148         (mem:BLK (match_dup 4)))
18149    (use (match_dup 5))]
18150   "!TARGET_64BIT"
18151   "rep movsb"
18152   [(set_attr "type" "str")
18153    (set_attr "prefix_rep" "1")
18154    (set_attr "memory" "both")
18155    (set_attr "mode" "SI")])
18156
18157 (define_insn "*rep_movqi_rex64"
18158   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18159    (set (match_operand:DI 0 "register_operand" "=D")
18160         (plus:DI (match_operand:DI 3 "register_operand" "0")
18161                  (match_operand:DI 5 "register_operand" "2")))
18162    (set (match_operand:DI 1 "register_operand" "=S")
18163         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18164    (set (mem:BLK (match_dup 3))
18165         (mem:BLK (match_dup 4)))
18166    (use (match_dup 5))]
18167   "TARGET_64BIT"
18168   "rep movsb"
18169   [(set_attr "type" "str")
18170    (set_attr "prefix_rep" "1")
18171    (set_attr "memory" "both")
18172    (set_attr "mode" "SI")])
18173
18174 (define_expand "setmemsi"
18175    [(use (match_operand:BLK 0 "memory_operand" ""))
18176     (use (match_operand:SI 1 "nonmemory_operand" ""))
18177     (use (match_operand 2 "const_int_operand" ""))
18178     (use (match_operand 3 "const_int_operand" ""))
18179     (use (match_operand:SI 4 "const_int_operand" ""))
18180     (use (match_operand:SI 5 "const_int_operand" ""))]
18181   ""
18182 {
18183  if (ix86_expand_setmem (operands[0], operands[1],
18184                          operands[2], operands[3],
18185                          operands[4], operands[5]))
18186    DONE;
18187  else
18188    FAIL;
18189 })
18190
18191 (define_expand "setmemdi"
18192    [(use (match_operand:BLK 0 "memory_operand" ""))
18193     (use (match_operand:DI 1 "nonmemory_operand" ""))
18194     (use (match_operand 2 "const_int_operand" ""))
18195     (use (match_operand 3 "const_int_operand" ""))
18196     (use (match_operand 4 "const_int_operand" ""))
18197     (use (match_operand 5 "const_int_operand" ""))]
18198   "TARGET_64BIT"
18199 {
18200  if (ix86_expand_setmem (operands[0], operands[1],
18201                          operands[2], operands[3],
18202                          operands[4], operands[5]))
18203    DONE;
18204  else
18205    FAIL;
18206 })
18207
18208 ;; Most CPUs don't like single string operations
18209 ;; Handle this case here to simplify previous expander.
18210
18211 (define_expand "strset"
18212   [(set (match_operand 1 "memory_operand" "")
18213         (match_operand 2 "register_operand" ""))
18214    (parallel [(set (match_operand 0 "register_operand" "")
18215                    (match_dup 3))
18216               (clobber (reg:CC FLAGS_REG))])]
18217   ""
18218 {
18219   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18220     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18221
18222   /* If .md ever supports :P for Pmode, this can be directly
18223      in the pattern above.  */
18224   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18225                               GEN_INT (GET_MODE_SIZE (GET_MODE
18226                                                       (operands[2]))));
18227   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18228     {
18229       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18230                                       operands[3]));
18231       DONE;
18232     }
18233 })
18234
18235 (define_expand "strset_singleop"
18236   [(parallel [(set (match_operand 1 "memory_operand" "")
18237                    (match_operand 2 "register_operand" ""))
18238               (set (match_operand 0 "register_operand" "")
18239                    (match_operand 3 "" ""))])]
18240   ""
18241   "ix86_current_function_needs_cld = 1;")
18242
18243 (define_insn "*strsetdi_rex_1"
18244   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18245         (match_operand:DI 2 "register_operand" "a"))
18246    (set (match_operand:DI 0 "register_operand" "=D")
18247         (plus:DI (match_dup 1)
18248                  (const_int 8)))]
18249   "TARGET_64BIT"
18250   "stosq"
18251   [(set_attr "type" "str")
18252    (set_attr "memory" "store")
18253    (set_attr "mode" "DI")])
18254
18255 (define_insn "*strsetsi_1"
18256   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18257         (match_operand:SI 2 "register_operand" "a"))
18258    (set (match_operand:SI 0 "register_operand" "=D")
18259         (plus:SI (match_dup 1)
18260                  (const_int 4)))]
18261   "!TARGET_64BIT"
18262   "stos{l|d}"
18263   [(set_attr "type" "str")
18264    (set_attr "memory" "store")
18265    (set_attr "mode" "SI")])
18266
18267 (define_insn "*strsetsi_rex_1"
18268   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18269         (match_operand:SI 2 "register_operand" "a"))
18270    (set (match_operand:DI 0 "register_operand" "=D")
18271         (plus:DI (match_dup 1)
18272                  (const_int 4)))]
18273   "TARGET_64BIT"
18274   "stos{l|d}"
18275   [(set_attr "type" "str")
18276    (set_attr "memory" "store")
18277    (set_attr "mode" "SI")])
18278
18279 (define_insn "*strsethi_1"
18280   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18281         (match_operand:HI 2 "register_operand" "a"))
18282    (set (match_operand:SI 0 "register_operand" "=D")
18283         (plus:SI (match_dup 1)
18284                  (const_int 2)))]
18285   "!TARGET_64BIT"
18286   "stosw"
18287   [(set_attr "type" "str")
18288    (set_attr "memory" "store")
18289    (set_attr "mode" "HI")])
18290
18291 (define_insn "*strsethi_rex_1"
18292   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18293         (match_operand:HI 2 "register_operand" "a"))
18294    (set (match_operand:DI 0 "register_operand" "=D")
18295         (plus:DI (match_dup 1)
18296                  (const_int 2)))]
18297   "TARGET_64BIT"
18298   "stosw"
18299   [(set_attr "type" "str")
18300    (set_attr "memory" "store")
18301    (set_attr "mode" "HI")])
18302
18303 (define_insn "*strsetqi_1"
18304   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18305         (match_operand:QI 2 "register_operand" "a"))
18306    (set (match_operand:SI 0 "register_operand" "=D")
18307         (plus:SI (match_dup 1)
18308                  (const_int 1)))]
18309   "!TARGET_64BIT"
18310   "stosb"
18311   [(set_attr "type" "str")
18312    (set_attr "memory" "store")
18313    (set_attr "mode" "QI")])
18314
18315 (define_insn "*strsetqi_rex_1"
18316   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18317         (match_operand:QI 2 "register_operand" "a"))
18318    (set (match_operand:DI 0 "register_operand" "=D")
18319         (plus:DI (match_dup 1)
18320                  (const_int 1)))]
18321   "TARGET_64BIT"
18322   "stosb"
18323   [(set_attr "type" "str")
18324    (set_attr "memory" "store")
18325    (set_attr "prefix_rex" "0")
18326    (set_attr "mode" "QI")])
18327
18328 (define_expand "rep_stos"
18329   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18330               (set (match_operand 0 "register_operand" "")
18331                    (match_operand 4 "" ""))
18332               (set (match_operand 2 "memory_operand" "") (const_int 0))
18333               (use (match_operand 3 "register_operand" ""))
18334               (use (match_dup 1))])]
18335   ""
18336   "ix86_current_function_needs_cld = 1;")
18337
18338 (define_insn "*rep_stosdi_rex64"
18339   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18340    (set (match_operand:DI 0 "register_operand" "=D")
18341         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18342                             (const_int 3))
18343                  (match_operand:DI 3 "register_operand" "0")))
18344    (set (mem:BLK (match_dup 3))
18345         (const_int 0))
18346    (use (match_operand:DI 2 "register_operand" "a"))
18347    (use (match_dup 4))]
18348   "TARGET_64BIT"
18349   "rep stosq"
18350   [(set_attr "type" "str")
18351    (set_attr "prefix_rep" "1")
18352    (set_attr "memory" "store")
18353    (set_attr "mode" "DI")])
18354
18355 (define_insn "*rep_stossi"
18356   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18357    (set (match_operand:SI 0 "register_operand" "=D")
18358         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18359                             (const_int 2))
18360                  (match_operand:SI 3 "register_operand" "0")))
18361    (set (mem:BLK (match_dup 3))
18362         (const_int 0))
18363    (use (match_operand:SI 2 "register_operand" "a"))
18364    (use (match_dup 4))]
18365   "!TARGET_64BIT"
18366   "rep stos{l|d}"
18367   [(set_attr "type" "str")
18368    (set_attr "prefix_rep" "1")
18369    (set_attr "memory" "store")
18370    (set_attr "mode" "SI")])
18371
18372 (define_insn "*rep_stossi_rex64"
18373   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18374    (set (match_operand:DI 0 "register_operand" "=D")
18375         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18376                             (const_int 2))
18377                  (match_operand:DI 3 "register_operand" "0")))
18378    (set (mem:BLK (match_dup 3))
18379         (const_int 0))
18380    (use (match_operand:SI 2 "register_operand" "a"))
18381    (use (match_dup 4))]
18382   "TARGET_64BIT"
18383   "rep stos{l|d}"
18384   [(set_attr "type" "str")
18385    (set_attr "prefix_rep" "1")
18386    (set_attr "memory" "store")
18387    (set_attr "mode" "SI")])
18388
18389 (define_insn "*rep_stosqi"
18390   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18391    (set (match_operand:SI 0 "register_operand" "=D")
18392         (plus:SI (match_operand:SI 3 "register_operand" "0")
18393                  (match_operand:SI 4 "register_operand" "1")))
18394    (set (mem:BLK (match_dup 3))
18395         (const_int 0))
18396    (use (match_operand:QI 2 "register_operand" "a"))
18397    (use (match_dup 4))]
18398   "!TARGET_64BIT"
18399   "rep stosb"
18400   [(set_attr "type" "str")
18401    (set_attr "prefix_rep" "1")
18402    (set_attr "memory" "store")
18403    (set_attr "mode" "QI")])
18404
18405 (define_insn "*rep_stosqi_rex64"
18406   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18407    (set (match_operand:DI 0 "register_operand" "=D")
18408         (plus:DI (match_operand:DI 3 "register_operand" "0")
18409                  (match_operand:DI 4 "register_operand" "1")))
18410    (set (mem:BLK (match_dup 3))
18411         (const_int 0))
18412    (use (match_operand:QI 2 "register_operand" "a"))
18413    (use (match_dup 4))]
18414   "TARGET_64BIT"
18415   "rep stosb"
18416   [(set_attr "type" "str")
18417    (set_attr "prefix_rep" "1")
18418    (set_attr "memory" "store")
18419    (set_attr "prefix_rex" "0")
18420    (set_attr "mode" "QI")])
18421
18422 (define_expand "cmpstrnsi"
18423   [(set (match_operand:SI 0 "register_operand" "")
18424         (compare:SI (match_operand:BLK 1 "general_operand" "")
18425                     (match_operand:BLK 2 "general_operand" "")))
18426    (use (match_operand 3 "general_operand" ""))
18427    (use (match_operand 4 "immediate_operand" ""))]
18428   ""
18429 {
18430   rtx addr1, addr2, out, outlow, count, countreg, align;
18431
18432   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18433     FAIL;
18434
18435   /* Can't use this if the user has appropriated esi or edi.  */
18436   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18437     FAIL;
18438
18439   out = operands[0];
18440   if (!REG_P (out))
18441     out = gen_reg_rtx (SImode);
18442
18443   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18444   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18445   if (addr1 != XEXP (operands[1], 0))
18446     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18447   if (addr2 != XEXP (operands[2], 0))
18448     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18449
18450   count = operands[3];
18451   countreg = ix86_zero_extend_to_Pmode (count);
18452
18453   /* %%% Iff we are testing strict equality, we can use known alignment
18454      to good advantage.  This may be possible with combine, particularly
18455      once cc0 is dead.  */
18456   align = operands[4];
18457
18458   if (CONST_INT_P (count))
18459     {
18460       if (INTVAL (count) == 0)
18461         {
18462           emit_move_insn (operands[0], const0_rtx);
18463           DONE;
18464         }
18465       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18466                                      operands[1], operands[2]));
18467     }
18468   else
18469     {
18470       rtx (*cmp_insn)(rtx, rtx);
18471
18472       if (TARGET_64BIT)
18473         cmp_insn = gen_cmpdi_1;
18474       else
18475         cmp_insn = gen_cmpsi_1;
18476       emit_insn (cmp_insn (countreg, countreg));
18477       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18478                                   operands[1], operands[2]));
18479     }
18480
18481   outlow = gen_lowpart (QImode, out);
18482   emit_insn (gen_cmpintqi (outlow));
18483   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18484
18485   if (operands[0] != out)
18486     emit_move_insn (operands[0], out);
18487
18488   DONE;
18489 })
18490
18491 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18492
18493 (define_expand "cmpintqi"
18494   [(set (match_dup 1)
18495         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18496    (set (match_dup 2)
18497         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18498    (parallel [(set (match_operand:QI 0 "register_operand" "")
18499                    (minus:QI (match_dup 1)
18500                              (match_dup 2)))
18501               (clobber (reg:CC FLAGS_REG))])]
18502   ""
18503   "operands[1] = gen_reg_rtx (QImode);
18504    operands[2] = gen_reg_rtx (QImode);")
18505
18506 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18507 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18508
18509 (define_expand "cmpstrnqi_nz_1"
18510   [(parallel [(set (reg:CC FLAGS_REG)
18511                    (compare:CC (match_operand 4 "memory_operand" "")
18512                                (match_operand 5 "memory_operand" "")))
18513               (use (match_operand 2 "register_operand" ""))
18514               (use (match_operand:SI 3 "immediate_operand" ""))
18515               (clobber (match_operand 0 "register_operand" ""))
18516               (clobber (match_operand 1 "register_operand" ""))
18517               (clobber (match_dup 2))])]
18518   ""
18519   "ix86_current_function_needs_cld = 1;")
18520
18521 (define_insn "*cmpstrnqi_nz_1"
18522   [(set (reg:CC FLAGS_REG)
18523         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18524                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18525    (use (match_operand:SI 6 "register_operand" "2"))
18526    (use (match_operand:SI 3 "immediate_operand" "i"))
18527    (clobber (match_operand:SI 0 "register_operand" "=S"))
18528    (clobber (match_operand:SI 1 "register_operand" "=D"))
18529    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18530   "!TARGET_64BIT"
18531   "repz cmpsb"
18532   [(set_attr "type" "str")
18533    (set_attr "mode" "QI")
18534    (set_attr "prefix_rep" "1")])
18535
18536 (define_insn "*cmpstrnqi_nz_rex_1"
18537   [(set (reg:CC FLAGS_REG)
18538         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18539                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18540    (use (match_operand:DI 6 "register_operand" "2"))
18541    (use (match_operand:SI 3 "immediate_operand" "i"))
18542    (clobber (match_operand:DI 0 "register_operand" "=S"))
18543    (clobber (match_operand:DI 1 "register_operand" "=D"))
18544    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18545   "TARGET_64BIT"
18546   "repz cmpsb"
18547   [(set_attr "type" "str")
18548    (set_attr "mode" "QI")
18549    (set_attr "prefix_rex" "0")
18550    (set_attr "prefix_rep" "1")])
18551
18552 ;; The same, but the count is not known to not be zero.
18553
18554 (define_expand "cmpstrnqi_1"
18555   [(parallel [(set (reg:CC FLAGS_REG)
18556                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18557                                      (const_int 0))
18558                   (compare:CC (match_operand 4 "memory_operand" "")
18559                               (match_operand 5 "memory_operand" ""))
18560                   (const_int 0)))
18561               (use (match_operand:SI 3 "immediate_operand" ""))
18562               (use (reg:CC FLAGS_REG))
18563               (clobber (match_operand 0 "register_operand" ""))
18564               (clobber (match_operand 1 "register_operand" ""))
18565               (clobber (match_dup 2))])]
18566   ""
18567   "ix86_current_function_needs_cld = 1;")
18568
18569 (define_insn "*cmpstrnqi_1"
18570   [(set (reg:CC FLAGS_REG)
18571         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18572                              (const_int 0))
18573           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18574                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18575           (const_int 0)))
18576    (use (match_operand:SI 3 "immediate_operand" "i"))
18577    (use (reg:CC FLAGS_REG))
18578    (clobber (match_operand:SI 0 "register_operand" "=S"))
18579    (clobber (match_operand:SI 1 "register_operand" "=D"))
18580    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18581   "!TARGET_64BIT"
18582   "repz cmpsb"
18583   [(set_attr "type" "str")
18584    (set_attr "mode" "QI")
18585    (set_attr "prefix_rep" "1")])
18586
18587 (define_insn "*cmpstrnqi_rex_1"
18588   [(set (reg:CC FLAGS_REG)
18589         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18590                              (const_int 0))
18591           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18592                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18593           (const_int 0)))
18594    (use (match_operand:SI 3 "immediate_operand" "i"))
18595    (use (reg:CC FLAGS_REG))
18596    (clobber (match_operand:DI 0 "register_operand" "=S"))
18597    (clobber (match_operand:DI 1 "register_operand" "=D"))
18598    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18599   "TARGET_64BIT"
18600   "repz cmpsb"
18601   [(set_attr "type" "str")
18602    (set_attr "mode" "QI")
18603    (set_attr "prefix_rex" "0")
18604    (set_attr "prefix_rep" "1")])
18605
18606 (define_expand "strlensi"
18607   [(set (match_operand:SI 0 "register_operand" "")
18608         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18609                     (match_operand:QI 2 "immediate_operand" "")
18610                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18611   ""
18612 {
18613  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18614    DONE;
18615  else
18616    FAIL;
18617 })
18618
18619 (define_expand "strlendi"
18620   [(set (match_operand:DI 0 "register_operand" "")
18621         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18622                     (match_operand:QI 2 "immediate_operand" "")
18623                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18624   ""
18625 {
18626  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18627    DONE;
18628  else
18629    FAIL;
18630 })
18631
18632 (define_expand "strlenqi_1"
18633   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18634               (clobber (match_operand 1 "register_operand" ""))
18635               (clobber (reg:CC FLAGS_REG))])]
18636   ""
18637   "ix86_current_function_needs_cld = 1;")
18638
18639 (define_insn "*strlenqi_1"
18640   [(set (match_operand:SI 0 "register_operand" "=&c")
18641         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18642                     (match_operand:QI 2 "register_operand" "a")
18643                     (match_operand:SI 3 "immediate_operand" "i")
18644                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18645    (clobber (match_operand:SI 1 "register_operand" "=D"))
18646    (clobber (reg:CC FLAGS_REG))]
18647   "!TARGET_64BIT"
18648   "repnz scasb"
18649   [(set_attr "type" "str")
18650    (set_attr "mode" "QI")
18651    (set_attr "prefix_rep" "1")])
18652
18653 (define_insn "*strlenqi_rex_1"
18654   [(set (match_operand:DI 0 "register_operand" "=&c")
18655         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18656                     (match_operand:QI 2 "register_operand" "a")
18657                     (match_operand:DI 3 "immediate_operand" "i")
18658                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18659    (clobber (match_operand:DI 1 "register_operand" "=D"))
18660    (clobber (reg:CC FLAGS_REG))]
18661   "TARGET_64BIT"
18662   "repnz scasb"
18663   [(set_attr "type" "str")
18664    (set_attr "mode" "QI")
18665    (set_attr "prefix_rex" "0")
18666    (set_attr "prefix_rep" "1")])
18667
18668 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18669 ;; handled in combine, but it is not currently up to the task.
18670 ;; When used for their truth value, the cmpstrn* expanders generate
18671 ;; code like this:
18672 ;;
18673 ;;   repz cmpsb
18674 ;;   seta       %al
18675 ;;   setb       %dl
18676 ;;   cmpb       %al, %dl
18677 ;;   jcc        label
18678 ;;
18679 ;; The intermediate three instructions are unnecessary.
18680
18681 ;; This one handles cmpstrn*_nz_1...
18682 (define_peephole2
18683   [(parallel[
18684      (set (reg:CC FLAGS_REG)
18685           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18686                       (mem:BLK (match_operand 5 "register_operand" ""))))
18687      (use (match_operand 6 "register_operand" ""))
18688      (use (match_operand:SI 3 "immediate_operand" ""))
18689      (clobber (match_operand 0 "register_operand" ""))
18690      (clobber (match_operand 1 "register_operand" ""))
18691      (clobber (match_operand 2 "register_operand" ""))])
18692    (set (match_operand:QI 7 "register_operand" "")
18693         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18694    (set (match_operand:QI 8 "register_operand" "")
18695         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18696    (set (reg FLAGS_REG)
18697         (compare (match_dup 7) (match_dup 8)))
18698   ]
18699   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18700   [(parallel[
18701      (set (reg:CC FLAGS_REG)
18702           (compare:CC (mem:BLK (match_dup 4))
18703                       (mem:BLK (match_dup 5))))
18704      (use (match_dup 6))
18705      (use (match_dup 3))
18706      (clobber (match_dup 0))
18707      (clobber (match_dup 1))
18708      (clobber (match_dup 2))])]
18709   "")
18710
18711 ;; ...and this one handles cmpstrn*_1.
18712 (define_peephole2
18713   [(parallel[
18714      (set (reg:CC FLAGS_REG)
18715           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18716                                (const_int 0))
18717             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18718                         (mem:BLK (match_operand 5 "register_operand" "")))
18719             (const_int 0)))
18720      (use (match_operand:SI 3 "immediate_operand" ""))
18721      (use (reg:CC FLAGS_REG))
18722      (clobber (match_operand 0 "register_operand" ""))
18723      (clobber (match_operand 1 "register_operand" ""))
18724      (clobber (match_operand 2 "register_operand" ""))])
18725    (set (match_operand:QI 7 "register_operand" "")
18726         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18727    (set (match_operand:QI 8 "register_operand" "")
18728         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18729    (set (reg FLAGS_REG)
18730         (compare (match_dup 7) (match_dup 8)))
18731   ]
18732   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18733   [(parallel[
18734      (set (reg:CC FLAGS_REG)
18735           (if_then_else:CC (ne (match_dup 6)
18736                                (const_int 0))
18737             (compare:CC (mem:BLK (match_dup 4))
18738                         (mem:BLK (match_dup 5)))
18739             (const_int 0)))
18740      (use (match_dup 3))
18741      (use (reg:CC FLAGS_REG))
18742      (clobber (match_dup 0))
18743      (clobber (match_dup 1))
18744      (clobber (match_dup 2))])]
18745   "")
18746
18747
18748 \f
18749 ;; Conditional move instructions.
18750
18751 (define_expand "mov<mode>cc"
18752   [(set (match_operand:SWIM 0 "register_operand" "")
18753         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18754                            (match_operand:SWIM 2 "general_operand" "")
18755                            (match_operand:SWIM 3 "general_operand" "")))]
18756   ""
18757   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18758
18759 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18760 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18761 ;; So just document what we're doing explicitly.
18762
18763 (define_expand "x86_mov<mode>cc_0_m1"
18764   [(parallel
18765     [(set (match_operand:SWI48 0 "register_operand" "")
18766           (if_then_else:SWI48
18767             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18768              [(match_operand 1 "flags_reg_operand" "")
18769               (const_int 0)])
18770             (const_int -1)
18771             (const_int 0)))
18772      (clobber (reg:CC FLAGS_REG))])]
18773   ""
18774   "")
18775
18776 (define_insn "*x86_mov<mode>cc_0_m1"
18777   [(set (match_operand:SWI48 0 "register_operand" "=r")
18778         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18779                              [(reg FLAGS_REG) (const_int 0)])
18780           (const_int -1)
18781           (const_int 0)))
18782    (clobber (reg:CC FLAGS_REG))]
18783   ""
18784   "sbb{<imodesuffix>}\t%0, %0"
18785   ; Since we don't have the proper number of operands for an alu insn,
18786   ; fill in all the blanks.
18787   [(set_attr "type" "alu")
18788    (set_attr "use_carry" "1")
18789    (set_attr "pent_pair" "pu")
18790    (set_attr "memory" "none")
18791    (set_attr "imm_disp" "false")
18792    (set_attr "mode" "<MODE>")
18793    (set_attr "length_immediate" "0")])
18794
18795 (define_insn "*x86_mov<mode>cc_0_m1_se"
18796   [(set (match_operand:SWI48 0 "register_operand" "=r")
18797         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18798                              [(reg FLAGS_REG) (const_int 0)])
18799                             (const_int 1)
18800                             (const_int 0)))
18801    (clobber (reg:CC FLAGS_REG))]
18802   ""
18803   "sbb{<imodesuffix>}\t%0, %0"
18804   [(set_attr "type" "alu")
18805    (set_attr "use_carry" "1")
18806    (set_attr "pent_pair" "pu")
18807    (set_attr "memory" "none")
18808    (set_attr "imm_disp" "false")
18809    (set_attr "mode" "<MODE>")
18810    (set_attr "length_immediate" "0")])
18811
18812 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18813   [(set (match_operand:SWI48 0 "register_operand" "=r")
18814         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18815                     [(reg FLAGS_REG) (const_int 0)])))]
18816   ""
18817   "sbb{<imodesuffix>}\t%0, %0"
18818   [(set_attr "type" "alu")
18819    (set_attr "use_carry" "1")
18820    (set_attr "pent_pair" "pu")
18821    (set_attr "memory" "none")
18822    (set_attr "imm_disp" "false")
18823    (set_attr "mode" "<MODE>")
18824    (set_attr "length_immediate" "0")])
18825
18826 (define_insn "*mov<mode>cc_noc"
18827   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18828         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18829                                [(reg FLAGS_REG) (const_int 0)])
18830           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18831           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18832   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18833   "@
18834    cmov%O2%C1\t{%2, %0|%0, %2}
18835    cmov%O2%c1\t{%3, %0|%0, %3}"
18836   [(set_attr "type" "icmov")
18837    (set_attr "mode" "<MODE>")])
18838
18839 (define_insn_and_split "*movqicc_noc"
18840   [(set (match_operand:QI 0 "register_operand" "=r,r")
18841         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18842                            [(match_operand 4 "flags_reg_operand" "")
18843                             (const_int 0)])
18844                       (match_operand:QI 2 "register_operand" "r,0")
18845                       (match_operand:QI 3 "register_operand" "0,r")))]
18846   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18847   "#"
18848   "&& reload_completed"
18849   [(set (match_dup 0)
18850         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18851                       (match_dup 2)
18852                       (match_dup 3)))]
18853   "operands[0] = gen_lowpart (SImode, operands[0]);
18854    operands[2] = gen_lowpart (SImode, operands[2]);
18855    operands[3] = gen_lowpart (SImode, operands[3]);"
18856   [(set_attr "type" "icmov")
18857    (set_attr "mode" "SI")])
18858
18859 (define_expand "mov<mode>cc"
18860   [(set (match_operand:X87MODEF 0 "register_operand" "")
18861         (if_then_else:X87MODEF
18862           (match_operand 1 "ix86_fp_comparison_operator" "")
18863           (match_operand:X87MODEF 2 "register_operand" "")
18864           (match_operand:X87MODEF 3 "register_operand" "")))]
18865   "(TARGET_80387 && TARGET_CMOVE)
18866    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18867   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18868
18869 (define_insn "*movsfcc_1_387"
18870   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18871         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18872                                 [(reg FLAGS_REG) (const_int 0)])
18873                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18874                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18875   "TARGET_80387 && TARGET_CMOVE
18876    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18877   "@
18878    fcmov%F1\t{%2, %0|%0, %2}
18879    fcmov%f1\t{%3, %0|%0, %3}
18880    cmov%O2%C1\t{%2, %0|%0, %2}
18881    cmov%O2%c1\t{%3, %0|%0, %3}"
18882   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18883    (set_attr "mode" "SF,SF,SI,SI")])
18884
18885 (define_insn "*movdfcc_1"
18886   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18887         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18888                                 [(reg FLAGS_REG) (const_int 0)])
18889                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18890                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18891   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18892    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18893   "@
18894    fcmov%F1\t{%2, %0|%0, %2}
18895    fcmov%f1\t{%3, %0|%0, %3}
18896    #
18897    #"
18898   [(set_attr "type" "fcmov,fcmov,multi,multi")
18899    (set_attr "mode" "DF")])
18900
18901 (define_insn "*movdfcc_1_rex64"
18902   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18903         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18904                                 [(reg FLAGS_REG) (const_int 0)])
18905                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18906                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18907   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18908    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18909   "@
18910    fcmov%F1\t{%2, %0|%0, %2}
18911    fcmov%f1\t{%3, %0|%0, %3}
18912    cmov%O2%C1\t{%2, %0|%0, %2}
18913    cmov%O2%c1\t{%3, %0|%0, %3}"
18914   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18915    (set_attr "mode" "DF")])
18916
18917 (define_split
18918   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18919         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18920                                 [(match_operand 4 "flags_reg_operand" "")
18921                                  (const_int 0)])
18922                       (match_operand:DF 2 "nonimmediate_operand" "")
18923                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18924   "!TARGET_64BIT && reload_completed"
18925   [(set (match_dup 2)
18926         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18927                       (match_dup 5)
18928                       (match_dup 6)))
18929    (set (match_dup 3)
18930         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18931                       (match_dup 7)
18932                       (match_dup 8)))]
18933   "split_di (&operands[2], 2, &operands[5], &operands[7]);
18934    split_di (&operands[0], 1, &operands[2], &operands[3]);")
18935
18936 (define_insn "*movxfcc_1"
18937   [(set (match_operand:XF 0 "register_operand" "=f,f")
18938         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18939                                 [(reg FLAGS_REG) (const_int 0)])
18940                       (match_operand:XF 2 "register_operand" "f,0")
18941                       (match_operand:XF 3 "register_operand" "0,f")))]
18942   "TARGET_80387 && TARGET_CMOVE"
18943   "@
18944    fcmov%F1\t{%2, %0|%0, %2}
18945    fcmov%f1\t{%3, %0|%0, %3}"
18946   [(set_attr "type" "fcmov")
18947    (set_attr "mode" "XF")])
18948
18949 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18950 ;; the scalar versions to have only XMM registers as operands.
18951
18952 ;; XOP conditional move
18953 (define_insn "*xop_pcmov_<mode>"
18954   [(set (match_operand:MODEF 0 "register_operand" "=x")
18955         (if_then_else:MODEF
18956           (match_operand:MODEF 1 "register_operand" "x")
18957           (match_operand:MODEF 2 "register_operand" "x")
18958           (match_operand:MODEF 3 "register_operand" "x")))]
18959   "TARGET_XOP"
18960   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18961   [(set_attr "type" "sse4arg")])
18962
18963 ;; These versions of the min/max patterns are intentionally ignorant of
18964 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18965 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18966 ;; are undefined in this condition, we're certain this is correct.
18967
18968 (define_insn "*avx_<code><mode>3"
18969   [(set (match_operand:MODEF 0 "register_operand" "=x")
18970         (smaxmin:MODEF
18971           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18972           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18973   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18974   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18975   [(set_attr "type" "sseadd")
18976    (set_attr "prefix" "vex")
18977    (set_attr "mode" "<MODE>")])
18978
18979 (define_insn "<code><mode>3"
18980   [(set (match_operand:MODEF 0 "register_operand" "=x")
18981         (smaxmin:MODEF
18982           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18983           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18984   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18985   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18986   [(set_attr "type" "sseadd")
18987    (set_attr "mode" "<MODE>")])
18988
18989 ;; These versions of the min/max patterns implement exactly the operations
18990 ;;   min = (op1 < op2 ? op1 : op2)
18991 ;;   max = (!(op1 < op2) ? op1 : op2)
18992 ;; Their operands are not commutative, and thus they may be used in the
18993 ;; presence of -0.0 and NaN.
18994
18995 (define_insn "*avx_ieee_smin<mode>3"
18996   [(set (match_operand:MODEF 0 "register_operand" "=x")
18997         (unspec:MODEF
18998           [(match_operand:MODEF 1 "register_operand" "x")
18999            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19000          UNSPEC_IEEE_MIN))]
19001   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19002   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19003   [(set_attr "type" "sseadd")
19004    (set_attr "prefix" "vex")
19005    (set_attr "mode" "<MODE>")])
19006
19007 (define_insn "*ieee_smin<mode>3"
19008   [(set (match_operand:MODEF 0 "register_operand" "=x")
19009         (unspec:MODEF
19010           [(match_operand:MODEF 1 "register_operand" "0")
19011            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19012          UNSPEC_IEEE_MIN))]
19013   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19014   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19015   [(set_attr "type" "sseadd")
19016    (set_attr "mode" "<MODE>")])
19017
19018 (define_insn "*avx_ieee_smax<mode>3"
19019   [(set (match_operand:MODEF 0 "register_operand" "=x")
19020         (unspec:MODEF
19021           [(match_operand:MODEF 1 "register_operand" "0")
19022            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19023          UNSPEC_IEEE_MAX))]
19024   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19025   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19026   [(set_attr "type" "sseadd")
19027    (set_attr "prefix" "vex")
19028    (set_attr "mode" "<MODE>")])
19029
19030 (define_insn "*ieee_smax<mode>3"
19031   [(set (match_operand:MODEF 0 "register_operand" "=x")
19032         (unspec:MODEF
19033           [(match_operand:MODEF 1 "register_operand" "0")
19034            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19035          UNSPEC_IEEE_MAX))]
19036   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19037   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19038   [(set_attr "type" "sseadd")
19039    (set_attr "mode" "<MODE>")])
19040
19041 ;; Make two stack loads independent:
19042 ;;   fld aa              fld aa
19043 ;;   fld %st(0)     ->   fld bb
19044 ;;   fmul bb             fmul %st(1), %st
19045 ;;
19046 ;; Actually we only match the last two instructions for simplicity.
19047 (define_peephole2
19048   [(set (match_operand 0 "fp_register_operand" "")
19049         (match_operand 1 "fp_register_operand" ""))
19050    (set (match_dup 0)
19051         (match_operator 2 "binary_fp_operator"
19052            [(match_dup 0)
19053             (match_operand 3 "memory_operand" "")]))]
19054   "REGNO (operands[0]) != REGNO (operands[1])"
19055   [(set (match_dup 0) (match_dup 3))
19056    (set (match_dup 0) (match_dup 4))]
19057
19058   ;; The % modifier is not operational anymore in peephole2's, so we have to
19059   ;; swap the operands manually in the case of addition and multiplication.
19060   "if (COMMUTATIVE_ARITH_P (operands[2]))
19061      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19062                                  operands[0], operands[1]);
19063    else
19064      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19065                                  operands[1], operands[0]);")
19066
19067 ;; Conditional addition patterns
19068 (define_expand "add<mode>cc"
19069   [(match_operand:SWI 0 "register_operand" "")
19070    (match_operand 1 "comparison_operator" "")
19071    (match_operand:SWI 2 "register_operand" "")
19072    (match_operand:SWI 3 "const_int_operand" "")]
19073   ""
19074   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19075
19076 \f
19077 ;; Misc patterns (?)
19078
19079 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19080 ;; Otherwise there will be nothing to keep
19081 ;;
19082 ;; [(set (reg ebp) (reg esp))]
19083 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19084 ;;  (clobber (eflags)]
19085 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19086 ;;
19087 ;; in proper program order.
19088 (define_insn "pro_epilogue_adjust_stack_1"
19089   [(set (match_operand:SI 0 "register_operand" "=r,r")
19090         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19091                  (match_operand:SI 2 "immediate_operand" "i,i")))
19092    (clobber (reg:CC FLAGS_REG))
19093    (clobber (mem:BLK (scratch)))]
19094   "!TARGET_64BIT"
19095 {
19096   switch (get_attr_type (insn))
19097     {
19098     case TYPE_IMOV:
19099       return "mov{l}\t{%1, %0|%0, %1}";
19100
19101     case TYPE_ALU:
19102       if (CONST_INT_P (operands[2])
19103           && (INTVAL (operands[2]) == 128
19104               || (INTVAL (operands[2]) < 0
19105                   && INTVAL (operands[2]) != -128)))
19106         {
19107           operands[2] = GEN_INT (-INTVAL (operands[2]));
19108           return "sub{l}\t{%2, %0|%0, %2}";
19109         }
19110       return "add{l}\t{%2, %0|%0, %2}";
19111
19112     case TYPE_LEA:
19113       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19114       return "lea{l}\t{%a2, %0|%0, %a2}";
19115
19116     default:
19117       gcc_unreachable ();
19118     }
19119 }
19120   [(set (attr "type")
19121         (cond [(and (eq_attr "alternative" "0") 
19122                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19123                  (const_string "alu")
19124                (match_operand:SI 2 "const0_operand" "")
19125                  (const_string "imov")
19126               ]
19127               (const_string "lea")))
19128    (set (attr "length_immediate")
19129         (cond [(eq_attr "type" "imov")
19130                  (const_string "0")
19131                (and (eq_attr "type" "alu")
19132                     (match_operand 2 "const128_operand" ""))
19133                  (const_string "1")
19134               ]
19135               (const_string "*")))
19136    (set_attr "mode" "SI")])
19137
19138 (define_insn "pro_epilogue_adjust_stack_rex64"
19139   [(set (match_operand:DI 0 "register_operand" "=r,r")
19140         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19141                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19142    (clobber (reg:CC FLAGS_REG))
19143    (clobber (mem:BLK (scratch)))]
19144   "TARGET_64BIT"
19145 {
19146   switch (get_attr_type (insn))
19147     {
19148     case TYPE_IMOV:
19149       return "mov{q}\t{%1, %0|%0, %1}";
19150
19151     case TYPE_ALU:
19152       if (CONST_INT_P (operands[2])
19153           /* Avoid overflows.  */
19154           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19155           && (INTVAL (operands[2]) == 128
19156               || (INTVAL (operands[2]) < 0
19157                   && INTVAL (operands[2]) != -128)))
19158         {
19159           operands[2] = GEN_INT (-INTVAL (operands[2]));
19160           return "sub{q}\t{%2, %0|%0, %2}";
19161         }
19162       return "add{q}\t{%2, %0|%0, %2}";
19163
19164     case TYPE_LEA:
19165       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19166       return "lea{q}\t{%a2, %0|%0, %a2}";
19167
19168     default:
19169       gcc_unreachable ();
19170     }
19171 }
19172   [(set (attr "type")
19173         (cond [(and (eq_attr "alternative" "0")
19174                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19175                  (const_string "alu")
19176                (match_operand:DI 2 "const0_operand" "")
19177                  (const_string "imov")
19178               ]
19179               (const_string "lea")))
19180    (set (attr "length_immediate")
19181         (cond [(eq_attr "type" "imov")
19182                  (const_string "0")
19183                (and (eq_attr "type" "alu")
19184                     (match_operand 2 "const128_operand" ""))
19185                  (const_string "1")
19186               ]
19187               (const_string "*")))
19188    (set_attr "mode" "DI")])
19189
19190 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19191   [(set (match_operand:DI 0 "register_operand" "=r,r")
19192         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19193                  (match_operand:DI 3 "immediate_operand" "i,i")))
19194    (use (match_operand:DI 2 "register_operand" "r,r"))
19195    (clobber (reg:CC FLAGS_REG))
19196    (clobber (mem:BLK (scratch)))]
19197   "TARGET_64BIT"
19198 {
19199   switch (get_attr_type (insn))
19200     {
19201     case TYPE_ALU:
19202       return "add{q}\t{%2, %0|%0, %2}";
19203
19204     case TYPE_LEA:
19205       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19206       return "lea{q}\t{%a2, %0|%0, %a2}";
19207
19208     default:
19209       gcc_unreachable ();
19210     }
19211 }
19212   [(set_attr "type" "alu,lea")
19213    (set_attr "mode" "DI")])
19214
19215 (define_insn "allocate_stack_worker_32"
19216   [(set (match_operand:SI 0 "register_operand" "=a")
19217         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19218                             UNSPECV_STACK_PROBE))
19219    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19220    (clobber (reg:CC FLAGS_REG))]
19221   "!TARGET_64BIT && TARGET_STACK_PROBE"
19222   "call\t___chkstk"
19223   [(set_attr "type" "multi")
19224    (set_attr "length" "5")])
19225
19226 (define_insn "allocate_stack_worker_64"
19227   [(set (match_operand:DI 0 "register_operand" "=a")
19228         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19229                             UNSPECV_STACK_PROBE))
19230    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19231    (clobber (reg:DI R10_REG))
19232    (clobber (reg:DI R11_REG))
19233    (clobber (reg:CC FLAGS_REG))]
19234   "TARGET_64BIT && TARGET_STACK_PROBE"
19235   "call\t___chkstk"
19236   [(set_attr "type" "multi")
19237    (set_attr "length" "5")])
19238
19239 (define_expand "allocate_stack"
19240   [(match_operand 0 "register_operand" "")
19241    (match_operand 1 "general_operand" "")]
19242   "TARGET_STACK_PROBE"
19243 {
19244   rtx x;
19245
19246 #ifndef CHECK_STACK_LIMIT
19247 #define CHECK_STACK_LIMIT 0
19248 #endif
19249
19250   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19251       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19252     {
19253       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19254                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19255       if (x != stack_pointer_rtx)
19256         emit_move_insn (stack_pointer_rtx, x);
19257     }
19258   else
19259     {
19260       x = copy_to_mode_reg (Pmode, operands[1]);
19261       if (TARGET_64BIT)
19262         x = gen_allocate_stack_worker_64 (x, x);
19263       else
19264         x = gen_allocate_stack_worker_32 (x, x);
19265       emit_insn (x);
19266     }
19267
19268   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19269   DONE;
19270 })
19271
19272 ;; Use IOR for stack probes, this is shorter.
19273 (define_expand "probe_stack"
19274   [(match_operand 0 "memory_operand" "")]
19275   ""
19276 {
19277   if (GET_MODE (operands[0]) == DImode)
19278     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19279   else
19280     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19281   DONE;
19282 })
19283
19284 (define_expand "builtin_setjmp_receiver"
19285   [(label_ref (match_operand 0 "" ""))]
19286   "!TARGET_64BIT && flag_pic"
19287 {
19288 #if TARGET_MACHO
19289   if (TARGET_MACHO)
19290     {
19291       rtx xops[3];
19292       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19293       rtx label_rtx = gen_label_rtx ();
19294       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19295       xops[0] = xops[1] = picreg;
19296       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19297       ix86_expand_binary_operator (MINUS, SImode, xops);
19298     }
19299   else
19300 #endif
19301     emit_insn (gen_set_got (pic_offset_table_rtx));
19302   DONE;
19303 })
19304 \f
19305 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19306
19307 (define_split
19308   [(set (match_operand 0 "register_operand" "")
19309         (match_operator 3 "promotable_binary_operator"
19310            [(match_operand 1 "register_operand" "")
19311             (match_operand 2 "aligned_operand" "")]))
19312    (clobber (reg:CC FLAGS_REG))]
19313   "! TARGET_PARTIAL_REG_STALL && reload_completed
19314    && ((GET_MODE (operands[0]) == HImode
19315         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19316             /* ??? next two lines just !satisfies_constraint_K (...) */
19317             || !CONST_INT_P (operands[2])
19318             || satisfies_constraint_K (operands[2])))
19319        || (GET_MODE (operands[0]) == QImode
19320            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19321   [(parallel [(set (match_dup 0)
19322                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19323               (clobber (reg:CC FLAGS_REG))])]
19324   "operands[0] = gen_lowpart (SImode, operands[0]);
19325    operands[1] = gen_lowpart (SImode, operands[1]);
19326    if (GET_CODE (operands[3]) != ASHIFT)
19327      operands[2] = gen_lowpart (SImode, operands[2]);
19328    PUT_MODE (operands[3], SImode);")
19329
19330 ; Promote the QImode tests, as i386 has encoding of the AND
19331 ; instruction with 32-bit sign-extended immediate and thus the
19332 ; instruction size is unchanged, except in the %eax case for
19333 ; which it is increased by one byte, hence the ! optimize_size.
19334 (define_split
19335   [(set (match_operand 0 "flags_reg_operand" "")
19336         (match_operator 2 "compare_operator"
19337           [(and (match_operand 3 "aligned_operand" "")
19338                 (match_operand 4 "const_int_operand" ""))
19339            (const_int 0)]))
19340    (set (match_operand 1 "register_operand" "")
19341         (and (match_dup 3) (match_dup 4)))]
19342   "! TARGET_PARTIAL_REG_STALL && reload_completed
19343    && optimize_insn_for_speed_p ()
19344    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19345        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19346    /* Ensure that the operand will remain sign-extended immediate.  */
19347    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19348   [(parallel [(set (match_dup 0)
19349                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19350                                     (const_int 0)]))
19351               (set (match_dup 1)
19352                    (and:SI (match_dup 3) (match_dup 4)))])]
19353 {
19354   operands[4]
19355     = gen_int_mode (INTVAL (operands[4])
19356                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19357   operands[1] = gen_lowpart (SImode, operands[1]);
19358   operands[3] = gen_lowpart (SImode, operands[3]);
19359 })
19360
19361 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19362 ; the TEST instruction with 32-bit sign-extended immediate and thus
19363 ; the instruction size would at least double, which is not what we
19364 ; want even with ! optimize_size.
19365 (define_split
19366   [(set (match_operand 0 "flags_reg_operand" "")
19367         (match_operator 1 "compare_operator"
19368           [(and (match_operand:HI 2 "aligned_operand" "")
19369                 (match_operand:HI 3 "const_int_operand" ""))
19370            (const_int 0)]))]
19371   "! TARGET_PARTIAL_REG_STALL && reload_completed
19372    && ! TARGET_FAST_PREFIX
19373    && optimize_insn_for_speed_p ()
19374    /* Ensure that the operand will remain sign-extended immediate.  */
19375    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19376   [(set (match_dup 0)
19377         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19378                          (const_int 0)]))]
19379 {
19380   operands[3]
19381     = gen_int_mode (INTVAL (operands[3])
19382                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19383   operands[2] = gen_lowpart (SImode, operands[2]);
19384 })
19385
19386 (define_split
19387   [(set (match_operand 0 "register_operand" "")
19388         (neg (match_operand 1 "register_operand" "")))
19389    (clobber (reg:CC FLAGS_REG))]
19390   "! TARGET_PARTIAL_REG_STALL && reload_completed
19391    && (GET_MODE (operands[0]) == HImode
19392        || (GET_MODE (operands[0]) == QImode
19393            && (TARGET_PROMOTE_QImode
19394                || optimize_insn_for_size_p ())))"
19395   [(parallel [(set (match_dup 0)
19396                    (neg:SI (match_dup 1)))
19397               (clobber (reg:CC FLAGS_REG))])]
19398   "operands[0] = gen_lowpart (SImode, operands[0]);
19399    operands[1] = gen_lowpart (SImode, operands[1]);")
19400
19401 (define_split
19402   [(set (match_operand 0 "register_operand" "")
19403         (not (match_operand 1 "register_operand" "")))]
19404   "! TARGET_PARTIAL_REG_STALL && reload_completed
19405    && (GET_MODE (operands[0]) == HImode
19406        || (GET_MODE (operands[0]) == QImode
19407            && (TARGET_PROMOTE_QImode
19408                || optimize_insn_for_size_p ())))"
19409   [(set (match_dup 0)
19410         (not:SI (match_dup 1)))]
19411   "operands[0] = gen_lowpart (SImode, operands[0]);
19412    operands[1] = gen_lowpart (SImode, operands[1]);")
19413
19414 (define_split
19415   [(set (match_operand 0 "register_operand" "")
19416         (if_then_else (match_operator 1 "comparison_operator"
19417                                 [(reg FLAGS_REG) (const_int 0)])
19418                       (match_operand 2 "register_operand" "")
19419                       (match_operand 3 "register_operand" "")))]
19420   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19421    && (GET_MODE (operands[0]) == HImode
19422        || (GET_MODE (operands[0]) == QImode
19423            && (TARGET_PROMOTE_QImode
19424                || optimize_insn_for_size_p ())))"
19425   [(set (match_dup 0)
19426         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19427   "operands[0] = gen_lowpart (SImode, operands[0]);
19428    operands[2] = gen_lowpart (SImode, operands[2]);
19429    operands[3] = gen_lowpart (SImode, operands[3]);")
19430
19431 \f
19432 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19433 ;; transform a complex memory operation into two memory to register operations.
19434
19435 ;; Don't push memory operands
19436 (define_peephole2
19437   [(set (match_operand:SI 0 "push_operand" "")
19438         (match_operand:SI 1 "memory_operand" ""))
19439    (match_scratch:SI 2 "r")]
19440   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19441    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19442   [(set (match_dup 2) (match_dup 1))
19443    (set (match_dup 0) (match_dup 2))]
19444   "")
19445
19446 (define_peephole2
19447   [(set (match_operand:DI 0 "push_operand" "")
19448         (match_operand:DI 1 "memory_operand" ""))
19449    (match_scratch:DI 2 "r")]
19450   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19451    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19452   [(set (match_dup 2) (match_dup 1))
19453    (set (match_dup 0) (match_dup 2))]
19454   "")
19455
19456 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19457 ;; SImode pushes.
19458 (define_peephole2
19459   [(set (match_operand:SF 0 "push_operand" "")
19460         (match_operand:SF 1 "memory_operand" ""))
19461    (match_scratch:SF 2 "r")]
19462   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19463    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19464   [(set (match_dup 2) (match_dup 1))
19465    (set (match_dup 0) (match_dup 2))]
19466   "")
19467
19468 (define_peephole2
19469   [(set (match_operand:HI 0 "push_operand" "")
19470         (match_operand:HI 1 "memory_operand" ""))
19471    (match_scratch:HI 2 "r")]
19472   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19473    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19474   [(set (match_dup 2) (match_dup 1))
19475    (set (match_dup 0) (match_dup 2))]
19476   "")
19477
19478 (define_peephole2
19479   [(set (match_operand:QI 0 "push_operand" "")
19480         (match_operand:QI 1 "memory_operand" ""))
19481    (match_scratch:QI 2 "q")]
19482   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19483    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19484   [(set (match_dup 2) (match_dup 1))
19485    (set (match_dup 0) (match_dup 2))]
19486   "")
19487
19488 ;; Don't move an immediate directly to memory when the instruction
19489 ;; gets too big.
19490 (define_peephole2
19491   [(match_scratch:SI 1 "r")
19492    (set (match_operand:SI 0 "memory_operand" "")
19493         (const_int 0))]
19494   "optimize_insn_for_speed_p ()
19495    && ! TARGET_USE_MOV0
19496    && TARGET_SPLIT_LONG_MOVES
19497    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19498    && peep2_regno_dead_p (0, FLAGS_REG)"
19499   [(parallel [(set (match_dup 1) (const_int 0))
19500               (clobber (reg:CC FLAGS_REG))])
19501    (set (match_dup 0) (match_dup 1))]
19502   "")
19503
19504 (define_peephole2
19505   [(match_scratch:HI 1 "r")
19506    (set (match_operand:HI 0 "memory_operand" "")
19507         (const_int 0))]
19508   "optimize_insn_for_speed_p ()
19509    && ! TARGET_USE_MOV0
19510    && TARGET_SPLIT_LONG_MOVES
19511    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19512    && peep2_regno_dead_p (0, FLAGS_REG)"
19513   [(parallel [(set (match_dup 2) (const_int 0))
19514               (clobber (reg:CC FLAGS_REG))])
19515    (set (match_dup 0) (match_dup 1))]
19516   "operands[2] = gen_lowpart (SImode, operands[1]);")
19517
19518 (define_peephole2
19519   [(match_scratch:QI 1 "q")
19520    (set (match_operand:QI 0 "memory_operand" "")
19521         (const_int 0))]
19522   "optimize_insn_for_speed_p ()
19523    && ! TARGET_USE_MOV0
19524    && TARGET_SPLIT_LONG_MOVES
19525    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19526    && peep2_regno_dead_p (0, FLAGS_REG)"
19527   [(parallel [(set (match_dup 2) (const_int 0))
19528               (clobber (reg:CC FLAGS_REG))])
19529    (set (match_dup 0) (match_dup 1))]
19530   "operands[2] = gen_lowpart (SImode, operands[1]);")
19531
19532 (define_peephole2
19533   [(match_scratch:SI 2 "r")
19534    (set (match_operand:SI 0 "memory_operand" "")
19535         (match_operand:SI 1 "immediate_operand" ""))]
19536   "optimize_insn_for_speed_p ()
19537    && TARGET_SPLIT_LONG_MOVES
19538    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19539   [(set (match_dup 2) (match_dup 1))
19540    (set (match_dup 0) (match_dup 2))]
19541   "")
19542
19543 (define_peephole2
19544   [(match_scratch:HI 2 "r")
19545    (set (match_operand:HI 0 "memory_operand" "")
19546         (match_operand:HI 1 "immediate_operand" ""))]
19547   "optimize_insn_for_speed_p ()
19548    && TARGET_SPLIT_LONG_MOVES
19549    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19550   [(set (match_dup 2) (match_dup 1))
19551    (set (match_dup 0) (match_dup 2))]
19552   "")
19553
19554 (define_peephole2
19555   [(match_scratch:QI 2 "q")
19556    (set (match_operand:QI 0 "memory_operand" "")
19557         (match_operand:QI 1 "immediate_operand" ""))]
19558   "optimize_insn_for_speed_p ()
19559    && TARGET_SPLIT_LONG_MOVES
19560    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19561   [(set (match_dup 2) (match_dup 1))
19562    (set (match_dup 0) (match_dup 2))]
19563   "")
19564
19565 ;; Don't compare memory with zero, load and use a test instead.
19566 (define_peephole2
19567   [(set (match_operand 0 "flags_reg_operand" "")
19568         (match_operator 1 "compare_operator"
19569           [(match_operand:SI 2 "memory_operand" "")
19570            (const_int 0)]))
19571    (match_scratch:SI 3 "r")]
19572   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19573   [(set (match_dup 3) (match_dup 2))
19574    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19575   "")
19576
19577 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19578 ;; Don't split NOTs with a displacement operand, because resulting XOR
19579 ;; will not be pairable anyway.
19580 ;;
19581 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19582 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19583 ;; so this split helps here as well.
19584 ;;
19585 ;; Note: Can't do this as a regular split because we can't get proper
19586 ;; lifetime information then.
19587
19588 (define_peephole2
19589   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19590         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19591   "optimize_insn_for_speed_p ()
19592    && ((TARGET_NOT_UNPAIRABLE
19593         && (!MEM_P (operands[0])
19594             || !memory_displacement_operand (operands[0], SImode)))
19595        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19596    && peep2_regno_dead_p (0, FLAGS_REG)"
19597   [(parallel [(set (match_dup 0)
19598                    (xor:SI (match_dup 1) (const_int -1)))
19599               (clobber (reg:CC FLAGS_REG))])]
19600   "")
19601
19602 (define_peephole2
19603   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19604         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19605   "optimize_insn_for_speed_p ()
19606    && ((TARGET_NOT_UNPAIRABLE
19607         && (!MEM_P (operands[0])
19608             || !memory_displacement_operand (operands[0], HImode)))
19609        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19610    && peep2_regno_dead_p (0, FLAGS_REG)"
19611   [(parallel [(set (match_dup 0)
19612                    (xor:HI (match_dup 1) (const_int -1)))
19613               (clobber (reg:CC FLAGS_REG))])]
19614   "")
19615
19616 (define_peephole2
19617   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19618         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19619   "optimize_insn_for_speed_p ()
19620    && ((TARGET_NOT_UNPAIRABLE
19621         && (!MEM_P (operands[0])
19622             || !memory_displacement_operand (operands[0], QImode)))
19623        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19624    && peep2_regno_dead_p (0, FLAGS_REG)"
19625   [(parallel [(set (match_dup 0)
19626                    (xor:QI (match_dup 1) (const_int -1)))
19627               (clobber (reg:CC FLAGS_REG))])]
19628   "")
19629
19630 ;; Non pairable "test imm, reg" instructions can be translated to
19631 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19632 ;; byte opcode instead of two, have a short form for byte operands),
19633 ;; so do it for other CPUs as well.  Given that the value was dead,
19634 ;; this should not create any new dependencies.  Pass on the sub-word
19635 ;; versions if we're concerned about partial register stalls.
19636
19637 (define_peephole2
19638   [(set (match_operand 0 "flags_reg_operand" "")
19639         (match_operator 1 "compare_operator"
19640           [(and:SI (match_operand:SI 2 "register_operand" "")
19641                    (match_operand:SI 3 "immediate_operand" ""))
19642            (const_int 0)]))]
19643   "ix86_match_ccmode (insn, CCNOmode)
19644    && (true_regnum (operands[2]) != AX_REG
19645        || satisfies_constraint_K (operands[3]))
19646    && peep2_reg_dead_p (1, operands[2])"
19647   [(parallel
19648      [(set (match_dup 0)
19649            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19650                             (const_int 0)]))
19651       (set (match_dup 2)
19652            (and:SI (match_dup 2) (match_dup 3)))])]
19653   "")
19654
19655 ;; We don't need to handle HImode case, because it will be promoted to SImode
19656 ;; on ! TARGET_PARTIAL_REG_STALL
19657
19658 (define_peephole2
19659   [(set (match_operand 0 "flags_reg_operand" "")
19660         (match_operator 1 "compare_operator"
19661           [(and:QI (match_operand:QI 2 "register_operand" "")
19662                    (match_operand:QI 3 "immediate_operand" ""))
19663            (const_int 0)]))]
19664   "! TARGET_PARTIAL_REG_STALL
19665    && ix86_match_ccmode (insn, CCNOmode)
19666    && true_regnum (operands[2]) != AX_REG
19667    && peep2_reg_dead_p (1, operands[2])"
19668   [(parallel
19669      [(set (match_dup 0)
19670            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19671                             (const_int 0)]))
19672       (set (match_dup 2)
19673            (and:QI (match_dup 2) (match_dup 3)))])]
19674   "")
19675
19676 (define_peephole2
19677   [(set (match_operand 0 "flags_reg_operand" "")
19678         (match_operator 1 "compare_operator"
19679           [(and:SI
19680              (zero_extract:SI
19681                (match_operand 2 "ext_register_operand" "")
19682                (const_int 8)
19683                (const_int 8))
19684              (match_operand 3 "const_int_operand" ""))
19685            (const_int 0)]))]
19686   "! TARGET_PARTIAL_REG_STALL
19687    && ix86_match_ccmode (insn, CCNOmode)
19688    && true_regnum (operands[2]) != AX_REG
19689    && peep2_reg_dead_p (1, operands[2])"
19690   [(parallel [(set (match_dup 0)
19691                    (match_op_dup 1
19692                      [(and:SI
19693                         (zero_extract:SI
19694                           (match_dup 2)
19695                           (const_int 8)
19696                           (const_int 8))
19697                         (match_dup 3))
19698                       (const_int 0)]))
19699               (set (zero_extract:SI (match_dup 2)
19700                                     (const_int 8)
19701                                     (const_int 8))
19702                    (and:SI
19703                      (zero_extract:SI
19704                        (match_dup 2)
19705                        (const_int 8)
19706                        (const_int 8))
19707                      (match_dup 3)))])]
19708   "")
19709
19710 ;; Don't do logical operations with memory inputs.
19711 (define_peephole2
19712   [(match_scratch:SI 2 "r")
19713    (parallel [(set (match_operand:SI 0 "register_operand" "")
19714                    (match_operator:SI 3 "arith_or_logical_operator"
19715                      [(match_dup 0)
19716                       (match_operand:SI 1 "memory_operand" "")]))
19717               (clobber (reg:CC FLAGS_REG))])]
19718   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19719   [(set (match_dup 2) (match_dup 1))
19720    (parallel [(set (match_dup 0)
19721                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19722               (clobber (reg:CC FLAGS_REG))])]
19723   "")
19724
19725 (define_peephole2
19726   [(match_scratch:SI 2 "r")
19727    (parallel [(set (match_operand:SI 0 "register_operand" "")
19728                    (match_operator:SI 3 "arith_or_logical_operator"
19729                      [(match_operand:SI 1 "memory_operand" "")
19730                       (match_dup 0)]))
19731               (clobber (reg:CC FLAGS_REG))])]
19732   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19733   [(set (match_dup 2) (match_dup 1))
19734    (parallel [(set (match_dup 0)
19735                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19736               (clobber (reg:CC FLAGS_REG))])]
19737   "")
19738
19739 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
19740 ;; refers to the destination of the load!
19741
19742 (define_peephole2
19743   [(set (match_operand:SI 0 "register_operand" "")
19744         (match_operand:SI 1 "register_operand" ""))
19745    (parallel [(set (match_dup 0)
19746                    (match_operator:SI 3 "commutative_operator"
19747                      [(match_dup 0)
19748                       (match_operand:SI 2 "memory_operand" "")]))
19749               (clobber (reg:CC FLAGS_REG))])]
19750   "REGNO (operands[0]) != REGNO (operands[1])
19751    && GENERAL_REGNO_P (REGNO (operands[0]))
19752    && GENERAL_REGNO_P (REGNO (operands[1]))"
19753   [(set (match_dup 0) (match_dup 4))
19754    (parallel [(set (match_dup 0)
19755                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19756               (clobber (reg:CC FLAGS_REG))])]
19757   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19758
19759 (define_peephole2
19760   [(set (match_operand 0 "register_operand" "")
19761         (match_operand 1 "register_operand" ""))
19762    (set (match_dup 0)
19763                    (match_operator 3 "commutative_operator"
19764                      [(match_dup 0)
19765                       (match_operand 2 "memory_operand" "")]))]
19766   "REGNO (operands[0]) != REGNO (operands[1])
19767    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
19768        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19769   [(set (match_dup 0) (match_dup 2))
19770    (set (match_dup 0)
19771         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19772   "")
19773
19774 ; Don't do logical operations with memory outputs
19775 ;
19776 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19777 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19778 ; the same decoder scheduling characteristics as the original.
19779
19780 (define_peephole2
19781   [(match_scratch:SI 2 "r")
19782    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19783                    (match_operator:SI 3 "arith_or_logical_operator"
19784                      [(match_dup 0)
19785                       (match_operand:SI 1 "nonmemory_operand" "")]))
19786               (clobber (reg:CC FLAGS_REG))])]
19787   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19788    /* Do not split stack checking probes.  */
19789    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19790   [(set (match_dup 2) (match_dup 0))
19791    (parallel [(set (match_dup 2)
19792                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19793               (clobber (reg:CC FLAGS_REG))])
19794    (set (match_dup 0) (match_dup 2))]
19795   "")
19796
19797 (define_peephole2
19798   [(match_scratch:SI 2 "r")
19799    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19800                    (match_operator:SI 3 "arith_or_logical_operator"
19801                      [(match_operand:SI 1 "nonmemory_operand" "")
19802                       (match_dup 0)]))
19803               (clobber (reg:CC FLAGS_REG))])]
19804   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19805    /* Do not split stack checking probes.  */
19806    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19807   [(set (match_dup 2) (match_dup 0))
19808    (parallel [(set (match_dup 2)
19809                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19810               (clobber (reg:CC FLAGS_REG))])
19811    (set (match_dup 0) (match_dup 2))]
19812   "")
19813
19814 ;; Attempt to always use XOR for zeroing registers.
19815 (define_peephole2
19816   [(set (match_operand 0 "register_operand" "")
19817         (match_operand 1 "const0_operand" ""))]
19818   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19819    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19820    && GENERAL_REG_P (operands[0])
19821    && peep2_regno_dead_p (0, FLAGS_REG)"
19822   [(parallel [(set (match_dup 0) (const_int 0))
19823               (clobber (reg:CC FLAGS_REG))])]
19824 {
19825   operands[0] = gen_lowpart (word_mode, operands[0]);
19826 })
19827
19828 (define_peephole2
19829   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19830         (const_int 0))]
19831   "(GET_MODE (operands[0]) == QImode
19832     || GET_MODE (operands[0]) == HImode)
19833    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19834    && peep2_regno_dead_p (0, FLAGS_REG)"
19835   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19836               (clobber (reg:CC FLAGS_REG))])])
19837
19838 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19839 (define_peephole2
19840   [(set (match_operand 0 "register_operand" "")
19841         (const_int -1))]
19842   "(GET_MODE (operands[0]) == HImode
19843     || GET_MODE (operands[0]) == SImode
19844     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19845    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19846    && peep2_regno_dead_p (0, FLAGS_REG)"
19847   [(parallel [(set (match_dup 0) (const_int -1))
19848               (clobber (reg:CC FLAGS_REG))])]
19849   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19850                               operands[0]);")
19851
19852 ;; Attempt to convert simple leas to adds. These can be created by
19853 ;; move expanders.
19854 (define_peephole2
19855   [(set (match_operand:SI 0 "register_operand" "")
19856         (plus:SI (match_dup 0)
19857                  (match_operand:SI 1 "nonmemory_operand" "")))]
19858   "peep2_regno_dead_p (0, FLAGS_REG)"
19859   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19860               (clobber (reg:CC FLAGS_REG))])]
19861   "")
19862
19863 (define_peephole2
19864   [(set (match_operand:SI 0 "register_operand" "")
19865         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19866                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19867   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19868   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19869               (clobber (reg:CC FLAGS_REG))])]
19870   "operands[2] = gen_lowpart (SImode, operands[2]);")
19871
19872 (define_peephole2
19873   [(set (match_operand:DI 0 "register_operand" "")
19874         (plus:DI (match_dup 0)
19875                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19876   "peep2_regno_dead_p (0, FLAGS_REG)"
19877   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19878               (clobber (reg:CC FLAGS_REG))])]
19879   "")
19880
19881 (define_peephole2
19882   [(set (match_operand:SI 0 "register_operand" "")
19883         (mult:SI (match_dup 0)
19884                  (match_operand:SI 1 "const_int_operand" "")))]
19885   "exact_log2 (INTVAL (operands[1])) >= 0
19886    && peep2_regno_dead_p (0, FLAGS_REG)"
19887   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19888               (clobber (reg:CC FLAGS_REG))])]
19889   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19890
19891 (define_peephole2
19892   [(set (match_operand:DI 0 "register_operand" "")
19893         (mult:DI (match_dup 0)
19894                  (match_operand:DI 1 "const_int_operand" "")))]
19895   "exact_log2 (INTVAL (operands[1])) >= 0
19896    && peep2_regno_dead_p (0, FLAGS_REG)"
19897   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19898               (clobber (reg:CC FLAGS_REG))])]
19899   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19900
19901 (define_peephole2
19902   [(set (match_operand:SI 0 "register_operand" "")
19903         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19904                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19905   "exact_log2 (INTVAL (operands[2])) >= 0
19906    && REGNO (operands[0]) == REGNO (operands[1])
19907    && peep2_regno_dead_p (0, FLAGS_REG)"
19908   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19909               (clobber (reg:CC FLAGS_REG))])]
19910   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19911
19912 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19913 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19914 ;; many CPUs it is also faster, since special hardware to avoid esp
19915 ;; dependencies is present.
19916
19917 ;; While some of these conversions may be done using splitters, we use peepholes
19918 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19919
19920 ;; Convert prologue esp subtractions to push.
19921 ;; We need register to push.  In order to keep verify_flow_info happy we have
19922 ;; two choices
19923 ;; - use scratch and clobber it in order to avoid dependencies
19924 ;; - use already live register
19925 ;; We can't use the second way right now, since there is no reliable way how to
19926 ;; verify that given register is live.  First choice will also most likely in
19927 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19928 ;; call clobbered registers are dead.  We may want to use base pointer as an
19929 ;; alternative when no register is available later.
19930
19931 (define_peephole2
19932   [(match_scratch:SI 0 "r")
19933    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19934               (clobber (reg:CC FLAGS_REG))
19935               (clobber (mem:BLK (scratch)))])]
19936   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19937   [(clobber (match_dup 0))
19938    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19939               (clobber (mem:BLK (scratch)))])])
19940
19941 (define_peephole2
19942   [(match_scratch:SI 0 "r")
19943    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19944               (clobber (reg:CC FLAGS_REG))
19945               (clobber (mem:BLK (scratch)))])]
19946   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19947   [(clobber (match_dup 0))
19948    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19949    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19950               (clobber (mem:BLK (scratch)))])])
19951
19952 ;; Convert esp subtractions to push.
19953 (define_peephole2
19954   [(match_scratch:SI 0 "r")
19955    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19956               (clobber (reg:CC FLAGS_REG))])]
19957   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19958   [(clobber (match_dup 0))
19959    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19960
19961 (define_peephole2
19962   [(match_scratch:SI 0 "r")
19963    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19964               (clobber (reg:CC FLAGS_REG))])]
19965   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19966   [(clobber (match_dup 0))
19967    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19968    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19969
19970 ;; Convert epilogue deallocator to pop.
19971 (define_peephole2
19972   [(match_scratch:SI 0 "r")
19973    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19974               (clobber (reg:CC FLAGS_REG))
19975               (clobber (mem:BLK (scratch)))])]
19976   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19977   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19978               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19979               (clobber (mem:BLK (scratch)))])]
19980   "")
19981
19982 ;; Two pops case is tricky, since pop causes dependency on destination register.
19983 ;; We use two registers if available.
19984 (define_peephole2
19985   [(match_scratch:SI 0 "r")
19986    (match_scratch:SI 1 "r")
19987    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19988               (clobber (reg:CC FLAGS_REG))
19989               (clobber (mem:BLK (scratch)))])]
19990   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19991   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19992               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19993               (clobber (mem:BLK (scratch)))])
19994    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19995               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19996   "")
19997
19998 (define_peephole2
19999   [(match_scratch:SI 0 "r")
20000    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20001               (clobber (reg:CC FLAGS_REG))
20002               (clobber (mem:BLK (scratch)))])]
20003   "optimize_insn_for_size_p ()"
20004   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20005               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20006               (clobber (mem:BLK (scratch)))])
20007    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20008               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20009   "")
20010
20011 ;; Convert esp additions to pop.
20012 (define_peephole2
20013   [(match_scratch:SI 0 "r")
20014    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20015               (clobber (reg:CC FLAGS_REG))])]
20016   ""
20017   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20018               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20019   "")
20020
20021 ;; Two pops case is tricky, since pop causes dependency on destination register.
20022 ;; We use two registers if available.
20023 (define_peephole2
20024   [(match_scratch:SI 0 "r")
20025    (match_scratch:SI 1 "r")
20026    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20027               (clobber (reg:CC FLAGS_REG))])]
20028   ""
20029   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20030               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20031    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20032               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20033   "")
20034
20035 (define_peephole2
20036   [(match_scratch:SI 0 "r")
20037    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20038               (clobber (reg:CC FLAGS_REG))])]
20039   "optimize_insn_for_size_p ()"
20040   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20041               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20042    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20043               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20044   "")
20045 \f
20046 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20047 ;; required and register dies.  Similarly for 128 to -128.
20048 (define_peephole2
20049   [(set (match_operand 0 "flags_reg_operand" "")
20050         (match_operator 1 "compare_operator"
20051           [(match_operand 2 "register_operand" "")
20052            (match_operand 3 "const_int_operand" "")]))]
20053   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20054      && incdec_operand (operands[3], GET_MODE (operands[3])))
20055     || (!TARGET_FUSE_CMP_AND_BRANCH
20056         && INTVAL (operands[3]) == 128))
20057    && ix86_match_ccmode (insn, CCGCmode)
20058    && peep2_reg_dead_p (1, operands[2])"
20059   [(parallel [(set (match_dup 0)
20060                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20061               (clobber (match_dup 2))])]
20062   "")
20063 \f
20064 (define_peephole2
20065   [(match_scratch:DI 0 "r")
20066    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20067               (clobber (reg:CC FLAGS_REG))
20068               (clobber (mem:BLK (scratch)))])]
20069   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20070   [(clobber (match_dup 0))
20071    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20072               (clobber (mem:BLK (scratch)))])])
20073
20074 (define_peephole2
20075   [(match_scratch:DI 0 "r")
20076    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20077               (clobber (reg:CC FLAGS_REG))
20078               (clobber (mem:BLK (scratch)))])]
20079   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20080   [(clobber (match_dup 0))
20081    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20082    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20083               (clobber (mem:BLK (scratch)))])])
20084
20085 ;; Convert esp subtractions to push.
20086 (define_peephole2
20087   [(match_scratch:DI 0 "r")
20088    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20089               (clobber (reg:CC FLAGS_REG))])]
20090   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20091   [(clobber (match_dup 0))
20092    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20093
20094 (define_peephole2
20095   [(match_scratch:DI 0 "r")
20096    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20097               (clobber (reg:CC FLAGS_REG))])]
20098   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20099   [(clobber (match_dup 0))
20100    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20101    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20102
20103 ;; Convert epilogue deallocator to pop.
20104 (define_peephole2
20105   [(match_scratch:DI 0 "r")
20106    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20107               (clobber (reg:CC FLAGS_REG))
20108               (clobber (mem:BLK (scratch)))])]
20109   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20110   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20111               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20112               (clobber (mem:BLK (scratch)))])]
20113   "")
20114
20115 ;; Two pops case is tricky, since pop causes dependency on destination register.
20116 ;; We use two registers if available.
20117 (define_peephole2
20118   [(match_scratch:DI 0 "r")
20119    (match_scratch:DI 1 "r")
20120    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20121               (clobber (reg:CC FLAGS_REG))
20122               (clobber (mem:BLK (scratch)))])]
20123   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20124   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20125               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20126               (clobber (mem:BLK (scratch)))])
20127    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20128               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20129   "")
20130
20131 (define_peephole2
20132   [(match_scratch:DI 0 "r")
20133    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20134               (clobber (reg:CC FLAGS_REG))
20135               (clobber (mem:BLK (scratch)))])]
20136   "optimize_insn_for_size_p ()"
20137   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20138               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20139               (clobber (mem:BLK (scratch)))])
20140    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20141               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20142   "")
20143
20144 ;; Convert esp additions to pop.
20145 (define_peephole2
20146   [(match_scratch:DI 0 "r")
20147    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20148               (clobber (reg:CC FLAGS_REG))])]
20149   ""
20150   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20151               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20152   "")
20153
20154 ;; Two pops case is tricky, since pop causes dependency on destination register.
20155 ;; We use two registers if available.
20156 (define_peephole2
20157   [(match_scratch:DI 0 "r")
20158    (match_scratch:DI 1 "r")
20159    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20160               (clobber (reg:CC FLAGS_REG))])]
20161   ""
20162   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20163               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20164    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20165               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20166   "")
20167
20168 (define_peephole2
20169   [(match_scratch:DI 0 "r")
20170    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20171               (clobber (reg:CC FLAGS_REG))])]
20172   "optimize_insn_for_size_p ()"
20173   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20174               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20175    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20176               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20177   "")
20178 \f
20179 ;; Convert imul by three, five and nine into lea
20180 (define_peephole2
20181   [(parallel
20182     [(set (match_operand:SI 0 "register_operand" "")
20183           (mult:SI (match_operand:SI 1 "register_operand" "")
20184                    (match_operand:SI 2 "const_int_operand" "")))
20185      (clobber (reg:CC FLAGS_REG))])]
20186   "INTVAL (operands[2]) == 3
20187    || INTVAL (operands[2]) == 5
20188    || INTVAL (operands[2]) == 9"
20189   [(set (match_dup 0)
20190         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20191                  (match_dup 1)))]
20192   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20193
20194 (define_peephole2
20195   [(parallel
20196     [(set (match_operand:SI 0 "register_operand" "")
20197           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20198                    (match_operand:SI 2 "const_int_operand" "")))
20199      (clobber (reg:CC FLAGS_REG))])]
20200   "optimize_insn_for_speed_p ()
20201    && (INTVAL (operands[2]) == 3
20202        || INTVAL (operands[2]) == 5
20203        || INTVAL (operands[2]) == 9)"
20204   [(set (match_dup 0) (match_dup 1))
20205    (set (match_dup 0)
20206         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20207                  (match_dup 0)))]
20208   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20209
20210 (define_peephole2
20211   [(parallel
20212     [(set (match_operand:DI 0 "register_operand" "")
20213           (mult:DI (match_operand:DI 1 "register_operand" "")
20214                    (match_operand:DI 2 "const_int_operand" "")))
20215      (clobber (reg:CC FLAGS_REG))])]
20216   "TARGET_64BIT
20217    && (INTVAL (operands[2]) == 3
20218        || INTVAL (operands[2]) == 5
20219        || INTVAL (operands[2]) == 9)"
20220   [(set (match_dup 0)
20221         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20222                  (match_dup 1)))]
20223   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20224
20225 (define_peephole2
20226   [(parallel
20227     [(set (match_operand:DI 0 "register_operand" "")
20228           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20229                    (match_operand:DI 2 "const_int_operand" "")))
20230      (clobber (reg:CC FLAGS_REG))])]
20231   "TARGET_64BIT
20232    && optimize_insn_for_speed_p ()
20233    && (INTVAL (operands[2]) == 3
20234        || INTVAL (operands[2]) == 5
20235        || INTVAL (operands[2]) == 9)"
20236   [(set (match_dup 0) (match_dup 1))
20237    (set (match_dup 0)
20238         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20239                  (match_dup 0)))]
20240   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20241
20242 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20243 ;; imul $32bit_imm, reg, reg is direct decoded.
20244 (define_peephole2
20245   [(match_scratch:DI 3 "r")
20246    (parallel [(set (match_operand:DI 0 "register_operand" "")
20247                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20248                             (match_operand:DI 2 "immediate_operand" "")))
20249               (clobber (reg:CC FLAGS_REG))])]
20250   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20251    && !satisfies_constraint_K (operands[2])"
20252   [(set (match_dup 3) (match_dup 1))
20253    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20254               (clobber (reg:CC FLAGS_REG))])]
20255 "")
20256
20257 (define_peephole2
20258   [(match_scratch:SI 3 "r")
20259    (parallel [(set (match_operand:SI 0 "register_operand" "")
20260                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20261                             (match_operand:SI 2 "immediate_operand" "")))
20262               (clobber (reg:CC FLAGS_REG))])]
20263   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20264    && !satisfies_constraint_K (operands[2])"
20265   [(set (match_dup 3) (match_dup 1))
20266    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20267               (clobber (reg:CC FLAGS_REG))])]
20268 "")
20269
20270 (define_peephole2
20271   [(match_scratch:SI 3 "r")
20272    (parallel [(set (match_operand:DI 0 "register_operand" "")
20273                    (zero_extend:DI
20274                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20275                               (match_operand:SI 2 "immediate_operand" ""))))
20276               (clobber (reg:CC FLAGS_REG))])]
20277   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20278    && !satisfies_constraint_K (operands[2])"
20279   [(set (match_dup 3) (match_dup 1))
20280    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20281               (clobber (reg:CC FLAGS_REG))])]
20282 "")
20283
20284 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20285 ;; Convert it into imul reg, reg
20286 ;; It would be better to force assembler to encode instruction using long
20287 ;; immediate, but there is apparently no way to do so.
20288 (define_peephole2
20289   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20290                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20291                             (match_operand:DI 2 "const_int_operand" "")))
20292               (clobber (reg:CC FLAGS_REG))])
20293    (match_scratch:DI 3 "r")]
20294   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20295    && satisfies_constraint_K (operands[2])"
20296   [(set (match_dup 3) (match_dup 2))
20297    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20298               (clobber (reg:CC FLAGS_REG))])]
20299 {
20300   if (!rtx_equal_p (operands[0], operands[1]))
20301     emit_move_insn (operands[0], operands[1]);
20302 })
20303
20304 (define_peephole2
20305   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20306                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20307                             (match_operand:SI 2 "const_int_operand" "")))
20308               (clobber (reg:CC FLAGS_REG))])
20309    (match_scratch:SI 3 "r")]
20310   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20311    && satisfies_constraint_K (operands[2])"
20312   [(set (match_dup 3) (match_dup 2))
20313    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20314               (clobber (reg:CC FLAGS_REG))])]
20315 {
20316   if (!rtx_equal_p (operands[0], operands[1]))
20317     emit_move_insn (operands[0], operands[1]);
20318 })
20319
20320 (define_peephole2
20321   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20322                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20323                             (match_operand:HI 2 "immediate_operand" "")))
20324               (clobber (reg:CC FLAGS_REG))])
20325    (match_scratch:HI 3 "r")]
20326   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20327   [(set (match_dup 3) (match_dup 2))
20328    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20329               (clobber (reg:CC FLAGS_REG))])]
20330 {
20331   if (!rtx_equal_p (operands[0], operands[1]))
20332     emit_move_insn (operands[0], operands[1]);
20333 })
20334
20335 ;; After splitting up read-modify operations, array accesses with memory
20336 ;; operands might end up in form:
20337 ;;  sall    $2, %eax
20338 ;;  movl    4(%esp), %edx
20339 ;;  addl    %edx, %eax
20340 ;; instead of pre-splitting:
20341 ;;  sall    $2, %eax
20342 ;;  addl    4(%esp), %eax
20343 ;; Turn it into:
20344 ;;  movl    4(%esp), %edx
20345 ;;  leal    (%edx,%eax,4), %eax
20346
20347 (define_peephole2
20348   [(parallel [(set (match_operand 0 "register_operand" "")
20349                    (ashift (match_operand 1 "register_operand" "")
20350                            (match_operand 2 "const_int_operand" "")))
20351                (clobber (reg:CC FLAGS_REG))])
20352    (set (match_operand 3 "register_operand")
20353         (match_operand 4 "x86_64_general_operand" ""))
20354    (parallel [(set (match_operand 5 "register_operand" "")
20355                    (plus (match_operand 6 "register_operand" "")
20356                          (match_operand 7 "register_operand" "")))
20357                    (clobber (reg:CC FLAGS_REG))])]
20358   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20359    /* Validate MODE for lea.  */
20360    && ((!TARGET_PARTIAL_REG_STALL
20361         && (GET_MODE (operands[0]) == QImode
20362             || GET_MODE (operands[0]) == HImode))
20363        || GET_MODE (operands[0]) == SImode
20364        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20365    /* We reorder load and the shift.  */
20366    && !rtx_equal_p (operands[1], operands[3])
20367    && !reg_overlap_mentioned_p (operands[0], operands[4])
20368    /* Last PLUS must consist of operand 0 and 3.  */
20369    && !rtx_equal_p (operands[0], operands[3])
20370    && (rtx_equal_p (operands[3], operands[6])
20371        || rtx_equal_p (operands[3], operands[7]))
20372    && (rtx_equal_p (operands[0], operands[6])
20373        || rtx_equal_p (operands[0], operands[7]))
20374    /* The intermediate operand 0 must die or be same as output.  */
20375    && (rtx_equal_p (operands[0], operands[5])
20376        || peep2_reg_dead_p (3, operands[0]))"
20377   [(set (match_dup 3) (match_dup 4))
20378    (set (match_dup 0) (match_dup 1))]
20379 {
20380   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20381   int scale = 1 << INTVAL (operands[2]);
20382   rtx index = gen_lowpart (Pmode, operands[1]);
20383   rtx base = gen_lowpart (Pmode, operands[3]);
20384   rtx dest = gen_lowpart (mode, operands[5]);
20385
20386   operands[1] = gen_rtx_PLUS (Pmode, base,
20387                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20388   if (mode != Pmode)
20389     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20390   operands[0] = dest;
20391 })
20392 \f
20393 ;; Call-value patterns last so that the wildcard operand does not
20394 ;; disrupt insn-recog's switch tables.
20395
20396 (define_insn "*call_value_pop_0"
20397   [(set (match_operand 0 "" "")
20398         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20399               (match_operand:SI 2 "" "")))
20400    (set (reg:SI SP_REG)
20401         (plus:SI (reg:SI SP_REG)
20402                  (match_operand:SI 3 "immediate_operand" "")))]
20403   "!TARGET_64BIT"
20404 {
20405   if (SIBLING_CALL_P (insn))
20406     return "jmp\t%P1";
20407   else
20408     return "call\t%P1";
20409 }
20410   [(set_attr "type" "callv")])
20411
20412 (define_insn "*call_value_pop_1"
20413   [(set (match_operand 0 "" "")
20414         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20415               (match_operand:SI 2 "" "")))
20416    (set (reg:SI SP_REG)
20417         (plus:SI (reg:SI SP_REG)
20418                  (match_operand:SI 3 "immediate_operand" "i")))]
20419   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20420 {
20421   if (constant_call_address_operand (operands[1], Pmode))
20422     return "call\t%P1";
20423   return "call\t%A1";
20424 }
20425   [(set_attr "type" "callv")])
20426
20427 (define_insn "*sibcall_value_pop_1"
20428   [(set (match_operand 0 "" "")
20429         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20430               (match_operand:SI 2 "" "")))
20431    (set (reg:SI SP_REG)
20432         (plus:SI (reg:SI SP_REG)
20433                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20434   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20435   "@
20436    jmp\t%P1
20437    jmp\t%A1"
20438   [(set_attr "type" "callv")])
20439
20440 (define_insn "*call_value_0"
20441   [(set (match_operand 0 "" "")
20442         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20443               (match_operand:SI 2 "" "")))]
20444   "!TARGET_64BIT"
20445 {
20446   if (SIBLING_CALL_P (insn))
20447     return "jmp\t%P1";
20448   else
20449     return "call\t%P1";
20450 }
20451   [(set_attr "type" "callv")])
20452
20453 (define_insn "*call_value_0_rex64"
20454   [(set (match_operand 0 "" "")
20455         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20456               (match_operand:DI 2 "const_int_operand" "")))]
20457   "TARGET_64BIT"
20458 {
20459   if (SIBLING_CALL_P (insn))
20460     return "jmp\t%P1";
20461   else
20462     return "call\t%P1";
20463 }
20464   [(set_attr "type" "callv")])
20465
20466 (define_insn "*call_value_0_rex64_ms_sysv"
20467   [(set (match_operand 0 "" "")
20468         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20469               (match_operand:DI 2 "const_int_operand" "")))
20470    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20471    (clobber (reg:TI XMM6_REG))
20472    (clobber (reg:TI XMM7_REG))
20473    (clobber (reg:TI XMM8_REG))
20474    (clobber (reg:TI XMM9_REG))
20475    (clobber (reg:TI XMM10_REG))
20476    (clobber (reg:TI XMM11_REG))
20477    (clobber (reg:TI XMM12_REG))
20478    (clobber (reg:TI XMM13_REG))
20479    (clobber (reg:TI XMM14_REG))
20480    (clobber (reg:TI XMM15_REG))
20481    (clobber (reg:DI SI_REG))
20482    (clobber (reg:DI DI_REG))]
20483   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20484 {
20485   if (SIBLING_CALL_P (insn))
20486     return "jmp\t%P1";
20487   else
20488     return "call\t%P1";
20489 }
20490   [(set_attr "type" "callv")])
20491
20492 (define_insn "*call_value_1"
20493   [(set (match_operand 0 "" "")
20494         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20495               (match_operand:SI 2 "" "")))]
20496   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20497 {
20498   if (constant_call_address_operand (operands[1], Pmode))
20499     return "call\t%P1";
20500   return "call\t%A1";
20501 }
20502   [(set_attr "type" "callv")])
20503
20504 (define_insn "*sibcall_value_1"
20505   [(set (match_operand 0 "" "")
20506         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20507               (match_operand:SI 2 "" "")))]
20508   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20509   "@
20510    jmp\t%P1
20511    jmp\t%A1"
20512   [(set_attr "type" "callv")])
20513
20514 (define_insn "*call_value_1_rex64"
20515   [(set (match_operand 0 "" "")
20516         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20517               (match_operand:DI 2 "" "")))]
20518   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20519    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20520 {
20521   if (constant_call_address_operand (operands[1], Pmode))
20522     return "call\t%P1";
20523   return "call\t%A1";
20524 }
20525   [(set_attr "type" "callv")])
20526
20527 (define_insn "*call_value_1_rex64_ms_sysv"
20528   [(set (match_operand 0 "" "")
20529         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20530               (match_operand:DI 2 "" "")))
20531    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20532    (clobber (reg:TI XMM6_REG))
20533    (clobber (reg:TI XMM7_REG))
20534    (clobber (reg:TI XMM8_REG))
20535    (clobber (reg:TI XMM9_REG))
20536    (clobber (reg:TI XMM10_REG))
20537    (clobber (reg:TI XMM11_REG))
20538    (clobber (reg:TI XMM12_REG))
20539    (clobber (reg:TI XMM13_REG))
20540    (clobber (reg:TI XMM14_REG))
20541    (clobber (reg:TI XMM15_REG))
20542    (clobber (reg:DI SI_REG))
20543    (clobber (reg:DI DI_REG))]
20544   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20545 {
20546   if (constant_call_address_operand (operands[1], Pmode))
20547     return "call\t%P1";
20548   return "call\t%A1";
20549 }
20550   [(set_attr "type" "callv")])
20551
20552 (define_insn "*call_value_1_rex64_large"
20553   [(set (match_operand 0 "" "")
20554         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20555               (match_operand:DI 2 "" "")))]
20556   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20557   "call\t%A1"
20558   [(set_attr "type" "callv")])
20559
20560 (define_insn "*sibcall_value_1_rex64"
20561   [(set (match_operand 0 "" "")
20562         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20563               (match_operand:DI 2 "" "")))]
20564   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20565   "@
20566    jmp\t%P1
20567    jmp\t%A1"
20568   [(set_attr "type" "callv")])
20569 \f
20570 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20571 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20572 ;; caught for use by garbage collectors and the like.  Using an insn that
20573 ;; maps to SIGILL makes it more likely the program will rightfully die.
20574 ;; Keeping with tradition, "6" is in honor of #UD.
20575 (define_insn "trap"
20576   [(trap_if (const_int 1) (const_int 6))]
20577   ""
20578   { return ASM_SHORT "0x0b0f"; }
20579   [(set_attr "length" "2")])
20580
20581 (define_expand "sse_prologue_save"
20582   [(parallel [(set (match_operand:BLK 0 "" "")
20583                    (unspec:BLK [(reg:DI XMM0_REG)
20584                                 (reg:DI XMM1_REG)
20585                                 (reg:DI XMM2_REG)
20586                                 (reg:DI XMM3_REG)
20587                                 (reg:DI XMM4_REG)
20588                                 (reg:DI XMM5_REG)
20589                                 (reg:DI XMM6_REG)
20590                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20591               (use (match_operand:DI 1 "register_operand" ""))
20592               (use (match_operand:DI 2 "immediate_operand" ""))
20593               (use (label_ref:DI (match_operand 3 "" "")))])]
20594   "TARGET_64BIT"
20595   "")
20596
20597 (define_insn "*sse_prologue_save_insn"
20598   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20599                           (match_operand:DI 4 "const_int_operand" "n")))
20600         (unspec:BLK [(reg:DI XMM0_REG)
20601                      (reg:DI XMM1_REG)
20602                      (reg:DI XMM2_REG)
20603                      (reg:DI XMM3_REG)
20604                      (reg:DI XMM4_REG)
20605                      (reg:DI XMM5_REG)
20606                      (reg:DI XMM6_REG)
20607                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20608    (use (match_operand:DI 1 "register_operand" "r"))
20609    (use (match_operand:DI 2 "const_int_operand" "i"))
20610    (use (label_ref:DI (match_operand 3 "" "X")))]
20611   "TARGET_64BIT
20612    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20613    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20614 {
20615   int i;
20616   operands[0] = gen_rtx_MEM (Pmode,
20617                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20618   /* VEX instruction with a REX prefix will #UD.  */
20619   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20620     gcc_unreachable ();
20621
20622   output_asm_insn ("jmp\t%A1", operands);
20623   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20624     {
20625       operands[4] = adjust_address (operands[0], DImode, i*16);
20626       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20627       PUT_MODE (operands[4], TImode);
20628       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20629         output_asm_insn ("rex", operands);
20630       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20631     }
20632   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20633                                      CODE_LABEL_NUMBER (operands[3]));
20634   return "";
20635 }
20636   [(set_attr "type" "other")
20637    (set_attr "length_immediate" "0")
20638    (set_attr "length_address" "0")
20639    (set (attr "length")
20640      (if_then_else
20641        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20642        (const_string "34")
20643        (const_string "42")))
20644    (set_attr "memory" "store")
20645    (set_attr "modrm" "0")
20646    (set_attr "prefix" "maybe_vex")
20647    (set_attr "mode" "DI")])
20648
20649 (define_expand "prefetch"
20650   [(prefetch (match_operand 0 "address_operand" "")
20651              (match_operand:SI 1 "const_int_operand" "")
20652              (match_operand:SI 2 "const_int_operand" ""))]
20653   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20654 {
20655   int rw = INTVAL (operands[1]);
20656   int locality = INTVAL (operands[2]);
20657
20658   gcc_assert (rw == 0 || rw == 1);
20659   gcc_assert (locality >= 0 && locality <= 3);
20660   gcc_assert (GET_MODE (operands[0]) == Pmode
20661               || GET_MODE (operands[0]) == VOIDmode);
20662
20663   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20664      supported by SSE counterpart or the SSE prefetch is not available
20665      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20666      of locality.  */
20667   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20668     operands[2] = GEN_INT (3);
20669   else
20670     operands[1] = const0_rtx;
20671 })
20672
20673 (define_insn "*prefetch_sse"
20674   [(prefetch (match_operand:SI 0 "address_operand" "p")
20675              (const_int 0)
20676              (match_operand:SI 1 "const_int_operand" ""))]
20677   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20678 {
20679   static const char * const patterns[4] = {
20680    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20681   };
20682
20683   int locality = INTVAL (operands[1]);
20684   gcc_assert (locality >= 0 && locality <= 3);
20685
20686   return patterns[locality];
20687 }
20688   [(set_attr "type" "sse")
20689    (set_attr "atom_sse_attr" "prefetch")
20690    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20691    (set_attr "memory" "none")])
20692
20693 (define_insn "*prefetch_sse_rex"
20694   [(prefetch (match_operand:DI 0 "address_operand" "p")
20695              (const_int 0)
20696              (match_operand:SI 1 "const_int_operand" ""))]
20697   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20698 {
20699   static const char * const patterns[4] = {
20700    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20701   };
20702
20703   int locality = INTVAL (operands[1]);
20704   gcc_assert (locality >= 0 && locality <= 3);
20705
20706   return patterns[locality];
20707 }
20708   [(set_attr "type" "sse")
20709    (set_attr "atom_sse_attr" "prefetch")
20710    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20711    (set_attr "memory" "none")])
20712
20713 (define_insn "*prefetch_3dnow"
20714   [(prefetch (match_operand:SI 0 "address_operand" "p")
20715              (match_operand:SI 1 "const_int_operand" "n")
20716              (const_int 3))]
20717   "TARGET_3DNOW && !TARGET_64BIT"
20718 {
20719   if (INTVAL (operands[1]) == 0)
20720     return "prefetch\t%a0";
20721   else
20722     return "prefetchw\t%a0";
20723 }
20724   [(set_attr "type" "mmx")
20725    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20726    (set_attr "memory" "none")])
20727
20728 (define_insn "*prefetch_3dnow_rex"
20729   [(prefetch (match_operand:DI 0 "address_operand" "p")
20730              (match_operand:SI 1 "const_int_operand" "n")
20731              (const_int 3))]
20732   "TARGET_3DNOW && TARGET_64BIT"
20733 {
20734   if (INTVAL (operands[1]) == 0)
20735     return "prefetch\t%a0";
20736   else
20737     return "prefetchw\t%a0";
20738 }
20739   [(set_attr "type" "mmx")
20740    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20741    (set_attr "memory" "none")])
20742
20743 (define_expand "stack_protect_set"
20744   [(match_operand 0 "memory_operand" "")
20745    (match_operand 1 "memory_operand" "")]
20746   ""
20747 {
20748 #ifdef TARGET_THREAD_SSP_OFFSET
20749   if (TARGET_64BIT)
20750     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20751                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20752   else
20753     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20754                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20755 #else
20756   if (TARGET_64BIT)
20757     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20758   else
20759     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20760 #endif
20761   DONE;
20762 })
20763
20764 (define_insn "stack_protect_set_si"
20765   [(set (match_operand:SI 0 "memory_operand" "=m")
20766         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20767    (set (match_scratch:SI 2 "=&r") (const_int 0))
20768    (clobber (reg:CC FLAGS_REG))]
20769   ""
20770   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20771   [(set_attr "type" "multi")])
20772
20773 (define_insn "stack_protect_set_di"
20774   [(set (match_operand:DI 0 "memory_operand" "=m")
20775         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20776    (set (match_scratch:DI 2 "=&r") (const_int 0))
20777    (clobber (reg:CC FLAGS_REG))]
20778   "TARGET_64BIT"
20779   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20780   [(set_attr "type" "multi")])
20781
20782 (define_insn "stack_tls_protect_set_si"
20783   [(set (match_operand:SI 0 "memory_operand" "=m")
20784         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20785    (set (match_scratch:SI 2 "=&r") (const_int 0))
20786    (clobber (reg:CC FLAGS_REG))]
20787   ""
20788   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20789   [(set_attr "type" "multi")])
20790
20791 (define_insn "stack_tls_protect_set_di"
20792   [(set (match_operand:DI 0 "memory_operand" "=m")
20793         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20794    (set (match_scratch:DI 2 "=&r") (const_int 0))
20795    (clobber (reg:CC FLAGS_REG))]
20796   "TARGET_64BIT"
20797   {
20798      /* The kernel uses a different segment register for performance reasons; a
20799         system call would not have to trash the userspace segment register,
20800         which would be expensive */
20801      if (ix86_cmodel != CM_KERNEL)
20802         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20803      else
20804         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20805   }
20806   [(set_attr "type" "multi")])
20807
20808 (define_expand "stack_protect_test"
20809   [(match_operand 0 "memory_operand" "")
20810    (match_operand 1 "memory_operand" "")
20811    (match_operand 2 "" "")]
20812   ""
20813 {
20814   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20815
20816 #ifdef TARGET_THREAD_SSP_OFFSET
20817   if (TARGET_64BIT)
20818     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20819                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20820   else
20821     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20822                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20823 #else
20824   if (TARGET_64BIT)
20825     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20826   else
20827     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20828 #endif
20829
20830   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20831                                   flags, const0_rtx, operands[2]));
20832   DONE;
20833 })
20834
20835 (define_insn "stack_protect_test_si"
20836   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20837         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20838                      (match_operand:SI 2 "memory_operand" "m")]
20839                     UNSPEC_SP_TEST))
20840    (clobber (match_scratch:SI 3 "=&r"))]
20841   ""
20842   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20843   [(set_attr "type" "multi")])
20844
20845 (define_insn "stack_protect_test_di"
20846   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20847         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20848                      (match_operand:DI 2 "memory_operand" "m")]
20849                     UNSPEC_SP_TEST))
20850    (clobber (match_scratch:DI 3 "=&r"))]
20851   "TARGET_64BIT"
20852   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20853   [(set_attr "type" "multi")])
20854
20855 (define_insn "stack_tls_protect_test_si"
20856   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20857         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20858                      (match_operand:SI 2 "const_int_operand" "i")]
20859                     UNSPEC_SP_TLS_TEST))
20860    (clobber (match_scratch:SI 3 "=r"))]
20861   ""
20862   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20863   [(set_attr "type" "multi")])
20864
20865 (define_insn "stack_tls_protect_test_di"
20866   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20867         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20868                      (match_operand:DI 2 "const_int_operand" "i")]
20869                     UNSPEC_SP_TLS_TEST))
20870    (clobber (match_scratch:DI 3 "=r"))]
20871   "TARGET_64BIT"
20872   {
20873      /* The kernel uses a different segment register for performance reasons; a
20874         system call would not have to trash the userspace segment register,
20875         which would be expensive */
20876      if (ix86_cmodel != CM_KERNEL)
20877         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20878      else
20879         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20880   }
20881   [(set_attr "type" "multi")])
20882
20883 (define_insn "sse4_2_crc32<mode>"
20884   [(set (match_operand:SI 0 "register_operand" "=r")
20885         (unspec:SI
20886           [(match_operand:SI 1 "register_operand" "0")
20887            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20888           UNSPEC_CRC32))]
20889   "TARGET_SSE4_2 || TARGET_CRC32"
20890   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20891   [(set_attr "type" "sselog1")
20892    (set_attr "prefix_rep" "1")
20893    (set_attr "prefix_extra" "1")
20894    (set (attr "prefix_data16")
20895      (if_then_else (match_operand:HI 2 "" "")
20896        (const_string "1")
20897        (const_string "*")))
20898    (set (attr "prefix_rex")
20899      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20900        (const_string "1")
20901        (const_string "*")))
20902    (set_attr "mode" "SI")])
20903
20904 (define_insn "sse4_2_crc32di"
20905   [(set (match_operand:DI 0 "register_operand" "=r")
20906         (unspec:DI
20907           [(match_operand:DI 1 "register_operand" "0")
20908            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20909           UNSPEC_CRC32))]
20910   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20911   "crc32{q}\t{%2, %0|%0, %2}"
20912   [(set_attr "type" "sselog1")
20913    (set_attr "prefix_rep" "1")
20914    (set_attr "prefix_extra" "1")
20915    (set_attr "mode" "DI")])
20916
20917 (define_expand "rdpmc"
20918   [(match_operand:DI 0 "register_operand" "")
20919    (match_operand:SI 1 "register_operand" "")]
20920   ""
20921 {
20922   rtx reg = gen_reg_rtx (DImode);
20923   rtx si;
20924
20925   /* Force operand 1 into ECX.  */
20926   rtx ecx = gen_rtx_REG (SImode, CX_REG);
20927   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20928   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20929                                 UNSPECV_RDPMC);
20930
20931   if (TARGET_64BIT)
20932     {
20933       rtvec vec = rtvec_alloc (2);
20934       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20935       rtx upper = gen_reg_rtx (DImode);
20936       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20937                                         gen_rtvec (1, const0_rtx),
20938                                         UNSPECV_RDPMC);
20939       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20940       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20941       emit_insn (load);
20942       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20943                                    NULL, 1, OPTAB_DIRECT);
20944       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20945                                  OPTAB_DIRECT);
20946     }
20947   else
20948     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20949   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20950   DONE;
20951 })
20952
20953 (define_insn "*rdpmc"
20954   [(set (match_operand:DI 0 "register_operand" "=A")
20955         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20956                             UNSPECV_RDPMC))]
20957   "!TARGET_64BIT"
20958   "rdpmc"
20959   [(set_attr "type" "other")
20960    (set_attr "length" "2")])
20961
20962 (define_insn "*rdpmc_rex64"
20963   [(set (match_operand:DI 0 "register_operand" "=a")
20964         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20965                             UNSPECV_RDPMC))
20966   (set (match_operand:DI 1 "register_operand" "=d")
20967        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20968   "TARGET_64BIT"
20969   "rdpmc"
20970   [(set_attr "type" "other")
20971    (set_attr "length" "2")])
20972
20973 (define_expand "rdtsc"
20974   [(set (match_operand:DI 0 "register_operand" "")
20975         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20976   ""
20977 {
20978   if (TARGET_64BIT)
20979     {
20980       rtvec vec = rtvec_alloc (2);
20981       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20982       rtx upper = gen_reg_rtx (DImode);
20983       rtx lower = gen_reg_rtx (DImode);
20984       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20985                                          gen_rtvec (1, const0_rtx),
20986                                          UNSPECV_RDTSC);
20987       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20988       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20989       emit_insn (load);
20990       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20991                                    NULL, 1, OPTAB_DIRECT);
20992       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20993                                    OPTAB_DIRECT);
20994       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20995       DONE;
20996     }
20997 })
20998
20999 (define_insn "*rdtsc"
21000   [(set (match_operand:DI 0 "register_operand" "=A")
21001         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21002   "!TARGET_64BIT"
21003   "rdtsc"
21004   [(set_attr "type" "other")
21005    (set_attr "length" "2")])
21006
21007 (define_insn "*rdtsc_rex64"
21008   [(set (match_operand:DI 0 "register_operand" "=a")
21009         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21010    (set (match_operand:DI 1 "register_operand" "=d")
21011         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21012   "TARGET_64BIT"
21013   "rdtsc"
21014   [(set_attr "type" "other")
21015    (set_attr "length" "2")])
21016
21017 (define_expand "rdtscp"
21018   [(match_operand:DI 0 "register_operand" "")
21019    (match_operand:SI 1 "memory_operand" "")]
21020   ""
21021 {
21022   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21023                                     gen_rtvec (1, const0_rtx),
21024                                     UNSPECV_RDTSCP);
21025   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21026                                     gen_rtvec (1, const0_rtx),
21027                                     UNSPECV_RDTSCP);
21028   rtx reg = gen_reg_rtx (DImode);
21029   rtx tmp = gen_reg_rtx (SImode);
21030
21031   if (TARGET_64BIT)
21032     {
21033       rtvec vec = rtvec_alloc (3);
21034       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21035       rtx upper = gen_reg_rtx (DImode);
21036       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21037       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21038       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21039       emit_insn (load);
21040       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21041                                    NULL, 1, OPTAB_DIRECT);
21042       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21043                                  OPTAB_DIRECT);
21044     }
21045   else
21046     {
21047       rtvec vec = rtvec_alloc (2);
21048       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21049       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21050       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21051       emit_insn (load);
21052     }
21053   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21054   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21055   DONE;
21056 })
21057
21058 (define_insn "*rdtscp"
21059   [(set (match_operand:DI 0 "register_operand" "=A")
21060         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21061    (set (match_operand:SI 1 "register_operand" "=c")
21062         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21063   "!TARGET_64BIT"
21064   "rdtscp"
21065   [(set_attr "type" "other")
21066    (set_attr "length" "3")])
21067
21068 (define_insn "*rdtscp_rex64"
21069   [(set (match_operand:DI 0 "register_operand" "=a")
21070         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21071    (set (match_operand:DI 1 "register_operand" "=d")
21072         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21073    (set (match_operand:SI 2 "register_operand" "=c")
21074         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21075   "TARGET_64BIT"
21076   "rdtscp"
21077   [(set_attr "type" "other")
21078    (set_attr "length" "3")])
21079
21080 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21081 ;;
21082 ;; LWP instructions
21083 ;;
21084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21085
21086 (define_insn "lwp_llwpcbhi1"
21087   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21088            UNSPEC_LLWP_INTRINSIC)]
21089   "TARGET_LWP"
21090   "llwpcb\t%0"
21091   [(set_attr "type" "lwp")
21092    (set_attr "mode" "HI")])
21093
21094 (define_insn "lwp_llwpcbsi1"
21095   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21096            UNSPEC_LLWP_INTRINSIC)]
21097   "TARGET_LWP"
21098   "llwpcb\t%0"
21099   [(set_attr "type" "lwp")
21100    (set_attr "mode" "SI")])
21101
21102 (define_insn "lwp_llwpcbdi1"
21103   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21104            UNSPEC_LLWP_INTRINSIC)]
21105   "TARGET_LWP"
21106   "llwpcb\t%0"
21107   [(set_attr "type" "lwp")
21108    (set_attr "mode" "DI")])
21109
21110 (define_insn "lwp_slwpcbhi1"
21111   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21112            UNSPEC_SLWP_INTRINSIC)]
21113   "TARGET_LWP"
21114   "slwpcb\t%0"
21115   [(set_attr "type" "lwp")
21116    (set_attr "mode" "HI")])
21117
21118 (define_insn "lwp_slwpcbsi1"
21119   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21120            UNSPEC_SLWP_INTRINSIC)]
21121   "TARGET_LWP"
21122   "slwpcb\t%0"
21123   [(set_attr "type" "lwp")
21124    (set_attr "mode" "SI")])
21125
21126 (define_insn "lwp_slwpcbdi1"
21127   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21128            UNSPEC_SLWP_INTRINSIC)]
21129   "TARGET_LWP"
21130   "slwpcb\t%0"
21131   [(set_attr "type" "lwp")
21132    (set_attr "mode" "DI")])
21133
21134 (define_insn "lwp_lwpvalhi3"
21135   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21136                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21137                      (match_operand:HI 2 "const_int_operand" "")]
21138                     UNSPECV_LWPVAL_INTRINSIC)]
21139   "TARGET_LWP"
21140   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21141   [(set_attr "type" "lwp")
21142    (set_attr "mode" "HI")])
21143
21144 (define_insn "lwp_lwpvalsi3"
21145   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21146                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21147                      (match_operand:SI 2 "const_int_operand" "")]
21148                     UNSPECV_LWPVAL_INTRINSIC)]
21149   "TARGET_LWP"
21150   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21151   [(set_attr "type" "lwp")
21152    (set_attr "mode" "SI")])
21153
21154 (define_insn "lwp_lwpvaldi3"
21155   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21156                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21157                      (match_operand:SI 2 "const_int_operand" "")]
21158                     UNSPECV_LWPVAL_INTRINSIC)]
21159   "TARGET_LWP"
21160   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21161   [(set_attr "type" "lwp")
21162    (set_attr "mode" "DI")])
21163
21164 (define_insn "lwp_lwpinshi3"
21165   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21166                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21167                      (match_operand:HI 2 "const_int_operand" "")]
21168                     UNSPECV_LWPINS_INTRINSIC)]
21169   "TARGET_LWP"
21170   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21171   [(set_attr "type" "lwp")
21172    (set_attr "mode" "HI")])
21173
21174 (define_insn "lwp_lwpinssi3"
21175   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21176                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21177                      (match_operand:SI 2 "const_int_operand" "")]
21178                     UNSPECV_LWPINS_INTRINSIC)]
21179   "TARGET_LWP"
21180   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21181   [(set_attr "type" "lwp")
21182    (set_attr "mode" "SI")])
21183
21184 (define_insn "lwp_lwpinsdi3"
21185   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21186                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21187                      (match_operand:SI 2 "const_int_operand" "")]
21188                     UNSPECV_LWPINS_INTRINSIC)]
21189   "TARGET_LWP"
21190   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21191   [(set_attr "type" "lwp")
21192    (set_attr "mode" "DI")])
21193
21194 (include "mmx.md")
21195 (include "sse.md")
21196 (include "sync.md")