OSDN Git Service

Fix FMA4 and XOP insns.
[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 [(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 ;; SSE and x87 SFmode and DFmode floating point modes
805 (define_mode_iterator MODEF [SF DF])
806
807 ;; All x87 floating point modes
808 (define_mode_iterator X87MODEF [SF DF XF])
809
810 ;; All integer modes handled by x87 fisttp operator.
811 (define_mode_iterator X87MODEI [HI SI DI])
812
813 ;; All integer modes handled by integer x87 operators.
814 (define_mode_iterator X87MODEI12 [HI SI])
815
816 ;; All integer modes handled by SSE cvtts?2si* operators.
817 (define_mode_iterator SSEMODEI24 [SI DI])
818
819 ;; SSE asm suffix for floating point modes
820 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
821
822 ;; SSE vector mode corresponding to a scalar mode
823 (define_mode_attr ssevecmode
824   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
825
826 ;; Instruction suffix for REX 64bit operators.
827 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
828
829 ;; This mode iterator allows :P to be used for patterns that operate on
830 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
831 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
832 \f
833 ;; Scheduling descriptions
834
835 (include "pentium.md")
836 (include "ppro.md")
837 (include "k6.md")
838 (include "athlon.md")
839 (include "geode.md")
840 (include "atom.md")
841
842 \f
843 ;; Operand and operator predicates and constraints
844
845 (include "predicates.md")
846 (include "constraints.md")
847
848 \f
849 ;; Compare and branch/compare and store instructions.
850
851 (define_expand "cbranch<mode>4"
852   [(set (reg:CC FLAGS_REG)
853         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
854                     (match_operand:SDWIM 2 "<general_operand>" "")))
855    (set (pc) (if_then_else
856                (match_operator 0 "comparison_operator"
857                 [(reg:CC FLAGS_REG) (const_int 0)])
858                (label_ref (match_operand 3 "" ""))
859                (pc)))]
860   ""
861 {
862   if (MEM_P (operands[1]) && MEM_P (operands[2]))
863     operands[1] = force_reg (<MODE>mode, operands[1]);
864   ix86_compare_op0 = operands[1];
865   ix86_compare_op1 = operands[2];
866   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
867   DONE;
868 })
869
870 (define_expand "cstore<mode>4"
871   [(set (reg:CC FLAGS_REG)
872         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
873                     (match_operand:SWIM 3 "<general_operand>" "")))
874    (set (match_operand:QI 0 "register_operand" "")
875         (match_operator 1 "comparison_operator"
876           [(reg:CC FLAGS_REG) (const_int 0)]))]
877   ""
878 {
879   if (MEM_P (operands[2]) && MEM_P (operands[3]))
880     operands[2] = force_reg (<MODE>mode, operands[2]);
881   ix86_compare_op0 = operands[2];
882   ix86_compare_op1 = operands[3];
883   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
884   DONE;
885 })
886
887 (define_expand "cmp<mode>_1"
888   [(set (reg:CC FLAGS_REG)
889         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
890                     (match_operand:SWI48 1 "<general_operand>" "")))]
891   ""
892   "")
893
894 (define_insn "*cmp<mode>_ccno_1"
895   [(set (reg FLAGS_REG)
896         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
897                  (match_operand:SWI 1 "const0_operand" "")))]
898   "ix86_match_ccmode (insn, CCNOmode)"
899   "@
900    test{<imodesuffix>}\t%0, %0
901    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
902   [(set_attr "type" "test,icmp")
903    (set_attr "length_immediate" "0,1")
904    (set_attr "mode" "<MODE>")])
905
906 (define_insn "*cmp<mode>_1"
907   [(set (reg FLAGS_REG)
908         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
909                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
910   "ix86_match_ccmode (insn, CCmode)"
911   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
912   [(set_attr "type" "icmp")
913    (set_attr "mode" "<MODE>")])
914
915 (define_insn "*cmp<mode>_minus_1"
916   [(set (reg FLAGS_REG)
917         (compare
918           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
919                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
920           (const_int 0)))]
921   "ix86_match_ccmode (insn, CCGOCmode)"
922   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
923   [(set_attr "type" "icmp")
924    (set_attr "mode" "<MODE>")])
925
926 (define_insn "*cmpqi_ext_1"
927   [(set (reg FLAGS_REG)
928         (compare
929           (match_operand:QI 0 "general_operand" "Qm")
930           (subreg:QI
931             (zero_extract:SI
932               (match_operand 1 "ext_register_operand" "Q")
933               (const_int 8)
934               (const_int 8)) 0)))]
935   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
936   "cmp{b}\t{%h1, %0|%0, %h1}"
937   [(set_attr "type" "icmp")
938    (set_attr "mode" "QI")])
939
940 (define_insn "*cmpqi_ext_1_rex64"
941   [(set (reg FLAGS_REG)
942         (compare
943           (match_operand:QI 0 "register_operand" "Q")
944           (subreg:QI
945             (zero_extract:SI
946               (match_operand 1 "ext_register_operand" "Q")
947               (const_int 8)
948               (const_int 8)) 0)))]
949   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
950   "cmp{b}\t{%h1, %0|%0, %h1}"
951   [(set_attr "type" "icmp")
952    (set_attr "mode" "QI")])
953
954 (define_insn "*cmpqi_ext_2"
955   [(set (reg FLAGS_REG)
956         (compare
957           (subreg:QI
958             (zero_extract:SI
959               (match_operand 0 "ext_register_operand" "Q")
960               (const_int 8)
961               (const_int 8)) 0)
962           (match_operand:QI 1 "const0_operand" "")))]
963   "ix86_match_ccmode (insn, CCNOmode)"
964   "test{b}\t%h0, %h0"
965   [(set_attr "type" "test")
966    (set_attr "length_immediate" "0")
967    (set_attr "mode" "QI")])
968
969 (define_expand "cmpqi_ext_3"
970   [(set (reg:CC FLAGS_REG)
971         (compare:CC
972           (subreg:QI
973             (zero_extract:SI
974               (match_operand 0 "ext_register_operand" "")
975               (const_int 8)
976               (const_int 8)) 0)
977           (match_operand:QI 1 "immediate_operand" "")))]
978   ""
979   "")
980
981 (define_insn "*cmpqi_ext_3_insn"
982   [(set (reg FLAGS_REG)
983         (compare
984           (subreg:QI
985             (zero_extract:SI
986               (match_operand 0 "ext_register_operand" "Q")
987               (const_int 8)
988               (const_int 8)) 0)
989           (match_operand:QI 1 "general_operand" "Qmn")))]
990   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
991   "cmp{b}\t{%1, %h0|%h0, %1}"
992   [(set_attr "type" "icmp")
993    (set_attr "modrm" "1")
994    (set_attr "mode" "QI")])
995
996 (define_insn "*cmpqi_ext_3_insn_rex64"
997   [(set (reg FLAGS_REG)
998         (compare
999           (subreg:QI
1000             (zero_extract:SI
1001               (match_operand 0 "ext_register_operand" "Q")
1002               (const_int 8)
1003               (const_int 8)) 0)
1004           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1005   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1006   "cmp{b}\t{%1, %h0|%h0, %1}"
1007   [(set_attr "type" "icmp")
1008    (set_attr "modrm" "1")
1009    (set_attr "mode" "QI")])
1010
1011 (define_insn "*cmpqi_ext_4"
1012   [(set (reg FLAGS_REG)
1013         (compare
1014           (subreg:QI
1015             (zero_extract:SI
1016               (match_operand 0 "ext_register_operand" "Q")
1017               (const_int 8)
1018               (const_int 8)) 0)
1019           (subreg:QI
1020             (zero_extract:SI
1021               (match_operand 1 "ext_register_operand" "Q")
1022               (const_int 8)
1023               (const_int 8)) 0)))]
1024   "ix86_match_ccmode (insn, CCmode)"
1025   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1026   [(set_attr "type" "icmp")
1027    (set_attr "mode" "QI")])
1028
1029 ;; These implement float point compares.
1030 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1031 ;; which would allow mix and match FP modes on the compares.  Which is what
1032 ;; the old patterns did, but with many more of them.
1033
1034 (define_expand "cbranchxf4"
1035   [(set (reg:CC FLAGS_REG)
1036         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1037                     (match_operand:XF 2 "nonmemory_operand" "")))
1038    (set (pc) (if_then_else
1039               (match_operator 0 "ix86_fp_comparison_operator"
1040                [(reg:CC FLAGS_REG)
1041                 (const_int 0)])
1042               (label_ref (match_operand 3 "" ""))
1043               (pc)))]
1044   "TARGET_80387"
1045 {
1046   ix86_compare_op0 = operands[1];
1047   ix86_compare_op1 = operands[2];
1048   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1049   DONE;
1050 })
1051
1052 (define_expand "cstorexf4"
1053   [(set (reg:CC FLAGS_REG)
1054         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1055                     (match_operand:XF 3 "nonmemory_operand" "")))
1056    (set (match_operand:QI 0 "register_operand" "")
1057               (match_operator 1 "ix86_fp_comparison_operator"
1058                [(reg:CC FLAGS_REG)
1059                 (const_int 0)]))]
1060   "TARGET_80387"
1061 {
1062   ix86_compare_op0 = operands[2];
1063   ix86_compare_op1 = operands[3];
1064   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1065   DONE;
1066 })
1067
1068 (define_expand "cbranch<mode>4"
1069   [(set (reg:CC FLAGS_REG)
1070         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1071                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1072    (set (pc) (if_then_else
1073               (match_operator 0 "ix86_fp_comparison_operator"
1074                [(reg:CC FLAGS_REG)
1075                 (const_int 0)])
1076               (label_ref (match_operand 3 "" ""))
1077               (pc)))]
1078   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1079 {
1080   ix86_compare_op0 = operands[1];
1081   ix86_compare_op1 = operands[2];
1082   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1083   DONE;
1084 })
1085
1086 (define_expand "cstore<mode>4"
1087   [(set (reg:CC FLAGS_REG)
1088         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1089                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1090    (set (match_operand:QI 0 "register_operand" "")
1091               (match_operator 1 "ix86_fp_comparison_operator"
1092                [(reg:CC FLAGS_REG)
1093                 (const_int 0)]))]
1094   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1095 {
1096   ix86_compare_op0 = operands[2];
1097   ix86_compare_op1 = operands[3];
1098   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1099   DONE;
1100 })
1101
1102 (define_expand "cbranchcc4"
1103   [(set (pc) (if_then_else
1104               (match_operator 0 "comparison_operator"
1105                [(match_operand 1 "flags_reg_operand" "")
1106                 (match_operand 2 "const0_operand" "")])
1107               (label_ref (match_operand 3 "" ""))
1108               (pc)))]
1109   ""
1110 {
1111   ix86_compare_op0 = operands[1];
1112   ix86_compare_op1 = operands[2];
1113   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1114   DONE;
1115 })
1116
1117 (define_expand "cstorecc4"
1118   [(set (match_operand:QI 0 "register_operand" "")
1119               (match_operator 1 "comparison_operator"
1120                [(match_operand 2 "flags_reg_operand" "")
1121                 (match_operand 3 "const0_operand" "")]))]
1122   ""
1123 {
1124   ix86_compare_op0 = operands[2];
1125   ix86_compare_op1 = operands[3];
1126   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1127   DONE;
1128 })
1129
1130
1131 ;; FP compares, step 1:
1132 ;; Set the FP condition codes.
1133 ;;
1134 ;; CCFPmode     compare with exceptions
1135 ;; CCFPUmode    compare with no exceptions
1136
1137 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1138 ;; used to manage the reg stack popping would not be preserved.
1139
1140 (define_insn "*cmpfp_0"
1141   [(set (match_operand:HI 0 "register_operand" "=a")
1142         (unspec:HI
1143           [(compare:CCFP
1144              (match_operand 1 "register_operand" "f")
1145              (match_operand 2 "const0_operand" ""))]
1146         UNSPEC_FNSTSW))]
1147   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1148    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1149   "* return output_fp_compare (insn, operands, 0, 0);"
1150   [(set_attr "type" "multi")
1151    (set_attr "unit" "i387")
1152    (set (attr "mode")
1153      (cond [(match_operand:SF 1 "" "")
1154               (const_string "SF")
1155             (match_operand:DF 1 "" "")
1156               (const_string "DF")
1157            ]
1158            (const_string "XF")))])
1159
1160 (define_insn_and_split "*cmpfp_0_cc"
1161   [(set (reg:CCFP FLAGS_REG)
1162         (compare:CCFP
1163           (match_operand 1 "register_operand" "f")
1164           (match_operand 2 "const0_operand" "")))
1165    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1166   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1167    && TARGET_SAHF && !TARGET_CMOVE
1168    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1169   "#"
1170   "&& reload_completed"
1171   [(set (match_dup 0)
1172         (unspec:HI
1173           [(compare:CCFP (match_dup 1)(match_dup 2))]
1174         UNSPEC_FNSTSW))
1175    (set (reg:CC FLAGS_REG)
1176         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1177   ""
1178   [(set_attr "type" "multi")
1179    (set_attr "unit" "i387")
1180    (set (attr "mode")
1181      (cond [(match_operand:SF 1 "" "")
1182               (const_string "SF")
1183             (match_operand:DF 1 "" "")
1184               (const_string "DF")
1185            ]
1186            (const_string "XF")))])
1187
1188 (define_insn "*cmpfp_xf"
1189   [(set (match_operand:HI 0 "register_operand" "=a")
1190         (unspec:HI
1191           [(compare:CCFP
1192              (match_operand:XF 1 "register_operand" "f")
1193              (match_operand:XF 2 "register_operand" "f"))]
1194           UNSPEC_FNSTSW))]
1195   "TARGET_80387"
1196   "* return output_fp_compare (insn, operands, 0, 0);"
1197   [(set_attr "type" "multi")
1198    (set_attr "unit" "i387")
1199    (set_attr "mode" "XF")])
1200
1201 (define_insn_and_split "*cmpfp_xf_cc"
1202   [(set (reg:CCFP FLAGS_REG)
1203         (compare:CCFP
1204           (match_operand:XF 1 "register_operand" "f")
1205           (match_operand:XF 2 "register_operand" "f")))
1206    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1207   "TARGET_80387
1208    && TARGET_SAHF && !TARGET_CMOVE"
1209   "#"
1210   "&& reload_completed"
1211   [(set (match_dup 0)
1212         (unspec:HI
1213           [(compare:CCFP (match_dup 1)(match_dup 2))]
1214         UNSPEC_FNSTSW))
1215    (set (reg:CC FLAGS_REG)
1216         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1217   ""
1218   [(set_attr "type" "multi")
1219    (set_attr "unit" "i387")
1220    (set_attr "mode" "XF")])
1221
1222 (define_insn "*cmpfp_<mode>"
1223   [(set (match_operand:HI 0 "register_operand" "=a")
1224         (unspec:HI
1225           [(compare:CCFP
1226              (match_operand:MODEF 1 "register_operand" "f")
1227              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1228           UNSPEC_FNSTSW))]
1229   "TARGET_80387"
1230   "* return output_fp_compare (insn, operands, 0, 0);"
1231   [(set_attr "type" "multi")
1232    (set_attr "unit" "i387")
1233    (set_attr "mode" "<MODE>")])
1234
1235 (define_insn_and_split "*cmpfp_<mode>_cc"
1236   [(set (reg:CCFP FLAGS_REG)
1237         (compare:CCFP
1238           (match_operand:MODEF 1 "register_operand" "f")
1239           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1240    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1241   "TARGET_80387
1242    && TARGET_SAHF && !TARGET_CMOVE"
1243   "#"
1244   "&& reload_completed"
1245   [(set (match_dup 0)
1246         (unspec:HI
1247           [(compare:CCFP (match_dup 1)(match_dup 2))]
1248         UNSPEC_FNSTSW))
1249    (set (reg:CC FLAGS_REG)
1250         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1251   ""
1252   [(set_attr "type" "multi")
1253    (set_attr "unit" "i387")
1254    (set_attr "mode" "<MODE>")])
1255
1256 (define_insn "*cmpfp_u"
1257   [(set (match_operand:HI 0 "register_operand" "=a")
1258         (unspec:HI
1259           [(compare:CCFPU
1260              (match_operand 1 "register_operand" "f")
1261              (match_operand 2 "register_operand" "f"))]
1262           UNSPEC_FNSTSW))]
1263   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265   "* return output_fp_compare (insn, operands, 0, 1);"
1266   [(set_attr "type" "multi")
1267    (set_attr "unit" "i387")
1268    (set (attr "mode")
1269      (cond [(match_operand:SF 1 "" "")
1270               (const_string "SF")
1271             (match_operand:DF 1 "" "")
1272               (const_string "DF")
1273            ]
1274            (const_string "XF")))])
1275
1276 (define_insn_and_split "*cmpfp_u_cc"
1277   [(set (reg:CCFPU FLAGS_REG)
1278         (compare:CCFPU
1279           (match_operand 1 "register_operand" "f")
1280           (match_operand 2 "register_operand" "f")))
1281    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283    && TARGET_SAHF && !TARGET_CMOVE
1284    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1285   "#"
1286   "&& reload_completed"
1287   [(set (match_dup 0)
1288         (unspec:HI
1289           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1290         UNSPEC_FNSTSW))
1291    (set (reg:CC FLAGS_REG)
1292         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293   ""
1294   [(set_attr "type" "multi")
1295    (set_attr "unit" "i387")
1296    (set (attr "mode")
1297      (cond [(match_operand:SF 1 "" "")
1298               (const_string "SF")
1299             (match_operand:DF 1 "" "")
1300               (const_string "DF")
1301            ]
1302            (const_string "XF")))])
1303
1304 (define_insn "*cmpfp_<mode>"
1305   [(set (match_operand:HI 0 "register_operand" "=a")
1306         (unspec:HI
1307           [(compare:CCFP
1308              (match_operand 1 "register_operand" "f")
1309              (match_operator 3 "float_operator"
1310                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1311           UNSPEC_FNSTSW))]
1312   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1313    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1314    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1315   "* return output_fp_compare (insn, operands, 0, 0);"
1316   [(set_attr "type" "multi")
1317    (set_attr "unit" "i387")
1318    (set_attr "fp_int_src" "true")
1319    (set_attr "mode" "<MODE>")])
1320
1321 (define_insn_and_split "*cmpfp_<mode>_cc"
1322   [(set (reg:CCFP FLAGS_REG)
1323         (compare:CCFP
1324           (match_operand 1 "register_operand" "f")
1325           (match_operator 3 "float_operator"
1326             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1327    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1328   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1329    && TARGET_SAHF && !TARGET_CMOVE
1330    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1331    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1332   "#"
1333   "&& reload_completed"
1334   [(set (match_dup 0)
1335         (unspec:HI
1336           [(compare:CCFP
1337              (match_dup 1)
1338              (match_op_dup 3 [(match_dup 2)]))]
1339         UNSPEC_FNSTSW))
1340    (set (reg:CC FLAGS_REG)
1341         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1342   ""
1343   [(set_attr "type" "multi")
1344    (set_attr "unit" "i387")
1345    (set_attr "fp_int_src" "true")
1346    (set_attr "mode" "<MODE>")])
1347
1348 ;; FP compares, step 2
1349 ;; Move the fpsw to ax.
1350
1351 (define_insn "x86_fnstsw_1"
1352   [(set (match_operand:HI 0 "register_operand" "=a")
1353         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1354   "TARGET_80387"
1355   "fnstsw\t%0"
1356   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1357    (set_attr "mode" "SI")
1358    (set_attr "unit" "i387")])
1359
1360 ;; FP compares, step 3
1361 ;; Get ax into flags, general case.
1362
1363 (define_insn "x86_sahf_1"
1364   [(set (reg:CC FLAGS_REG)
1365         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1366                    UNSPEC_SAHF))]
1367   "TARGET_SAHF"
1368 {
1369 #ifdef HAVE_AS_IX86_SAHF
1370   return "sahf";
1371 #else
1372   return ASM_BYTE "0x9e";
1373 #endif
1374 }
1375   [(set_attr "length" "1")
1376    (set_attr "athlon_decode" "vector")
1377    (set_attr "amdfam10_decode" "direct")
1378    (set_attr "mode" "SI")])
1379
1380 ;; Pentium Pro can do steps 1 through 3 in one go.
1381 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1382 (define_insn "*cmpfp_i_mixed"
1383   [(set (reg:CCFP FLAGS_REG)
1384         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1385                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1386   "TARGET_MIX_SSE_I387
1387    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389   "* return output_fp_compare (insn, operands, 1, 0);"
1390   [(set_attr "type" "fcmp,ssecomi")
1391    (set_attr "prefix" "orig,maybe_vex")
1392    (set (attr "mode")
1393      (if_then_else (match_operand:SF 1 "" "")
1394         (const_string "SF")
1395         (const_string "DF")))
1396    (set (attr "prefix_rep")
1397         (if_then_else (eq_attr "type" "ssecomi")
1398                       (const_string "0")
1399                       (const_string "*")))
1400    (set (attr "prefix_data16")
1401         (cond [(eq_attr "type" "fcmp")
1402                  (const_string "*")
1403                (eq_attr "mode" "DF")
1404                  (const_string "1")
1405               ]
1406               (const_string "0")))
1407    (set_attr "athlon_decode" "vector")
1408    (set_attr "amdfam10_decode" "direct")])
1409
1410 (define_insn "*cmpfp_i_sse"
1411   [(set (reg:CCFP FLAGS_REG)
1412         (compare:CCFP (match_operand 0 "register_operand" "x")
1413                       (match_operand 1 "nonimmediate_operand" "xm")))]
1414   "TARGET_SSE_MATH
1415    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1416    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1417   "* return output_fp_compare (insn, operands, 1, 0);"
1418   [(set_attr "type" "ssecomi")
1419    (set_attr "prefix" "maybe_vex")
1420    (set (attr "mode")
1421      (if_then_else (match_operand:SF 1 "" "")
1422         (const_string "SF")
1423         (const_string "DF")))
1424    (set_attr "prefix_rep" "0")
1425    (set (attr "prefix_data16")
1426         (if_then_else (eq_attr "mode" "DF")
1427                       (const_string "1")
1428                       (const_string "0")))
1429    (set_attr "athlon_decode" "vector")
1430    (set_attr "amdfam10_decode" "direct")])
1431
1432 (define_insn "*cmpfp_i_i387"
1433   [(set (reg:CCFP FLAGS_REG)
1434         (compare:CCFP (match_operand 0 "register_operand" "f")
1435                       (match_operand 1 "register_operand" "f")))]
1436   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1437    && TARGET_CMOVE
1438    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1439    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1440   "* return output_fp_compare (insn, operands, 1, 0);"
1441   [(set_attr "type" "fcmp")
1442    (set (attr "mode")
1443      (cond [(match_operand:SF 1 "" "")
1444               (const_string "SF")
1445             (match_operand:DF 1 "" "")
1446               (const_string "DF")
1447            ]
1448            (const_string "XF")))
1449    (set_attr "athlon_decode" "vector")
1450    (set_attr "amdfam10_decode" "direct")])
1451
1452 (define_insn "*cmpfp_iu_mixed"
1453   [(set (reg:CCFPU FLAGS_REG)
1454         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1455                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1456   "TARGET_MIX_SSE_I387
1457    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1458    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1459   "* return output_fp_compare (insn, operands, 1, 1);"
1460   [(set_attr "type" "fcmp,ssecomi")
1461    (set_attr "prefix" "orig,maybe_vex")
1462    (set (attr "mode")
1463      (if_then_else (match_operand:SF 1 "" "")
1464         (const_string "SF")
1465         (const_string "DF")))
1466    (set (attr "prefix_rep")
1467         (if_then_else (eq_attr "type" "ssecomi")
1468                       (const_string "0")
1469                       (const_string "*")))
1470    (set (attr "prefix_data16")
1471         (cond [(eq_attr "type" "fcmp")
1472                  (const_string "*")
1473                (eq_attr "mode" "DF")
1474                  (const_string "1")
1475               ]
1476               (const_string "0")))
1477    (set_attr "athlon_decode" "vector")
1478    (set_attr "amdfam10_decode" "direct")])
1479
1480 (define_insn "*cmpfp_iu_sse"
1481   [(set (reg:CCFPU FLAGS_REG)
1482         (compare:CCFPU (match_operand 0 "register_operand" "x")
1483                        (match_operand 1 "nonimmediate_operand" "xm")))]
1484   "TARGET_SSE_MATH
1485    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1486    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1487   "* return output_fp_compare (insn, operands, 1, 1);"
1488   [(set_attr "type" "ssecomi")
1489    (set_attr "prefix" "maybe_vex")
1490    (set (attr "mode")
1491      (if_then_else (match_operand:SF 1 "" "")
1492         (const_string "SF")
1493         (const_string "DF")))
1494    (set_attr "prefix_rep" "0")
1495    (set (attr "prefix_data16")
1496         (if_then_else (eq_attr "mode" "DF")
1497                       (const_string "1")
1498                       (const_string "0")))
1499    (set_attr "athlon_decode" "vector")
1500    (set_attr "amdfam10_decode" "direct")])
1501
1502 (define_insn "*cmpfp_iu_387"
1503   [(set (reg:CCFPU FLAGS_REG)
1504         (compare:CCFPU (match_operand 0 "register_operand" "f")
1505                        (match_operand 1 "register_operand" "f")))]
1506   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1507    && TARGET_CMOVE
1508    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510   "* return output_fp_compare (insn, operands, 1, 1);"
1511   [(set_attr "type" "fcmp")
1512    (set (attr "mode")
1513      (cond [(match_operand:SF 1 "" "")
1514               (const_string "SF")
1515             (match_operand:DF 1 "" "")
1516               (const_string "DF")
1517            ]
1518            (const_string "XF")))
1519    (set_attr "athlon_decode" "vector")
1520    (set_attr "amdfam10_decode" "direct")])
1521 \f
1522 ;; Move instructions.
1523
1524 ;; General case of fullword move.
1525
1526 (define_expand "movsi"
1527   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1528         (match_operand:SI 1 "general_operand" ""))]
1529   ""
1530   "ix86_expand_move (SImode, operands); DONE;")
1531
1532 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1533 ;; general_operand.
1534 ;;
1535 ;; %%% We don't use a post-inc memory reference because x86 is not a
1536 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1537 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1538 ;; targets without our curiosities, and it is just as easy to represent
1539 ;; this differently.
1540
1541 (define_insn "*pushsi2"
1542   [(set (match_operand:SI 0 "push_operand" "=<")
1543         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1544   "!TARGET_64BIT"
1545   "push{l}\t%1"
1546   [(set_attr "type" "push")
1547    (set_attr "mode" "SI")])
1548
1549 ;; For 64BIT abi we always round up to 8 bytes.
1550 (define_insn "*pushsi2_rex64"
1551   [(set (match_operand:SI 0 "push_operand" "=X")
1552         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1553   "TARGET_64BIT"
1554   "push{q}\t%q1"
1555   [(set_attr "type" "push")
1556    (set_attr "mode" "SI")])
1557
1558 (define_insn "*pushsi2_prologue"
1559   [(set (match_operand:SI 0 "push_operand" "=<")
1560         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1561    (clobber (mem:BLK (scratch)))]
1562   "!TARGET_64BIT"
1563   "push{l}\t%1"
1564   [(set_attr "type" "push")
1565    (set_attr "mode" "SI")])
1566
1567 (define_insn "*popsi1_epilogue"
1568   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1569         (mem:SI (reg:SI SP_REG)))
1570    (set (reg:SI SP_REG)
1571         (plus:SI (reg:SI SP_REG) (const_int 4)))
1572    (clobber (mem:BLK (scratch)))]
1573   "!TARGET_64BIT"
1574   "pop{l}\t%0"
1575   [(set_attr "type" "pop")
1576    (set_attr "mode" "SI")])
1577
1578 (define_insn "popsi1"
1579   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1580         (mem:SI (reg:SI SP_REG)))
1581    (set (reg:SI SP_REG)
1582         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1583   "!TARGET_64BIT"
1584   "pop{l}\t%0"
1585   [(set_attr "type" "pop")
1586    (set_attr "mode" "SI")])
1587
1588 (define_insn "*movsi_xor"
1589   [(set (match_operand:SI 0 "register_operand" "=r")
1590         (match_operand:SI 1 "const0_operand" ""))
1591    (clobber (reg:CC FLAGS_REG))]
1592   "reload_completed"
1593   "xor{l}\t%0, %0"
1594   [(set_attr "type" "alu1")
1595    (set_attr "mode" "SI")
1596    (set_attr "length_immediate" "0")])
1597
1598 (define_insn "*movsi_or"
1599   [(set (match_operand:SI 0 "register_operand" "=r")
1600         (match_operand:SI 1 "immediate_operand" "i"))
1601    (clobber (reg:CC FLAGS_REG))]
1602   "reload_completed
1603    && operands[1] == constm1_rtx"
1604 {
1605   operands[1] = constm1_rtx;
1606   return "or{l}\t{%1, %0|%0, %1}";
1607 }
1608   [(set_attr "type" "alu1")
1609    (set_attr "mode" "SI")
1610    (set_attr "length_immediate" "1")])
1611
1612 (define_insn "*movsi_1"
1613   [(set (match_operand:SI 0 "nonimmediate_operand"
1614                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1615         (match_operand:SI 1 "general_operand"
1616                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1617   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1618 {
1619   switch (get_attr_type (insn))
1620     {
1621     case TYPE_SSELOG1:
1622       if (get_attr_mode (insn) == MODE_TI)
1623         return "%vpxor\t%0, %d0";
1624       return "%vxorps\t%0, %d0";
1625
1626     case TYPE_SSEMOV:
1627       switch (get_attr_mode (insn))
1628         {
1629         case MODE_TI:
1630           return "%vmovdqa\t{%1, %0|%0, %1}";
1631         case MODE_V4SF:
1632           return "%vmovaps\t{%1, %0|%0, %1}";
1633         case MODE_SI:
1634           return "%vmovd\t{%1, %0|%0, %1}";
1635         case MODE_SF:
1636           return "%vmovss\t{%1, %0|%0, %1}";
1637         default:
1638           gcc_unreachable ();
1639         }
1640
1641     case TYPE_MMX:
1642       return "pxor\t%0, %0";
1643
1644     case TYPE_MMXMOV:
1645       if (get_attr_mode (insn) == MODE_DI)
1646         return "movq\t{%1, %0|%0, %1}";
1647       return "movd\t{%1, %0|%0, %1}";
1648
1649     case TYPE_LEA:
1650       return "lea{l}\t{%1, %0|%0, %1}";
1651
1652     default:
1653       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1654       return "mov{l}\t{%1, %0|%0, %1}";
1655     }
1656 }
1657   [(set (attr "type")
1658      (cond [(eq_attr "alternative" "2")
1659               (const_string "mmx")
1660             (eq_attr "alternative" "3,4,5")
1661               (const_string "mmxmov")
1662             (eq_attr "alternative" "6")
1663               (const_string "sselog1")
1664             (eq_attr "alternative" "7,8,9,10,11")
1665               (const_string "ssemov")
1666             (match_operand:DI 1 "pic_32bit_operand" "")
1667               (const_string "lea")
1668            ]
1669            (const_string "imov")))
1670    (set (attr "prefix")
1671      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1672        (const_string "orig")
1673        (const_string "maybe_vex")))
1674    (set (attr "prefix_data16")
1675      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1676        (const_string "1")
1677        (const_string "*")))
1678    (set (attr "mode")
1679      (cond [(eq_attr "alternative" "2,3")
1680               (const_string "DI")
1681             (eq_attr "alternative" "6,7")
1682               (if_then_else
1683                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1684                 (const_string "V4SF")
1685                 (const_string "TI"))
1686             (and (eq_attr "alternative" "8,9,10,11")
1687                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1688               (const_string "SF")
1689            ]
1690            (const_string "SI")))])
1691
1692 ;; Stores and loads of ax to arbitrary constant address.
1693 ;; We fake an second form of instruction to force reload to load address
1694 ;; into register when rax is not available
1695 (define_insn "*movabssi_1_rex64"
1696   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1697         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1698   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1699   "@
1700    movabs{l}\t{%1, %P0|%P0, %1}
1701    mov{l}\t{%1, %a0|%a0, %1}"
1702   [(set_attr "type" "imov")
1703    (set_attr "modrm" "0,*")
1704    (set_attr "length_address" "8,0")
1705    (set_attr "length_immediate" "0,*")
1706    (set_attr "memory" "store")
1707    (set_attr "mode" "SI")])
1708
1709 (define_insn "*movabssi_2_rex64"
1710   [(set (match_operand:SI 0 "register_operand" "=a,r")
1711         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1712   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1713   "@
1714    movabs{l}\t{%P1, %0|%0, %P1}
1715    mov{l}\t{%a1, %0|%0, %a1}"
1716   [(set_attr "type" "imov")
1717    (set_attr "modrm" "0,*")
1718    (set_attr "length_address" "8,0")
1719    (set_attr "length_immediate" "0")
1720    (set_attr "memory" "load")
1721    (set_attr "mode" "SI")])
1722
1723 (define_insn "*swapsi"
1724   [(set (match_operand:SI 0 "register_operand" "+r")
1725         (match_operand:SI 1 "register_operand" "+r"))
1726    (set (match_dup 1)
1727         (match_dup 0))]
1728   ""
1729   "xchg{l}\t%1, %0"
1730   [(set_attr "type" "imov")
1731    (set_attr "mode" "SI")
1732    (set_attr "pent_pair" "np")
1733    (set_attr "athlon_decode" "vector")
1734    (set_attr "amdfam10_decode" "double")])
1735
1736 (define_expand "movhi"
1737   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1738         (match_operand:HI 1 "general_operand" ""))]
1739   ""
1740   "ix86_expand_move (HImode, operands); DONE;")
1741
1742 (define_insn "*pushhi2"
1743   [(set (match_operand:HI 0 "push_operand" "=X")
1744         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1745   "!TARGET_64BIT"
1746   "push{l}\t%k1"
1747   [(set_attr "type" "push")
1748    (set_attr "mode" "SI")])
1749
1750 ;; For 64BIT abi we always round up to 8 bytes.
1751 (define_insn "*pushhi2_rex64"
1752   [(set (match_operand:HI 0 "push_operand" "=X")
1753         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1754   "TARGET_64BIT"
1755   "push{q}\t%q1"
1756   [(set_attr "type" "push")
1757    (set_attr "mode" "DI")])
1758
1759 (define_insn "*movhi_1"
1760   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1761         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1762   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1763 {
1764   switch (get_attr_type (insn))
1765     {
1766     case TYPE_IMOVX:
1767       /* movzwl is faster than movw on p2 due to partial word stalls,
1768          though not as fast as an aligned movl.  */
1769       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1770     default:
1771       if (get_attr_mode (insn) == MODE_SI)
1772         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1773       else
1774         return "mov{w}\t{%1, %0|%0, %1}";
1775     }
1776 }
1777   [(set (attr "type")
1778      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1779               (const_string "imov")
1780             (and (eq_attr "alternative" "0")
1781                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1782                           (const_int 0))
1783                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1784                           (const_int 0))))
1785               (const_string "imov")
1786             (and (eq_attr "alternative" "1,2")
1787                  (match_operand:HI 1 "aligned_operand" ""))
1788               (const_string "imov")
1789             (and (ne (symbol_ref "TARGET_MOVX")
1790                      (const_int 0))
1791                  (eq_attr "alternative" "0,2"))
1792               (const_string "imovx")
1793            ]
1794            (const_string "imov")))
1795     (set (attr "mode")
1796       (cond [(eq_attr "type" "imovx")
1797                (const_string "SI")
1798              (and (eq_attr "alternative" "1,2")
1799                   (match_operand:HI 1 "aligned_operand" ""))
1800                (const_string "SI")
1801              (and (eq_attr "alternative" "0")
1802                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1803                            (const_int 0))
1804                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1805                            (const_int 0))))
1806                (const_string "SI")
1807             ]
1808             (const_string "HI")))])
1809
1810 ;; Stores and loads of ax to arbitrary constant address.
1811 ;; We fake an second form of instruction to force reload to load address
1812 ;; into register when rax is not available
1813 (define_insn "*movabshi_1_rex64"
1814   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1815         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1816   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1817   "@
1818    movabs{w}\t{%1, %P0|%P0, %1}
1819    mov{w}\t{%1, %a0|%a0, %1}"
1820   [(set_attr "type" "imov")
1821    (set_attr "modrm" "0,*")
1822    (set_attr "length_address" "8,0")
1823    (set_attr "length_immediate" "0,*")
1824    (set_attr "memory" "store")
1825    (set_attr "mode" "HI")])
1826
1827 (define_insn "*movabshi_2_rex64"
1828   [(set (match_operand:HI 0 "register_operand" "=a,r")
1829         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1830   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1831   "@
1832    movabs{w}\t{%P1, %0|%0, %P1}
1833    mov{w}\t{%a1, %0|%0, %a1}"
1834   [(set_attr "type" "imov")
1835    (set_attr "modrm" "0,*")
1836    (set_attr "length_address" "8,0")
1837    (set_attr "length_immediate" "0")
1838    (set_attr "memory" "load")
1839    (set_attr "mode" "HI")])
1840
1841 (define_insn "*swaphi_1"
1842   [(set (match_operand:HI 0 "register_operand" "+r")
1843         (match_operand:HI 1 "register_operand" "+r"))
1844    (set (match_dup 1)
1845         (match_dup 0))]
1846   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1847   "xchg{l}\t%k1, %k0"
1848   [(set_attr "type" "imov")
1849    (set_attr "mode" "SI")
1850    (set_attr "pent_pair" "np")
1851    (set_attr "athlon_decode" "vector")
1852    (set_attr "amdfam10_decode" "double")])
1853
1854 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1855 (define_insn "*swaphi_2"
1856   [(set (match_operand:HI 0 "register_operand" "+r")
1857         (match_operand:HI 1 "register_operand" "+r"))
1858    (set (match_dup 1)
1859         (match_dup 0))]
1860   "TARGET_PARTIAL_REG_STALL"
1861   "xchg{w}\t%1, %0"
1862   [(set_attr "type" "imov")
1863    (set_attr "mode" "HI")
1864    (set_attr "pent_pair" "np")
1865    (set_attr "athlon_decode" "vector")])
1866
1867 (define_expand "movstricthi"
1868   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1869         (match_operand:HI 1 "general_operand" ""))]
1870   ""
1871 {
1872   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1873     FAIL;
1874   /* Don't generate memory->memory moves, go through a register */
1875   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1876     operands[1] = force_reg (HImode, operands[1]);
1877 })
1878
1879 (define_insn "*movstricthi_1"
1880   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1881         (match_operand:HI 1 "general_operand" "rn,m"))]
1882   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1883    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884   "mov{w}\t{%1, %0|%0, %1}"
1885   [(set_attr "type" "imov")
1886    (set_attr "mode" "HI")])
1887
1888 (define_insn "*movstricthi_xor"
1889   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1890         (match_operand:HI 1 "const0_operand" ""))
1891    (clobber (reg:CC FLAGS_REG))]
1892   "reload_completed"
1893   "xor{w}\t%0, %0"
1894   [(set_attr "type" "alu1")
1895    (set_attr "mode" "HI")
1896    (set_attr "length_immediate" "0")])
1897
1898 (define_expand "movqi"
1899   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1900         (match_operand:QI 1 "general_operand" ""))]
1901   ""
1902   "ix86_expand_move (QImode, operands); DONE;")
1903
1904 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1905 ;; "push a byte".  But actually we use pushl, which has the effect
1906 ;; of rounding the amount pushed up to a word.
1907
1908 (define_insn "*pushqi2"
1909   [(set (match_operand:QI 0 "push_operand" "=X")
1910         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1911   "!TARGET_64BIT"
1912   "push{l}\t%k1"
1913   [(set_attr "type" "push")
1914    (set_attr "mode" "SI")])
1915
1916 ;; For 64BIT abi we always round up to 8 bytes.
1917 (define_insn "*pushqi2_rex64"
1918   [(set (match_operand:QI 0 "push_operand" "=X")
1919         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1920   "TARGET_64BIT"
1921   "push{q}\t%q1"
1922   [(set_attr "type" "push")
1923    (set_attr "mode" "DI")])
1924
1925 ;; Situation is quite tricky about when to choose full sized (SImode) move
1926 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1927 ;; partial register dependency machines (such as AMD Athlon), where QImode
1928 ;; moves issue extra dependency and for partial register stalls machines
1929 ;; that don't use QImode patterns (and QImode move cause stall on the next
1930 ;; instruction).
1931 ;;
1932 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1933 ;; register stall machines with, where we use QImode instructions, since
1934 ;; partial register stall can be caused there.  Then we use movzx.
1935 (define_insn "*movqi_1"
1936   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1937         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1938   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1939 {
1940   switch (get_attr_type (insn))
1941     {
1942     case TYPE_IMOVX:
1943       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1944       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1945     default:
1946       if (get_attr_mode (insn) == MODE_SI)
1947         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1948       else
1949         return "mov{b}\t{%1, %0|%0, %1}";
1950     }
1951 }
1952   [(set (attr "type")
1953      (cond [(and (eq_attr "alternative" "5")
1954                  (not (match_operand:QI 1 "aligned_operand" "")))
1955               (const_string "imovx")
1956             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1957               (const_string "imov")
1958             (and (eq_attr "alternative" "3")
1959                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1960                           (const_int 0))
1961                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1962                           (const_int 0))))
1963               (const_string "imov")
1964             (eq_attr "alternative" "3,5")
1965               (const_string "imovx")
1966             (and (ne (symbol_ref "TARGET_MOVX")
1967                      (const_int 0))
1968                  (eq_attr "alternative" "2"))
1969               (const_string "imovx")
1970            ]
1971            (const_string "imov")))
1972    (set (attr "mode")
1973       (cond [(eq_attr "alternative" "3,4,5")
1974                (const_string "SI")
1975              (eq_attr "alternative" "6")
1976                (const_string "QI")
1977              (eq_attr "type" "imovx")
1978                (const_string "SI")
1979              (and (eq_attr "type" "imov")
1980                   (and (eq_attr "alternative" "0,1")
1981                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1982                                 (const_int 0))
1983                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1984                                      (const_int 0))
1985                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1986                                      (const_int 0))))))
1987                (const_string "SI")
1988              ;; Avoid partial register stalls when not using QImode arithmetic
1989              (and (eq_attr "type" "imov")
1990                   (and (eq_attr "alternative" "0,1")
1991                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1992                                 (const_int 0))
1993                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1994                                 (const_int 0)))))
1995                (const_string "SI")
1996            ]
1997            (const_string "QI")))])
1998
1999 (define_insn "*swapqi_1"
2000   [(set (match_operand:QI 0 "register_operand" "+r")
2001         (match_operand:QI 1 "register_operand" "+r"))
2002    (set (match_dup 1)
2003         (match_dup 0))]
2004   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2005   "xchg{l}\t%k1, %k0"
2006   [(set_attr "type" "imov")
2007    (set_attr "mode" "SI")
2008    (set_attr "pent_pair" "np")
2009    (set_attr "athlon_decode" "vector")
2010    (set_attr "amdfam10_decode" "vector")])
2011
2012 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2013 (define_insn "*swapqi_2"
2014   [(set (match_operand:QI 0 "register_operand" "+q")
2015         (match_operand:QI 1 "register_operand" "+q"))
2016    (set (match_dup 1)
2017         (match_dup 0))]
2018   "TARGET_PARTIAL_REG_STALL"
2019   "xchg{b}\t%1, %0"
2020   [(set_attr "type" "imov")
2021    (set_attr "mode" "QI")
2022    (set_attr "pent_pair" "np")
2023    (set_attr "athlon_decode" "vector")])
2024
2025 (define_expand "movstrictqi"
2026   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2027         (match_operand:QI 1 "general_operand" ""))]
2028   ""
2029 {
2030   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2031     FAIL;
2032   /* Don't generate memory->memory moves, go through a register.  */
2033   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2034     operands[1] = force_reg (QImode, operands[1]);
2035 })
2036
2037 (define_insn "*movstrictqi_1"
2038   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2039         (match_operand:QI 1 "general_operand" "*qn,m"))]
2040   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2041    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2042   "mov{b}\t{%1, %0|%0, %1}"
2043   [(set_attr "type" "imov")
2044    (set_attr "mode" "QI")])
2045
2046 (define_insn "*movstrictqi_xor"
2047   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2048         (match_operand:QI 1 "const0_operand" ""))
2049    (clobber (reg:CC FLAGS_REG))]
2050   "reload_completed"
2051   "xor{b}\t%0, %0"
2052   [(set_attr "type" "alu1")
2053    (set_attr "mode" "QI")
2054    (set_attr "length_immediate" "0")])
2055
2056 (define_insn "*movsi_extv_1"
2057   [(set (match_operand:SI 0 "register_operand" "=R")
2058         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2059                          (const_int 8)
2060                          (const_int 8)))]
2061   ""
2062   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2063   [(set_attr "type" "imovx")
2064    (set_attr "mode" "SI")])
2065
2066 (define_insn "*movhi_extv_1"
2067   [(set (match_operand:HI 0 "register_operand" "=R")
2068         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2069                          (const_int 8)
2070                          (const_int 8)))]
2071   ""
2072   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2073   [(set_attr "type" "imovx")
2074    (set_attr "mode" "SI")])
2075
2076 (define_insn "*movqi_extv_1"
2077   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2078         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2079                          (const_int 8)
2080                          (const_int 8)))]
2081   "!TARGET_64BIT"
2082 {
2083   switch (get_attr_type (insn))
2084     {
2085     case TYPE_IMOVX:
2086       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2087     default:
2088       return "mov{b}\t{%h1, %0|%0, %h1}";
2089     }
2090 }
2091   [(set (attr "type")
2092      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2093                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2094                              (ne (symbol_ref "TARGET_MOVX")
2095                                  (const_int 0))))
2096         (const_string "imovx")
2097         (const_string "imov")))
2098    (set (attr "mode")
2099      (if_then_else (eq_attr "type" "imovx")
2100         (const_string "SI")
2101         (const_string "QI")))])
2102
2103 (define_insn "*movqi_extv_1_rex64"
2104   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2105         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2106                          (const_int 8)
2107                          (const_int 8)))]
2108   "TARGET_64BIT"
2109 {
2110   switch (get_attr_type (insn))
2111     {
2112     case TYPE_IMOVX:
2113       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2114     default:
2115       return "mov{b}\t{%h1, %0|%0, %h1}";
2116     }
2117 }
2118   [(set (attr "type")
2119      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2120                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2121                              (ne (symbol_ref "TARGET_MOVX")
2122                                  (const_int 0))))
2123         (const_string "imovx")
2124         (const_string "imov")))
2125    (set (attr "mode")
2126      (if_then_else (eq_attr "type" "imovx")
2127         (const_string "SI")
2128         (const_string "QI")))])
2129
2130 ;; Stores and loads of ax to arbitrary constant address.
2131 ;; We fake an second form of instruction to force reload to load address
2132 ;; into register when rax is not available
2133 (define_insn "*movabsqi_1_rex64"
2134   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2135         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2136   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2137   "@
2138    movabs{b}\t{%1, %P0|%P0, %1}
2139    mov{b}\t{%1, %a0|%a0, %1}"
2140   [(set_attr "type" "imov")
2141    (set_attr "modrm" "0,*")
2142    (set_attr "length_address" "8,0")
2143    (set_attr "length_immediate" "0,*")
2144    (set_attr "memory" "store")
2145    (set_attr "mode" "QI")])
2146
2147 (define_insn "*movabsqi_2_rex64"
2148   [(set (match_operand:QI 0 "register_operand" "=a,r")
2149         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2150   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2151   "@
2152    movabs{b}\t{%P1, %0|%0, %P1}
2153    mov{b}\t{%a1, %0|%0, %a1}"
2154   [(set_attr "type" "imov")
2155    (set_attr "modrm" "0,*")
2156    (set_attr "length_address" "8,0")
2157    (set_attr "length_immediate" "0")
2158    (set_attr "memory" "load")
2159    (set_attr "mode" "QI")])
2160
2161 (define_insn "*movdi_extzv_1"
2162   [(set (match_operand:DI 0 "register_operand" "=R")
2163         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2164                          (const_int 8)
2165                          (const_int 8)))]
2166   "TARGET_64BIT"
2167   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2168   [(set_attr "type" "imovx")
2169    (set_attr "mode" "SI")])
2170
2171 (define_insn "*movsi_extzv_1"
2172   [(set (match_operand:SI 0 "register_operand" "=R")
2173         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2174                          (const_int 8)
2175                          (const_int 8)))]
2176   ""
2177   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2178   [(set_attr "type" "imovx")
2179    (set_attr "mode" "SI")])
2180
2181 (define_insn "*movqi_extzv_2"
2182   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2183         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2184                                     (const_int 8)
2185                                     (const_int 8)) 0))]
2186   "!TARGET_64BIT"
2187 {
2188   switch (get_attr_type (insn))
2189     {
2190     case TYPE_IMOVX:
2191       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2192     default:
2193       return "mov{b}\t{%h1, %0|%0, %h1}";
2194     }
2195 }
2196   [(set (attr "type")
2197      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2198                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2199                              (ne (symbol_ref "TARGET_MOVX")
2200                                  (const_int 0))))
2201         (const_string "imovx")
2202         (const_string "imov")))
2203    (set (attr "mode")
2204      (if_then_else (eq_attr "type" "imovx")
2205         (const_string "SI")
2206         (const_string "QI")))])
2207
2208 (define_insn "*movqi_extzv_2_rex64"
2209   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2210         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2211                                     (const_int 8)
2212                                     (const_int 8)) 0))]
2213   "TARGET_64BIT"
2214 {
2215   switch (get_attr_type (insn))
2216     {
2217     case TYPE_IMOVX:
2218       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2219     default:
2220       return "mov{b}\t{%h1, %0|%0, %h1}";
2221     }
2222 }
2223   [(set (attr "type")
2224      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2225                         (ne (symbol_ref "TARGET_MOVX")
2226                             (const_int 0)))
2227         (const_string "imovx")
2228         (const_string "imov")))
2229    (set (attr "mode")
2230      (if_then_else (eq_attr "type" "imovx")
2231         (const_string "SI")
2232         (const_string "QI")))])
2233
2234 (define_insn "movsi_insv_1"
2235   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2236                          (const_int 8)
2237                          (const_int 8))
2238         (match_operand:SI 1 "general_operand" "Qmn"))]
2239   "!TARGET_64BIT"
2240   "mov{b}\t{%b1, %h0|%h0, %b1}"
2241   [(set_attr "type" "imov")
2242    (set_attr "mode" "QI")])
2243
2244 (define_insn "*movsi_insv_1_rex64"
2245   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2246                          (const_int 8)
2247                          (const_int 8))
2248         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2249   "TARGET_64BIT"
2250   "mov{b}\t{%b1, %h0|%h0, %b1}"
2251   [(set_attr "type" "imov")
2252    (set_attr "mode" "QI")])
2253
2254 (define_insn "movdi_insv_1_rex64"
2255   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2256                          (const_int 8)
2257                          (const_int 8))
2258         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2259   "TARGET_64BIT"
2260   "mov{b}\t{%b1, %h0|%h0, %b1}"
2261   [(set_attr "type" "imov")
2262    (set_attr "mode" "QI")])
2263
2264 (define_insn "*movqi_insv_2"
2265   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2266                          (const_int 8)
2267                          (const_int 8))
2268         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2269                      (const_int 8)))]
2270   ""
2271   "mov{b}\t{%h1, %h0|%h0, %h1}"
2272   [(set_attr "type" "imov")
2273    (set_attr "mode" "QI")])
2274
2275 (define_expand "movdi"
2276   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2277         (match_operand:DI 1 "general_operand" ""))]
2278   ""
2279   "ix86_expand_move (DImode, operands); DONE;")
2280
2281 (define_insn "*pushdi"
2282   [(set (match_operand:DI 0 "push_operand" "=<")
2283         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2284   "!TARGET_64BIT"
2285   "#")
2286
2287 (define_insn "*pushdi2_rex64"
2288   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2289         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2290   "TARGET_64BIT"
2291   "@
2292    push{q}\t%1
2293    #"
2294   [(set_attr "type" "push,multi")
2295    (set_attr "mode" "DI")])
2296
2297 ;; Convert impossible pushes of immediate to existing instructions.
2298 ;; First try to get scratch register and go through it.  In case this
2299 ;; fails, push sign extended lower part first and then overwrite
2300 ;; upper part by 32bit move.
2301 (define_peephole2
2302   [(match_scratch:DI 2 "r")
2303    (set (match_operand:DI 0 "push_operand" "")
2304         (match_operand:DI 1 "immediate_operand" ""))]
2305   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2306    && !x86_64_immediate_operand (operands[1], DImode)"
2307   [(set (match_dup 2) (match_dup 1))
2308    (set (match_dup 0) (match_dup 2))]
2309   "")
2310
2311 ;; We need to define this as both peepholer and splitter for case
2312 ;; peephole2 pass is not run.
2313 ;; "&& 1" is needed to keep it from matching the previous pattern.
2314 (define_peephole2
2315   [(set (match_operand:DI 0 "push_operand" "")
2316         (match_operand:DI 1 "immediate_operand" ""))]
2317   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2318    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2319   [(set (match_dup 0) (match_dup 1))
2320    (set (match_dup 2) (match_dup 3))]
2321   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2322    operands[1] = gen_lowpart (DImode, operands[2]);
2323    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2324                                                     GEN_INT (4)));
2325   ")
2326
2327 (define_split
2328   [(set (match_operand:DI 0 "push_operand" "")
2329         (match_operand:DI 1 "immediate_operand" ""))]
2330   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2331                     ? epilogue_completed : reload_completed)
2332    && !symbolic_operand (operands[1], DImode)
2333    && !x86_64_immediate_operand (operands[1], DImode)"
2334   [(set (match_dup 0) (match_dup 1))
2335    (set (match_dup 2) (match_dup 3))]
2336   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2337    operands[1] = gen_lowpart (DImode, operands[2]);
2338    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2339                                                     GEN_INT (4)));
2340   ")
2341
2342 (define_insn "*pushdi2_prologue_rex64"
2343   [(set (match_operand:DI 0 "push_operand" "=<")
2344         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2345    (clobber (mem:BLK (scratch)))]
2346   "TARGET_64BIT"
2347   "push{q}\t%1"
2348   [(set_attr "type" "push")
2349    (set_attr "mode" "DI")])
2350
2351 (define_insn "*popdi1_epilogue_rex64"
2352   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2353         (mem:DI (reg:DI SP_REG)))
2354    (set (reg:DI SP_REG)
2355         (plus:DI (reg:DI SP_REG) (const_int 8)))
2356    (clobber (mem:BLK (scratch)))]
2357   "TARGET_64BIT"
2358   "pop{q}\t%0"
2359   [(set_attr "type" "pop")
2360    (set_attr "mode" "DI")])
2361
2362 (define_insn "popdi1"
2363   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2364         (mem:DI (reg:DI SP_REG)))
2365    (set (reg:DI SP_REG)
2366         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2367   "TARGET_64BIT"
2368   "pop{q}\t%0"
2369   [(set_attr "type" "pop")
2370    (set_attr "mode" "DI")])
2371
2372 (define_insn "*movdi_xor_rex64"
2373   [(set (match_operand:DI 0 "register_operand" "=r")
2374         (match_operand:DI 1 "const0_operand" ""))
2375    (clobber (reg:CC FLAGS_REG))]
2376   "TARGET_64BIT
2377    && reload_completed"
2378   "xor{l}\t%k0, %k0";
2379   [(set_attr "type" "alu1")
2380    (set_attr "mode" "SI")
2381    (set_attr "length_immediate" "0")])
2382
2383 (define_insn "*movdi_or_rex64"
2384   [(set (match_operand:DI 0 "register_operand" "=r")
2385         (match_operand:DI 1 "const_int_operand" "i"))
2386    (clobber (reg:CC FLAGS_REG))]
2387   "TARGET_64BIT
2388    && reload_completed
2389    && operands[1] == constm1_rtx"
2390 {
2391   operands[1] = constm1_rtx;
2392   return "or{q}\t{%1, %0|%0, %1}";
2393 }
2394   [(set_attr "type" "alu1")
2395    (set_attr "mode" "DI")
2396    (set_attr "length_immediate" "1")])
2397
2398 (define_insn "*movdi_2"
2399   [(set (match_operand:DI 0 "nonimmediate_operand"
2400                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2401         (match_operand:DI 1 "general_operand"
2402                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2403   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2404   "@
2405    #
2406    #
2407    pxor\t%0, %0
2408    movq\t{%1, %0|%0, %1}
2409    movq\t{%1, %0|%0, %1}
2410    %vpxor\t%0, %d0
2411    %vmovq\t{%1, %0|%0, %1}
2412    %vmovdqa\t{%1, %0|%0, %1}
2413    %vmovq\t{%1, %0|%0, %1}
2414    xorps\t%0, %0
2415    movlps\t{%1, %0|%0, %1}
2416    movaps\t{%1, %0|%0, %1}
2417    movlps\t{%1, %0|%0, %1}"
2418   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2419    (set (attr "prefix")
2420      (if_then_else (eq_attr "alternative" "5,6,7,8")
2421        (const_string "vex")
2422        (const_string "orig")))
2423    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2424
2425 (define_split
2426   [(set (match_operand:DI 0 "push_operand" "")
2427         (match_operand:DI 1 "general_operand" ""))]
2428   "!TARGET_64BIT && reload_completed
2429    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2430   [(const_int 0)]
2431   "ix86_split_long_move (operands); DONE;")
2432
2433 ;; %%% This multiword shite has got to go.
2434 (define_split
2435   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2436         (match_operand:DI 1 "general_operand" ""))]
2437   "!TARGET_64BIT && reload_completed
2438    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2439    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2440   [(const_int 0)]
2441   "ix86_split_long_move (operands); DONE;")
2442
2443 (define_insn "*movdi_1_rex64"
2444   [(set (match_operand:DI 0 "nonimmediate_operand"
2445           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2446         (match_operand:DI 1 "general_operand"
2447           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2448   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2449 {
2450   switch (get_attr_type (insn))
2451     {
2452     case TYPE_SSECVT:
2453       if (SSE_REG_P (operands[0]))
2454         return "movq2dq\t{%1, %0|%0, %1}";
2455       else
2456         return "movdq2q\t{%1, %0|%0, %1}";
2457
2458     case TYPE_SSEMOV:
2459       if (TARGET_AVX)
2460         {
2461           if (get_attr_mode (insn) == MODE_TI)
2462             return "vmovdqa\t{%1, %0|%0, %1}";
2463           else
2464             return "vmovq\t{%1, %0|%0, %1}";
2465         }
2466
2467       if (get_attr_mode (insn) == MODE_TI)
2468         return "movdqa\t{%1, %0|%0, %1}";
2469       /* FALLTHRU */
2470
2471     case TYPE_MMXMOV:
2472       /* Moves from and into integer register is done using movd
2473          opcode with REX prefix.  */
2474       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2475         return "movd\t{%1, %0|%0, %1}";
2476       return "movq\t{%1, %0|%0, %1}";
2477
2478     case TYPE_SSELOG1:
2479       return "%vpxor\t%0, %d0";
2480
2481     case TYPE_MMX:
2482       return "pxor\t%0, %0";
2483
2484     case TYPE_MULTI:
2485       return "#";
2486
2487     case TYPE_LEA:
2488       return "lea{q}\t{%a1, %0|%0, %a1}";
2489
2490     default:
2491       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2492       if (get_attr_mode (insn) == MODE_SI)
2493         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2494       else if (which_alternative == 2)
2495         return "movabs{q}\t{%1, %0|%0, %1}";
2496       else
2497         return "mov{q}\t{%1, %0|%0, %1}";
2498     }
2499 }
2500   [(set (attr "type")
2501      (cond [(eq_attr "alternative" "5")
2502               (const_string "mmx")
2503             (eq_attr "alternative" "6,7,8,9,10")
2504               (const_string "mmxmov")
2505             (eq_attr "alternative" "11")
2506               (const_string "sselog1")
2507             (eq_attr "alternative" "12,13,14,15,16")
2508               (const_string "ssemov")
2509             (eq_attr "alternative" "17,18")
2510               (const_string "ssecvt")
2511             (eq_attr "alternative" "4")
2512               (const_string "multi")
2513             (match_operand:DI 1 "pic_32bit_operand" "")
2514               (const_string "lea")
2515            ]
2516            (const_string "imov")))
2517    (set (attr "modrm")
2518      (if_then_else
2519        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2520          (const_string "0")
2521          (const_string "*")))
2522    (set (attr "length_immediate")
2523      (if_then_else
2524        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2525          (const_string "8")
2526          (const_string "*")))
2527    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2528    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2529    (set (attr "prefix")
2530      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2531        (const_string "maybe_vex")
2532        (const_string "orig")))
2533    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2534
2535 ;; Stores and loads of ax to arbitrary constant address.
2536 ;; We fake an second form of instruction to force reload to load address
2537 ;; into register when rax is not available
2538 (define_insn "*movabsdi_1_rex64"
2539   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2540         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2541   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2542   "@
2543    movabs{q}\t{%1, %P0|%P0, %1}
2544    mov{q}\t{%1, %a0|%a0, %1}"
2545   [(set_attr "type" "imov")
2546    (set_attr "modrm" "0,*")
2547    (set_attr "length_address" "8,0")
2548    (set_attr "length_immediate" "0,*")
2549    (set_attr "memory" "store")
2550    (set_attr "mode" "DI")])
2551
2552 (define_insn "*movabsdi_2_rex64"
2553   [(set (match_operand:DI 0 "register_operand" "=a,r")
2554         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2555   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2556   "@
2557    movabs{q}\t{%P1, %0|%0, %P1}
2558    mov{q}\t{%a1, %0|%0, %a1}"
2559   [(set_attr "type" "imov")
2560    (set_attr "modrm" "0,*")
2561    (set_attr "length_address" "8,0")
2562    (set_attr "length_immediate" "0")
2563    (set_attr "memory" "load")
2564    (set_attr "mode" "DI")])
2565
2566 ;; Convert impossible stores of immediate to existing instructions.
2567 ;; First try to get scratch register and go through it.  In case this
2568 ;; fails, move by 32bit parts.
2569 (define_peephole2
2570   [(match_scratch:DI 2 "r")
2571    (set (match_operand:DI 0 "memory_operand" "")
2572         (match_operand:DI 1 "immediate_operand" ""))]
2573   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2574    && !x86_64_immediate_operand (operands[1], DImode)"
2575   [(set (match_dup 2) (match_dup 1))
2576    (set (match_dup 0) (match_dup 2))]
2577   "")
2578
2579 ;; We need to define this as both peepholer and splitter for case
2580 ;; peephole2 pass is not run.
2581 ;; "&& 1" is needed to keep it from matching the previous pattern.
2582 (define_peephole2
2583   [(set (match_operand:DI 0 "memory_operand" "")
2584         (match_operand:DI 1 "immediate_operand" ""))]
2585   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2586    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2587   [(set (match_dup 2) (match_dup 3))
2588    (set (match_dup 4) (match_dup 5))]
2589   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2590
2591 (define_split
2592   [(set (match_operand:DI 0 "memory_operand" "")
2593         (match_operand:DI 1 "immediate_operand" ""))]
2594   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2595                     ? epilogue_completed : reload_completed)
2596    && !symbolic_operand (operands[1], DImode)
2597    && !x86_64_immediate_operand (operands[1], DImode)"
2598   [(set (match_dup 2) (match_dup 3))
2599    (set (match_dup 4) (match_dup 5))]
2600   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2601
2602 (define_insn "*swapdi_rex64"
2603   [(set (match_operand:DI 0 "register_operand" "+r")
2604         (match_operand:DI 1 "register_operand" "+r"))
2605    (set (match_dup 1)
2606         (match_dup 0))]
2607   "TARGET_64BIT"
2608   "xchg{q}\t%1, %0"
2609   [(set_attr "type" "imov")
2610    (set_attr "mode" "DI")
2611    (set_attr "pent_pair" "np")
2612    (set_attr "athlon_decode" "vector")
2613    (set_attr "amdfam10_decode" "double")])
2614
2615 (define_expand "movoi"
2616   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2617         (match_operand:OI 1 "general_operand" ""))]
2618   "TARGET_AVX"
2619   "ix86_expand_move (OImode, operands); DONE;")
2620
2621 (define_insn "*movoi_internal"
2622   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2623         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2624   "TARGET_AVX
2625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2626 {
2627   switch (which_alternative)
2628     {
2629     case 0:
2630       return "vxorps\t%0, %0, %0";
2631     case 1:
2632     case 2:
2633       if (misaligned_operand (operands[0], OImode)
2634           || misaligned_operand (operands[1], OImode))
2635         return "vmovdqu\t{%1, %0|%0, %1}";
2636       else
2637         return "vmovdqa\t{%1, %0|%0, %1}";
2638     default:
2639       gcc_unreachable ();
2640     }
2641 }
2642   [(set_attr "type" "sselog1,ssemov,ssemov")
2643    (set_attr "prefix" "vex")
2644    (set_attr "mode" "OI")])
2645
2646 (define_expand "movti"
2647   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2648         (match_operand:TI 1 "nonimmediate_operand" ""))]
2649   "TARGET_SSE || TARGET_64BIT"
2650 {
2651   if (TARGET_64BIT)
2652     ix86_expand_move (TImode, operands);
2653   else if (push_operand (operands[0], TImode))
2654     ix86_expand_push (TImode, operands[1]);
2655   else
2656     ix86_expand_vector_move (TImode, operands);
2657   DONE;
2658 })
2659
2660 (define_insn "*movti_internal"
2661   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2662         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2663   "TARGET_SSE && !TARGET_64BIT
2664    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2665 {
2666   switch (which_alternative)
2667     {
2668     case 0:
2669       if (get_attr_mode (insn) == MODE_V4SF)
2670         return "%vxorps\t%0, %d0";
2671       else
2672         return "%vpxor\t%0, %d0";
2673     case 1:
2674     case 2:
2675       /* TDmode values are passed as TImode on the stack.  Moving them
2676          to stack may result in unaligned memory access.  */
2677       if (misaligned_operand (operands[0], TImode)
2678           || misaligned_operand (operands[1], TImode))
2679         {
2680           if (get_attr_mode (insn) == MODE_V4SF)
2681             return "%vmovups\t{%1, %0|%0, %1}";
2682          else
2683            return "%vmovdqu\t{%1, %0|%0, %1}";
2684         }
2685       else
2686         {
2687           if (get_attr_mode (insn) == MODE_V4SF)
2688             return "%vmovaps\t{%1, %0|%0, %1}";
2689          else
2690            return "%vmovdqa\t{%1, %0|%0, %1}";
2691         }
2692     default:
2693       gcc_unreachable ();
2694     }
2695 }
2696   [(set_attr "type" "sselog1,ssemov,ssemov")
2697    (set_attr "prefix" "maybe_vex")
2698    (set (attr "mode")
2699         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2701                  (const_string "V4SF")
2702                (and (eq_attr "alternative" "2")
2703                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2704                         (const_int 0)))
2705                  (const_string "V4SF")]
2706               (const_string "TI")))])
2707
2708 (define_insn "*movti_rex64"
2709   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2710         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2711   "TARGET_64BIT
2712    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2713 {
2714   switch (which_alternative)
2715     {
2716     case 0:
2717     case 1:
2718       return "#";
2719     case 2:
2720       if (get_attr_mode (insn) == MODE_V4SF)
2721         return "%vxorps\t%0, %d0";
2722       else
2723         return "%vpxor\t%0, %d0";
2724     case 3:
2725     case 4:
2726       /* TDmode values are passed as TImode on the stack.  Moving them
2727          to stack may result in unaligned memory access.  */
2728       if (misaligned_operand (operands[0], TImode)
2729           || misaligned_operand (operands[1], TImode))
2730         {
2731           if (get_attr_mode (insn) == MODE_V4SF)
2732             return "%vmovups\t{%1, %0|%0, %1}";
2733          else
2734            return "%vmovdqu\t{%1, %0|%0, %1}";
2735         }
2736       else
2737         {
2738           if (get_attr_mode (insn) == MODE_V4SF)
2739             return "%vmovaps\t{%1, %0|%0, %1}";
2740          else
2741            return "%vmovdqa\t{%1, %0|%0, %1}";
2742         }
2743     default:
2744       gcc_unreachable ();
2745     }
2746 }
2747   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2748    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2749    (set (attr "mode")
2750         (cond [(eq_attr "alternative" "2,3")
2751                  (if_then_else
2752                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2753                        (const_int 0))
2754                    (const_string "V4SF")
2755                    (const_string "TI"))
2756                (eq_attr "alternative" "4")
2757                  (if_then_else
2758                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2759                             (const_int 0))
2760                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2761                             (const_int 0)))
2762                    (const_string "V4SF")
2763                    (const_string "TI"))]
2764                (const_string "DI")))])
2765
2766 (define_split
2767   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2768         (match_operand:TI 1 "general_operand" ""))]
2769   "reload_completed && !SSE_REG_P (operands[0])
2770    && !SSE_REG_P (operands[1])"
2771   [(const_int 0)]
2772   "ix86_split_long_move (operands); DONE;")
2773
2774 ;; This expands to what emit_move_complex would generate if we didn't
2775 ;; have a movti pattern.  Having this avoids problems with reload on
2776 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2777 ;; to have around all the time.
2778 (define_expand "movcdi"
2779   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2780         (match_operand:CDI 1 "general_operand" ""))]
2781   ""
2782 {
2783   if (push_operand (operands[0], CDImode))
2784     emit_move_complex_push (CDImode, operands[0], operands[1]);
2785   else
2786     emit_move_complex_parts (operands[0], operands[1]);
2787   DONE;
2788 })
2789
2790 (define_expand "movsf"
2791   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2792         (match_operand:SF 1 "general_operand" ""))]
2793   ""
2794   "ix86_expand_move (SFmode, operands); DONE;")
2795
2796 (define_insn "*pushsf"
2797   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2798         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2799   "!TARGET_64BIT"
2800 {
2801   /* Anything else should be already split before reg-stack.  */
2802   gcc_assert (which_alternative == 1);
2803   return "push{l}\t%1";
2804 }
2805   [(set_attr "type" "multi,push,multi")
2806    (set_attr "unit" "i387,*,*")
2807    (set_attr "mode" "SF,SI,SF")])
2808
2809 (define_insn "*pushsf_rex64"
2810   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2811         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2812   "TARGET_64BIT"
2813 {
2814   /* Anything else should be already split before reg-stack.  */
2815   gcc_assert (which_alternative == 1);
2816   return "push{q}\t%q1";
2817 }
2818   [(set_attr "type" "multi,push,multi")
2819    (set_attr "unit" "i387,*,*")
2820    (set_attr "mode" "SF,DI,SF")])
2821
2822 (define_split
2823   [(set (match_operand:SF 0 "push_operand" "")
2824         (match_operand:SF 1 "memory_operand" ""))]
2825   "reload_completed
2826    && MEM_P (operands[1])
2827    && (operands[2] = find_constant_src (insn))"
2828   [(set (match_dup 0)
2829         (match_dup 2))])
2830
2831 ;; %%% Kill this when call knows how to work this out.
2832 (define_split
2833   [(set (match_operand:SF 0 "push_operand" "")
2834         (match_operand:SF 1 "any_fp_register_operand" ""))]
2835   "!TARGET_64BIT"
2836   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2837    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2838
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2844    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2845
2846 (define_insn "*movsf_1"
2847   [(set (match_operand:SF 0 "nonimmediate_operand"
2848           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2849         (match_operand:SF 1 "general_operand"
2850           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2851   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2852    && (reload_in_progress || reload_completed
2853        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2854        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2855            && standard_80387_constant_p (operands[1]))
2856        || GET_CODE (operands[1]) != CONST_DOUBLE
2857        || memory_operand (operands[0], SFmode))"
2858 {
2859   switch (which_alternative)
2860     {
2861     case 0:
2862     case 1:
2863       return output_387_reg_move (insn, operands);
2864
2865     case 2:
2866       return standard_80387_constant_opcode (operands[1]);
2867
2868     case 3:
2869     case 4:
2870       return "mov{l}\t{%1, %0|%0, %1}";
2871     case 5:
2872       if (get_attr_mode (insn) == MODE_TI)
2873         return "%vpxor\t%0, %d0";
2874       else
2875         return "%vxorps\t%0, %d0";
2876     case 6:
2877       if (get_attr_mode (insn) == MODE_V4SF)
2878         return "%vmovaps\t{%1, %0|%0, %1}";
2879       else
2880         return "%vmovss\t{%1, %d0|%d0, %1}";
2881     case 7:
2882       if (TARGET_AVX)
2883         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2884                                    : "vmovss\t{%1, %0|%0, %1}";
2885       else
2886         return "movss\t{%1, %0|%0, %1}";
2887     case 8:
2888       return "%vmovss\t{%1, %0|%0, %1}";
2889
2890     case 9: case 10: case 14: case 15:
2891       return "movd\t{%1, %0|%0, %1}";
2892     case 12: case 13:
2893       return "%vmovd\t{%1, %0|%0, %1}";
2894
2895     case 11:
2896       return "movq\t{%1, %0|%0, %1}";
2897
2898     default:
2899       gcc_unreachable ();
2900     }
2901 }
2902   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2903    (set (attr "prefix")
2904      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2905        (const_string "maybe_vex")
2906        (const_string "orig")))
2907    (set (attr "mode")
2908         (cond [(eq_attr "alternative" "3,4,9,10")
2909                  (const_string "SI")
2910                (eq_attr "alternative" "5")
2911                  (if_then_else
2912                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2913                                  (const_int 0))
2914                              (ne (symbol_ref "TARGET_SSE2")
2915                                  (const_int 0)))
2916                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2917                             (const_int 0)))
2918                    (const_string "TI")
2919                    (const_string "V4SF"))
2920                /* For architectures resolving dependencies on
2921                   whole SSE registers use APS move to break dependency
2922                   chains, otherwise use short move to avoid extra work.
2923
2924                   Do the same for architectures resolving dependencies on
2925                   the parts.  While in DF mode it is better to always handle
2926                   just register parts, the SF mode is different due to lack
2927                   of instructions to load just part of the register.  It is
2928                   better to maintain the whole registers in single format
2929                   to avoid problems on using packed logical operations.  */
2930                (eq_attr "alternative" "6")
2931                  (if_then_else
2932                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2933                             (const_int 0))
2934                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2935                             (const_int 0)))
2936                    (const_string "V4SF")
2937                    (const_string "SF"))
2938                (eq_attr "alternative" "11")
2939                  (const_string "DI")]
2940                (const_string "SF")))])
2941
2942 (define_insn "*swapsf"
2943   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2944         (match_operand:SF 1 "fp_register_operand" "+f"))
2945    (set (match_dup 1)
2946         (match_dup 0))]
2947   "reload_completed || TARGET_80387"
2948 {
2949   if (STACK_TOP_P (operands[0]))
2950     return "fxch\t%1";
2951   else
2952     return "fxch\t%0";
2953 }
2954   [(set_attr "type" "fxch")
2955    (set_attr "mode" "SF")])
2956
2957 (define_expand "movdf"
2958   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2959         (match_operand:DF 1 "general_operand" ""))]
2960   ""
2961   "ix86_expand_move (DFmode, operands); DONE;")
2962
2963 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2964 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2965 ;; On the average, pushdf using integers can be still shorter.  Allow this
2966 ;; pattern for optimize_size too.
2967
2968 (define_insn "*pushdf_nointeger"
2969   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2970         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2971   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2972 {
2973   /* This insn should be already split before reg-stack.  */
2974   gcc_unreachable ();
2975 }
2976   [(set_attr "type" "multi")
2977    (set_attr "unit" "i387,*,*,*")
2978    (set_attr "mode" "DF,SI,SI,DF")])
2979
2980 (define_insn "*pushdf_integer"
2981   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2982         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2983   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2984 {
2985   /* This insn should be already split before reg-stack.  */
2986   gcc_unreachable ();
2987 }
2988   [(set_attr "type" "multi")
2989    (set_attr "unit" "i387,*,*")
2990    (set_attr "mode" "DF,SI,DF")])
2991
2992 ;; %%% Kill this when call knows how to work this out.
2993 (define_split
2994   [(set (match_operand:DF 0 "push_operand" "")
2995         (match_operand:DF 1 "any_fp_register_operand" ""))]
2996   "reload_completed"
2997   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2998    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2999   "")
3000
3001 (define_split
3002   [(set (match_operand:DF 0 "push_operand" "")
3003         (match_operand:DF 1 "general_operand" ""))]
3004   "reload_completed"
3005   [(const_int 0)]
3006   "ix86_split_long_move (operands); DONE;")
3007
3008 ;; Moving is usually shorter when only FP registers are used. This separate
3009 ;; movdf pattern avoids the use of integer registers for FP operations
3010 ;; when optimizing for size.
3011
3012 (define_insn "*movdf_nointeger"
3013   [(set (match_operand:DF 0 "nonimmediate_operand"
3014                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3015         (match_operand:DF 1 "general_operand"
3016                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3017   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3018    && ((optimize_function_for_size_p (cfun)
3019        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3020    && (reload_in_progress || reload_completed
3021        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3022        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3023            && optimize_function_for_size_p (cfun)
3024            && !memory_operand (operands[0], DFmode)
3025            && standard_80387_constant_p (operands[1]))
3026        || GET_CODE (operands[1]) != CONST_DOUBLE
3027        || ((optimize_function_for_size_p (cfun)
3028             || !TARGET_MEMORY_MISMATCH_STALL
3029             || reload_in_progress || reload_completed)
3030            && memory_operand (operands[0], DFmode)))"
3031 {
3032   switch (which_alternative)
3033     {
3034     case 0:
3035     case 1:
3036       return output_387_reg_move (insn, operands);
3037
3038     case 2:
3039       return standard_80387_constant_opcode (operands[1]);
3040
3041     case 3:
3042     case 4:
3043       return "#";
3044     case 5:
3045       switch (get_attr_mode (insn))
3046         {
3047         case MODE_V4SF:
3048           return "%vxorps\t%0, %d0";
3049         case MODE_V2DF:
3050           return "%vxorpd\t%0, %d0";
3051         case MODE_TI:
3052           return "%vpxor\t%0, %d0";
3053         default:
3054           gcc_unreachable ();
3055         }
3056     case 6:
3057     case 7:
3058     case 8:
3059       switch (get_attr_mode (insn))
3060         {
3061         case MODE_V4SF:
3062           return "%vmovaps\t{%1, %0|%0, %1}";
3063         case MODE_V2DF:
3064           return "%vmovapd\t{%1, %0|%0, %1}";
3065         case MODE_TI:
3066           return "%vmovdqa\t{%1, %0|%0, %1}";
3067         case MODE_DI:
3068           return "%vmovq\t{%1, %0|%0, %1}";
3069         case MODE_DF:
3070           if (TARGET_AVX)
3071             {
3072               if (REG_P (operands[0]) && REG_P (operands[1]))
3073                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3074               else
3075                 return "vmovsd\t{%1, %0|%0, %1}";
3076             }
3077           else
3078             return "movsd\t{%1, %0|%0, %1}";
3079         case MODE_V1DF:
3080           if (TARGET_AVX)
3081             {
3082               if (REG_P (operands[0]))
3083                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3084               else
3085                 return "vmovlpd\t{%1, %0|%0, %1}";
3086             }
3087           else
3088             return "movlpd\t{%1, %0|%0, %1}";
3089         case MODE_V2SF:
3090           if (TARGET_AVX)
3091             {
3092               if (REG_P (operands[0]))
3093                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3094               else
3095                 return "vmovlps\t{%1, %0|%0, %1}";
3096             }
3097           else
3098             return "movlps\t{%1, %0|%0, %1}";
3099         default:
3100           gcc_unreachable ();
3101         }
3102
3103     default:
3104       gcc_unreachable ();
3105     }
3106 }
3107   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3108    (set (attr "prefix")
3109      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3110        (const_string "orig")
3111        (const_string "maybe_vex")))
3112    (set (attr "prefix_data16")
3113      (if_then_else (eq_attr "mode" "V1DF")
3114        (const_string "1")
3115        (const_string "*")))
3116    (set (attr "mode")
3117         (cond [(eq_attr "alternative" "0,1,2")
3118                  (const_string "DF")
3119                (eq_attr "alternative" "3,4")
3120                  (const_string "SI")
3121
3122                /* For SSE1, we have many fewer alternatives.  */
3123                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3124                  (cond [(eq_attr "alternative" "5,6")
3125                           (const_string "V4SF")
3126                        ]
3127                    (const_string "V2SF"))
3128
3129                /* xorps is one byte shorter.  */
3130                (eq_attr "alternative" "5")
3131                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3132                             (const_int 0))
3133                           (const_string "V4SF")
3134                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3135                             (const_int 0))
3136                           (const_string "TI")
3137                        ]
3138                        (const_string "V2DF"))
3139
3140                /* For architectures resolving dependencies on
3141                   whole SSE registers use APD move to break dependency
3142                   chains, otherwise use short move to avoid extra work.
3143
3144                   movaps encodes one byte shorter.  */
3145                (eq_attr "alternative" "6")
3146                  (cond
3147                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3148                         (const_int 0))
3149                       (const_string "V4SF")
3150                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3151                         (const_int 0))
3152                       (const_string "V2DF")
3153                    ]
3154                    (const_string "DF"))
3155                /* For architectures resolving dependencies on register
3156                   parts we may avoid extra work to zero out upper part
3157                   of register.  */
3158                (eq_attr "alternative" "7")
3159                  (if_then_else
3160                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3161                        (const_int 0))
3162                    (const_string "V1DF")
3163                    (const_string "DF"))
3164               ]
3165               (const_string "DF")))])
3166
3167 (define_insn "*movdf_integer_rex64"
3168   [(set (match_operand:DF 0 "nonimmediate_operand"
3169                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3170         (match_operand:DF 1 "general_operand"
3171                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3172   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3173    && (reload_in_progress || reload_completed
3174        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3175        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3176            && optimize_function_for_size_p (cfun)
3177            && standard_80387_constant_p (operands[1]))
3178        || GET_CODE (operands[1]) != CONST_DOUBLE
3179        || memory_operand (operands[0], DFmode))"
3180 {
3181   switch (which_alternative)
3182     {
3183     case 0:
3184     case 1:
3185       return output_387_reg_move (insn, operands);
3186
3187     case 2:
3188       return standard_80387_constant_opcode (operands[1]);
3189
3190     case 3:
3191     case 4:
3192       return "#";
3193
3194     case 5:
3195       switch (get_attr_mode (insn))
3196         {
3197         case MODE_V4SF:
3198           return "%vxorps\t%0, %d0";
3199         case MODE_V2DF:
3200           return "%vxorpd\t%0, %d0";
3201         case MODE_TI:
3202           return "%vpxor\t%0, %d0";
3203         default:
3204           gcc_unreachable ();
3205         }
3206     case 6:
3207     case 7:
3208     case 8:
3209       switch (get_attr_mode (insn))
3210         {
3211         case MODE_V4SF:
3212           return "%vmovaps\t{%1, %0|%0, %1}";
3213         case MODE_V2DF:
3214           return "%vmovapd\t{%1, %0|%0, %1}";
3215         case MODE_TI:
3216           return "%vmovdqa\t{%1, %0|%0, %1}";
3217         case MODE_DI:
3218           return "%vmovq\t{%1, %0|%0, %1}";
3219         case MODE_DF:
3220           if (TARGET_AVX)
3221             {
3222               if (REG_P (operands[0]) && REG_P (operands[1]))
3223                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3224               else
3225                 return "vmovsd\t{%1, %0|%0, %1}";
3226             }
3227           else
3228             return "movsd\t{%1, %0|%0, %1}";
3229         case MODE_V1DF:
3230           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3231         case MODE_V2SF:
3232           return "%vmovlps\t{%1, %d0|%d0, %1}";
3233         default:
3234           gcc_unreachable ();
3235         }
3236
3237     case 9:
3238     case 10:
3239     return "%vmovd\t{%1, %0|%0, %1}";
3240
3241     default:
3242       gcc_unreachable();
3243     }
3244 }
3245   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3246    (set (attr "prefix")
3247      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3248        (const_string "orig")
3249        (const_string "maybe_vex")))
3250    (set (attr "prefix_data16")
3251      (if_then_else (eq_attr "mode" "V1DF")
3252        (const_string "1")
3253        (const_string "*")))
3254    (set (attr "mode")
3255         (cond [(eq_attr "alternative" "0,1,2")
3256                  (const_string "DF")
3257                (eq_attr "alternative" "3,4,9,10")
3258                  (const_string "DI")
3259
3260                /* For SSE1, we have many fewer alternatives.  */
3261                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3262                  (cond [(eq_attr "alternative" "5,6")
3263                           (const_string "V4SF")
3264                        ]
3265                    (const_string "V2SF"))
3266
3267                /* xorps is one byte shorter.  */
3268                (eq_attr "alternative" "5")
3269                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3270                             (const_int 0))
3271                           (const_string "V4SF")
3272                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3273                             (const_int 0))
3274                           (const_string "TI")
3275                        ]
3276                        (const_string "V2DF"))
3277
3278                /* For architectures resolving dependencies on
3279                   whole SSE registers use APD move to break dependency
3280                   chains, otherwise use short move to avoid extra work.
3281
3282                   movaps encodes one byte shorter.  */
3283                (eq_attr "alternative" "6")
3284                  (cond
3285                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3286                         (const_int 0))
3287                       (const_string "V4SF")
3288                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3289                         (const_int 0))
3290                       (const_string "V2DF")
3291                    ]
3292                    (const_string "DF"))
3293                /* For architectures resolving dependencies on register
3294                   parts we may avoid extra work to zero out upper part
3295                   of register.  */
3296                (eq_attr "alternative" "7")
3297                  (if_then_else
3298                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3299                        (const_int 0))
3300                    (const_string "V1DF")
3301                    (const_string "DF"))
3302               ]
3303               (const_string "DF")))])
3304
3305 (define_insn "*movdf_integer"
3306   [(set (match_operand:DF 0 "nonimmediate_operand"
3307                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3308         (match_operand:DF 1 "general_operand"
3309                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3310   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3311    && optimize_function_for_speed_p (cfun)
3312    && TARGET_INTEGER_DFMODE_MOVES
3313    && (reload_in_progress || reload_completed
3314        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3315        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3316            && optimize_function_for_size_p (cfun)
3317            && standard_80387_constant_p (operands[1]))
3318        || GET_CODE (operands[1]) != CONST_DOUBLE
3319        || memory_operand (operands[0], DFmode))"
3320 {
3321   switch (which_alternative)
3322     {
3323     case 0:
3324     case 1:
3325       return output_387_reg_move (insn, operands);
3326
3327     case 2:
3328       return standard_80387_constant_opcode (operands[1]);
3329
3330     case 3:
3331     case 4:
3332       return "#";
3333
3334     case 5:
3335       switch (get_attr_mode (insn))
3336         {
3337         case MODE_V4SF:
3338           return "xorps\t%0, %0";
3339         case MODE_V2DF:
3340           return "xorpd\t%0, %0";
3341         case MODE_TI:
3342           return "pxor\t%0, %0";
3343         default:
3344           gcc_unreachable ();
3345         }
3346     case 6:
3347     case 7:
3348     case 8:
3349       switch (get_attr_mode (insn))
3350         {
3351         case MODE_V4SF:
3352           return "movaps\t{%1, %0|%0, %1}";
3353         case MODE_V2DF:
3354           return "movapd\t{%1, %0|%0, %1}";
3355         case MODE_TI:
3356           return "movdqa\t{%1, %0|%0, %1}";
3357         case MODE_DI:
3358           return "movq\t{%1, %0|%0, %1}";
3359         case MODE_DF:
3360           return "movsd\t{%1, %0|%0, %1}";
3361         case MODE_V1DF:
3362           return "movlpd\t{%1, %0|%0, %1}";
3363         case MODE_V2SF:
3364           return "movlps\t{%1, %0|%0, %1}";
3365         default:
3366           gcc_unreachable ();
3367         }
3368
3369     default:
3370       gcc_unreachable();
3371     }
3372 }
3373   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3374    (set (attr "prefix_data16")
3375      (if_then_else (eq_attr "mode" "V1DF")
3376        (const_string "1")
3377        (const_string "*")))
3378    (set (attr "mode")
3379         (cond [(eq_attr "alternative" "0,1,2")
3380                  (const_string "DF")
3381                (eq_attr "alternative" "3,4")
3382                  (const_string "SI")
3383
3384                /* For SSE1, we have many fewer alternatives.  */
3385                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3386                  (cond [(eq_attr "alternative" "5,6")
3387                           (const_string "V4SF")
3388                        ]
3389                    (const_string "V2SF"))
3390
3391                /* xorps is one byte shorter.  */
3392                (eq_attr "alternative" "5")
3393                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3394                             (const_int 0))
3395                           (const_string "V4SF")
3396                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3397                             (const_int 0))
3398                           (const_string "TI")
3399                        ]
3400                        (const_string "V2DF"))
3401
3402                /* For architectures resolving dependencies on
3403                   whole SSE registers use APD move to break dependency
3404                   chains, otherwise use short move to avoid extra work.
3405
3406                   movaps encodes one byte shorter.  */
3407                (eq_attr "alternative" "6")
3408                  (cond
3409                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3410                         (const_int 0))
3411                       (const_string "V4SF")
3412                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3413                         (const_int 0))
3414                       (const_string "V2DF")
3415                    ]
3416                    (const_string "DF"))
3417                /* For architectures resolving dependencies on register
3418                   parts we may avoid extra work to zero out upper part
3419                   of register.  */
3420                (eq_attr "alternative" "7")
3421                  (if_then_else
3422                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3423                        (const_int 0))
3424                    (const_string "V1DF")
3425                    (const_string "DF"))
3426               ]
3427               (const_string "DF")))])
3428
3429 (define_split
3430   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3431         (match_operand:DF 1 "general_operand" ""))]
3432   "reload_completed
3433    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3434    && ! (ANY_FP_REG_P (operands[0]) ||
3435          (GET_CODE (operands[0]) == SUBREG
3436           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3437    && ! (ANY_FP_REG_P (operands[1]) ||
3438          (GET_CODE (operands[1]) == SUBREG
3439           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3440   [(const_int 0)]
3441   "ix86_split_long_move (operands); DONE;")
3442
3443 (define_insn "*swapdf"
3444   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3445         (match_operand:DF 1 "fp_register_operand" "+f"))
3446    (set (match_dup 1)
3447         (match_dup 0))]
3448   "reload_completed || TARGET_80387"
3449 {
3450   if (STACK_TOP_P (operands[0]))
3451     return "fxch\t%1";
3452   else
3453     return "fxch\t%0";
3454 }
3455   [(set_attr "type" "fxch")
3456    (set_attr "mode" "DF")])
3457
3458 (define_expand "movxf"
3459   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3460         (match_operand:XF 1 "general_operand" ""))]
3461   ""
3462   "ix86_expand_move (XFmode, operands); DONE;")
3463
3464 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3465 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3466 ;; Pushing using integer instructions is longer except for constants
3467 ;; and direct memory references.
3468 ;; (assuming that any given constant is pushed only once, but this ought to be
3469 ;;  handled elsewhere).
3470
3471 (define_insn "*pushxf_nointeger"
3472   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3473         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3474   "optimize_function_for_size_p (cfun)"
3475 {
3476   /* This insn should be already split before reg-stack.  */
3477   gcc_unreachable ();
3478 }
3479   [(set_attr "type" "multi")
3480    (set_attr "unit" "i387,*,*")
3481    (set_attr "mode" "XF,SI,SI")])
3482
3483 (define_insn "*pushxf_integer"
3484   [(set (match_operand:XF 0 "push_operand" "=<,<")
3485         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3486   "optimize_function_for_speed_p (cfun)"
3487 {
3488   /* This insn should be already split before reg-stack.  */
3489   gcc_unreachable ();
3490 }
3491   [(set_attr "type" "multi")
3492    (set_attr "unit" "i387,*")
3493    (set_attr "mode" "XF,SI")])
3494
3495 (define_split
3496   [(set (match_operand 0 "push_operand" "")
3497         (match_operand 1 "general_operand" ""))]
3498   "reload_completed
3499    && (GET_MODE (operands[0]) == XFmode
3500        || GET_MODE (operands[0]) == DFmode)
3501    && !ANY_FP_REG_P (operands[1])"
3502   [(const_int 0)]
3503   "ix86_split_long_move (operands); DONE;")
3504
3505 (define_split
3506   [(set (match_operand:XF 0 "push_operand" "")
3507         (match_operand:XF 1 "any_fp_register_operand" ""))]
3508   ""
3509   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3510    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3511   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3512
3513 ;; Do not use integer registers when optimizing for size
3514 (define_insn "*movxf_nointeger"
3515   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3516         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3517   "optimize_function_for_size_p (cfun)
3518    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3519    && (reload_in_progress || reload_completed
3520        || standard_80387_constant_p (operands[1])
3521        || GET_CODE (operands[1]) != CONST_DOUBLE
3522        || memory_operand (operands[0], XFmode))"
3523 {
3524   switch (which_alternative)
3525     {
3526     case 0:
3527     case 1:
3528       return output_387_reg_move (insn, operands);
3529
3530     case 2:
3531       return standard_80387_constant_opcode (operands[1]);
3532
3533     case 3: case 4:
3534       return "#";
3535     default:
3536       gcc_unreachable ();
3537     }
3538 }
3539   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3540    (set_attr "mode" "XF,XF,XF,SI,SI")])
3541
3542 (define_insn "*movxf_integer"
3543   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3544         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3545   "optimize_function_for_speed_p (cfun)
3546    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3547    && (reload_in_progress || reload_completed
3548        || GET_CODE (operands[1]) != CONST_DOUBLE
3549        || memory_operand (operands[0], XFmode))"
3550 {
3551   switch (which_alternative)
3552     {
3553     case 0:
3554     case 1:
3555       return output_387_reg_move (insn, operands);
3556
3557     case 2:
3558       return standard_80387_constant_opcode (operands[1]);
3559
3560     case 3: case 4:
3561       return "#";
3562
3563     default:
3564       gcc_unreachable ();
3565     }
3566 }
3567   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3568    (set_attr "mode" "XF,XF,XF,SI,SI")])
3569
3570 (define_expand "movtf"
3571   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3572         (match_operand:TF 1 "nonimmediate_operand" ""))]
3573   "TARGET_SSE2"
3574 {
3575   ix86_expand_move (TFmode, operands);
3576   DONE;
3577 })
3578
3579 (define_insn "*movtf_internal"
3580   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3581         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3582   "TARGET_SSE2
3583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3584 {
3585   switch (which_alternative)
3586     {
3587     case 0:
3588     case 1:
3589       if (get_attr_mode (insn) == MODE_V4SF)
3590         return "%vmovaps\t{%1, %0|%0, %1}";
3591       else
3592         return "%vmovdqa\t{%1, %0|%0, %1}";
3593     case 2:
3594       if (get_attr_mode (insn) == MODE_V4SF)
3595         return "%vxorps\t%0, %d0";
3596       else
3597         return "%vpxor\t%0, %d0";
3598     case 3:
3599     case 4:
3600         return "#";
3601     default:
3602       gcc_unreachable ();
3603     }
3604 }
3605   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3606    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3607    (set (attr "mode")
3608         (cond [(eq_attr "alternative" "0,2")
3609                  (if_then_else
3610                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3611                        (const_int 0))
3612                    (const_string "V4SF")
3613                    (const_string "TI"))
3614                (eq_attr "alternative" "1")
3615                  (if_then_else
3616                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3617                             (const_int 0))
3618                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3619                             (const_int 0)))
3620                    (const_string "V4SF")
3621                    (const_string "TI"))]
3622                (const_string "DI")))])
3623
3624 (define_insn "*pushtf_sse"
3625   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3626         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3627   "TARGET_SSE2"
3628 {
3629   /* This insn should be already split before reg-stack.  */
3630   gcc_unreachable ();
3631 }
3632   [(set_attr "type" "multi")
3633    (set_attr "unit" "sse,*,*")
3634    (set_attr "mode" "TF,SI,SI")])
3635
3636 (define_split
3637   [(set (match_operand:TF 0 "push_operand" "")
3638         (match_operand:TF 1 "general_operand" ""))]
3639   "TARGET_SSE2 && reload_completed
3640    && !SSE_REG_P (operands[1])"
3641   [(const_int 0)]
3642   "ix86_split_long_move (operands); DONE;")
3643
3644 (define_split
3645   [(set (match_operand:TF 0 "push_operand" "")
3646         (match_operand:TF 1 "any_fp_register_operand" ""))]
3647   "TARGET_SSE2"
3648   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3649    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3650   "")
3651
3652 (define_split
3653   [(set (match_operand 0 "nonimmediate_operand" "")
3654         (match_operand 1 "general_operand" ""))]
3655   "reload_completed
3656    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3657    && GET_MODE (operands[0]) == XFmode
3658    && ! (ANY_FP_REG_P (operands[0]) ||
3659          (GET_CODE (operands[0]) == SUBREG
3660           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3661    && ! (ANY_FP_REG_P (operands[1]) ||
3662          (GET_CODE (operands[1]) == SUBREG
3663           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3664   [(const_int 0)]
3665   "ix86_split_long_move (operands); DONE;")
3666
3667 (define_split
3668   [(set (match_operand 0 "register_operand" "")
3669         (match_operand 1 "memory_operand" ""))]
3670   "reload_completed
3671    && MEM_P (operands[1])
3672    && (GET_MODE (operands[0]) == TFmode
3673        || GET_MODE (operands[0]) == XFmode
3674        || GET_MODE (operands[0]) == SFmode
3675        || GET_MODE (operands[0]) == DFmode)
3676    && (operands[2] = find_constant_src (insn))"
3677   [(set (match_dup 0) (match_dup 2))]
3678 {
3679   rtx c = operands[2];
3680   rtx r = operands[0];
3681
3682   if (GET_CODE (r) == SUBREG)
3683     r = SUBREG_REG (r);
3684
3685   if (SSE_REG_P (r))
3686     {
3687       if (!standard_sse_constant_p (c))
3688         FAIL;
3689     }
3690   else if (FP_REG_P (r))
3691     {
3692       if (!standard_80387_constant_p (c))
3693         FAIL;
3694     }
3695   else if (MMX_REG_P (r))
3696     FAIL;
3697 })
3698
3699 (define_split
3700   [(set (match_operand 0 "register_operand" "")
3701         (float_extend (match_operand 1 "memory_operand" "")))]
3702   "reload_completed
3703    && MEM_P (operands[1])
3704    && (GET_MODE (operands[0]) == TFmode
3705        || GET_MODE (operands[0]) == XFmode
3706        || GET_MODE (operands[0]) == SFmode
3707        || GET_MODE (operands[0]) == DFmode)
3708    && (operands[2] = find_constant_src (insn))"
3709   [(set (match_dup 0) (match_dup 2))]
3710 {
3711   rtx c = operands[2];
3712   rtx r = operands[0];
3713
3714   if (GET_CODE (r) == SUBREG)
3715     r = SUBREG_REG (r);
3716
3717   if (SSE_REG_P (r))
3718     {
3719       if (!standard_sse_constant_p (c))
3720         FAIL;
3721     }
3722   else if (FP_REG_P (r))
3723     {
3724       if (!standard_80387_constant_p (c))
3725         FAIL;
3726     }
3727   else if (MMX_REG_P (r))
3728     FAIL;
3729 })
3730
3731 (define_insn "swapxf"
3732   [(set (match_operand:XF 0 "register_operand" "+f")
3733         (match_operand:XF 1 "register_operand" "+f"))
3734    (set (match_dup 1)
3735         (match_dup 0))]
3736   "TARGET_80387"
3737 {
3738   if (STACK_TOP_P (operands[0]))
3739     return "fxch\t%1";
3740   else
3741     return "fxch\t%0";
3742 }
3743   [(set_attr "type" "fxch")
3744    (set_attr "mode" "XF")])
3745
3746 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3747 (define_split
3748   [(set (match_operand:X87MODEF 0 "register_operand" "")
3749         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3750   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3751    && (standard_80387_constant_p (operands[1]) == 8
3752        || standard_80387_constant_p (operands[1]) == 9)"
3753   [(set (match_dup 0)(match_dup 1))
3754    (set (match_dup 0)
3755         (neg:X87MODEF (match_dup 0)))]
3756 {
3757   REAL_VALUE_TYPE r;
3758
3759   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3760   if (real_isnegzero (&r))
3761     operands[1] = CONST0_RTX (<MODE>mode);
3762   else
3763     operands[1] = CONST1_RTX (<MODE>mode);
3764 })
3765
3766 (define_split
3767   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3768         (match_operand:TF 1 "general_operand" ""))]
3769   "reload_completed
3770    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3771   [(const_int 0)]
3772   "ix86_split_long_move (operands); DONE;")
3773 \f
3774 ;; Zero extension instructions
3775
3776 (define_expand "zero_extendhisi2"
3777   [(set (match_operand:SI 0 "register_operand" "")
3778      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3779   ""
3780 {
3781   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3782     {
3783       operands[1] = force_reg (HImode, operands[1]);
3784       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3785       DONE;
3786     }
3787 })
3788
3789 (define_insn "zero_extendhisi2_and"
3790   [(set (match_operand:SI 0 "register_operand" "=r")
3791      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3792    (clobber (reg:CC FLAGS_REG))]
3793   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3794   "#"
3795   [(set_attr "type" "alu1")
3796    (set_attr "mode" "SI")])
3797
3798 (define_split
3799   [(set (match_operand:SI 0 "register_operand" "")
3800         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3801    (clobber (reg:CC FLAGS_REG))]
3802   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3803    && optimize_function_for_speed_p (cfun)"
3804   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3805               (clobber (reg:CC FLAGS_REG))])]
3806   "")
3807
3808 (define_insn "*zero_extendhisi2_movzwl"
3809   [(set (match_operand:SI 0 "register_operand" "=r")
3810      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3811   "!TARGET_ZERO_EXTEND_WITH_AND
3812    || optimize_function_for_size_p (cfun)"
3813   "movz{wl|x}\t{%1, %0|%0, %1}"
3814   [(set_attr "type" "imovx")
3815    (set_attr "mode" "SI")])
3816
3817 (define_expand "zero_extendqihi2"
3818   [(parallel
3819     [(set (match_operand:HI 0 "register_operand" "")
3820        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3821      (clobber (reg:CC FLAGS_REG))])]
3822   ""
3823   "")
3824
3825 (define_insn "*zero_extendqihi2_and"
3826   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3827      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3828    (clobber (reg:CC FLAGS_REG))]
3829   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3830   "#"
3831   [(set_attr "type" "alu1")
3832    (set_attr "mode" "HI")])
3833
3834 (define_insn "*zero_extendqihi2_movzbw_and"
3835   [(set (match_operand:HI 0 "register_operand" "=r,r")
3836      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3837    (clobber (reg:CC FLAGS_REG))]
3838   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3839   "#"
3840   [(set_attr "type" "imovx,alu1")
3841    (set_attr "mode" "HI")])
3842
3843 ; zero extend to SImode here to avoid partial register stalls
3844 (define_insn "*zero_extendqihi2_movzbl"
3845   [(set (match_operand:HI 0 "register_operand" "=r")
3846      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3847   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3848    && reload_completed"
3849   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3850   [(set_attr "type" "imovx")
3851    (set_attr "mode" "SI")])
3852
3853 ;; For the movzbw case strip only the clobber
3854 (define_split
3855   [(set (match_operand:HI 0 "register_operand" "")
3856         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3857    (clobber (reg:CC FLAGS_REG))]
3858   "reload_completed
3859    && (!TARGET_ZERO_EXTEND_WITH_AND
3860        || optimize_function_for_size_p (cfun))
3861    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3862   [(set (match_operand:HI 0 "register_operand" "")
3863         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3864
3865 ;; When source and destination does not overlap, clear destination
3866 ;; first and then do the movb
3867 (define_split
3868   [(set (match_operand:HI 0 "register_operand" "")
3869         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3870    (clobber (reg:CC FLAGS_REG))]
3871   "reload_completed
3872    && ANY_QI_REG_P (operands[0])
3873    && (TARGET_ZERO_EXTEND_WITH_AND
3874        && optimize_function_for_speed_p (cfun))
3875    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3876   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3877 {
3878   operands[2] = gen_lowpart (QImode, operands[0]);
3879   ix86_expand_clear (operands[0]);
3880 })
3881
3882 ;; Rest is handled by single and.
3883 (define_split
3884   [(set (match_operand:HI 0 "register_operand" "")
3885         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3886    (clobber (reg:CC FLAGS_REG))]
3887   "reload_completed
3888    && true_regnum (operands[0]) == true_regnum (operands[1])"
3889   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3890               (clobber (reg:CC FLAGS_REG))])]
3891   "")
3892
3893 (define_expand "zero_extendqisi2"
3894   [(parallel
3895     [(set (match_operand:SI 0 "register_operand" "")
3896        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3897      (clobber (reg:CC FLAGS_REG))])]
3898   ""
3899   "")
3900
3901 (define_insn "*zero_extendqisi2_and"
3902   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3903      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3904    (clobber (reg:CC FLAGS_REG))]
3905   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3906   "#"
3907   [(set_attr "type" "alu1")
3908    (set_attr "mode" "SI")])
3909
3910 (define_insn "*zero_extendqisi2_movzbl_and"
3911   [(set (match_operand:SI 0 "register_operand" "=r,r")
3912      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3913    (clobber (reg:CC FLAGS_REG))]
3914   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3915   "#"
3916   [(set_attr "type" "imovx,alu1")
3917    (set_attr "mode" "SI")])
3918
3919 (define_insn "*zero_extendqisi2_movzbl"
3920   [(set (match_operand:SI 0 "register_operand" "=r")
3921      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3922   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3923    && reload_completed"
3924   "movz{bl|x}\t{%1, %0|%0, %1}"
3925   [(set_attr "type" "imovx")
3926    (set_attr "mode" "SI")])
3927
3928 ;; For the movzbl case strip only the clobber
3929 (define_split
3930   [(set (match_operand:SI 0 "register_operand" "")
3931         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3932    (clobber (reg:CC FLAGS_REG))]
3933   "reload_completed
3934    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3935    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3936   [(set (match_dup 0)
3937         (zero_extend:SI (match_dup 1)))])
3938
3939 ;; When source and destination does not overlap, clear destination
3940 ;; first and then do the movb
3941 (define_split
3942   [(set (match_operand:SI 0 "register_operand" "")
3943         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3944    (clobber (reg:CC FLAGS_REG))]
3945   "reload_completed
3946    && ANY_QI_REG_P (operands[0])
3947    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3948    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3949    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3950   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3951 {
3952   operands[2] = gen_lowpart (QImode, operands[0]);
3953   ix86_expand_clear (operands[0]);
3954 })
3955
3956 ;; Rest is handled by single and.
3957 (define_split
3958   [(set (match_operand:SI 0 "register_operand" "")
3959         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3960    (clobber (reg:CC FLAGS_REG))]
3961   "reload_completed
3962    && true_regnum (operands[0]) == true_regnum (operands[1])"
3963   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3964               (clobber (reg:CC FLAGS_REG))])]
3965   "")
3966
3967 ;; %%% Kill me once multi-word ops are sane.
3968 (define_expand "zero_extendsidi2"
3969   [(set (match_operand:DI 0 "register_operand" "")
3970      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3971   ""
3972 {
3973   if (!TARGET_64BIT)
3974     {
3975       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3976       DONE;
3977     }
3978 })
3979
3980 (define_insn "zero_extendsidi2_32"
3981   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3982         (zero_extend:DI
3983          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3984    (clobber (reg:CC FLAGS_REG))]
3985   "!TARGET_64BIT"
3986   "@
3987    #
3988    #
3989    #
3990    movd\t{%1, %0|%0, %1}
3991    movd\t{%1, %0|%0, %1}
3992    %vmovd\t{%1, %0|%0, %1}
3993    %vmovd\t{%1, %0|%0, %1}"
3994   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3995    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3996    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3997
3998 (define_insn "zero_extendsidi2_rex64"
3999   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4000      (zero_extend:DI
4001        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4002   "TARGET_64BIT"
4003   "@
4004    mov\t{%k1, %k0|%k0, %k1}
4005    #
4006    movd\t{%1, %0|%0, %1}
4007    movd\t{%1, %0|%0, %1}
4008    %vmovd\t{%1, %0|%0, %1}
4009    %vmovd\t{%1, %0|%0, %1}"
4010   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4011    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4012    (set_attr "prefix_0f" "0,*,*,*,*,*")
4013    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4014
4015 (define_split
4016   [(set (match_operand:DI 0 "memory_operand" "")
4017      (zero_extend:DI (match_dup 0)))]
4018   "TARGET_64BIT"
4019   [(set (match_dup 4) (const_int 0))]
4020   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4021
4022 (define_split
4023   [(set (match_operand:DI 0 "register_operand" "")
4024         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4025    (clobber (reg:CC FLAGS_REG))]
4026   "!TARGET_64BIT && reload_completed
4027    && true_regnum (operands[0]) == true_regnum (operands[1])"
4028   [(set (match_dup 4) (const_int 0))]
4029   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4030
4031 (define_split
4032   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4034    (clobber (reg:CC FLAGS_REG))]
4035   "!TARGET_64BIT && reload_completed
4036    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4037   [(set (match_dup 3) (match_dup 1))
4038    (set (match_dup 4) (const_int 0))]
4039   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4040
4041 (define_insn "zero_extendhidi2"
4042   [(set (match_operand:DI 0 "register_operand" "=r")
4043      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4044   "TARGET_64BIT"
4045   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4046   [(set_attr "type" "imovx")
4047    (set_attr "mode" "SI")])
4048
4049 (define_insn "zero_extendqidi2"
4050   [(set (match_operand:DI 0 "register_operand" "=r")
4051      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4052   "TARGET_64BIT"
4053   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4054   [(set_attr "type" "imovx")
4055    (set_attr "mode" "SI")])
4056 \f
4057 ;; Sign extension instructions
4058
4059 (define_expand "extendsidi2"
4060   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4061                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4062               (clobber (reg:CC FLAGS_REG))
4063               (clobber (match_scratch:SI 2 ""))])]
4064   ""
4065 {
4066   if (TARGET_64BIT)
4067     {
4068       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4069       DONE;
4070     }
4071 })
4072
4073 (define_insn "*extendsidi2_1"
4074   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4075         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4076    (clobber (reg:CC FLAGS_REG))
4077    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4078   "!TARGET_64BIT"
4079   "#")
4080
4081 (define_insn "extendsidi2_rex64"
4082   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4083         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4084   "TARGET_64BIT"
4085   "@
4086    {cltq|cdqe}
4087    movs{lq|x}\t{%1, %0|%0, %1}"
4088   [(set_attr "type" "imovx")
4089    (set_attr "mode" "DI")
4090    (set_attr "prefix_0f" "0")
4091    (set_attr "modrm" "0,1")])
4092
4093 (define_insn "extendhidi2"
4094   [(set (match_operand:DI 0 "register_operand" "=r")
4095         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4096   "TARGET_64BIT"
4097   "movs{wq|x}\t{%1, %0|%0, %1}"
4098   [(set_attr "type" "imovx")
4099    (set_attr "mode" "DI")])
4100
4101 (define_insn "extendqidi2"
4102   [(set (match_operand:DI 0 "register_operand" "=r")
4103         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4104   "TARGET_64BIT"
4105   "movs{bq|x}\t{%1, %0|%0, %1}"
4106    [(set_attr "type" "imovx")
4107     (set_attr "mode" "DI")])
4108
4109 ;; Extend to memory case when source register does die.
4110 (define_split
4111   [(set (match_operand:DI 0 "memory_operand" "")
4112         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4113    (clobber (reg:CC FLAGS_REG))
4114    (clobber (match_operand:SI 2 "register_operand" ""))]
4115   "(reload_completed
4116     && dead_or_set_p (insn, operands[1])
4117     && !reg_mentioned_p (operands[1], operands[0]))"
4118   [(set (match_dup 3) (match_dup 1))
4119    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4120               (clobber (reg:CC FLAGS_REG))])
4121    (set (match_dup 4) (match_dup 1))]
4122   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4123
4124 ;; Extend to memory case when source register does not die.
4125 (define_split
4126   [(set (match_operand:DI 0 "memory_operand" "")
4127         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4128    (clobber (reg:CC FLAGS_REG))
4129    (clobber (match_operand:SI 2 "register_operand" ""))]
4130   "reload_completed"
4131   [(const_int 0)]
4132 {
4133   split_di (&operands[0], 1, &operands[3], &operands[4]);
4134
4135   emit_move_insn (operands[3], operands[1]);
4136
4137   /* Generate a cltd if possible and doing so it profitable.  */
4138   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4139       && true_regnum (operands[1]) == AX_REG
4140       && true_regnum (operands[2]) == DX_REG)
4141     {
4142       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4143     }
4144   else
4145     {
4146       emit_move_insn (operands[2], operands[1]);
4147       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4148     }
4149   emit_move_insn (operands[4], operands[2]);
4150   DONE;
4151 })
4152
4153 ;; Extend to register case.  Optimize case where source and destination
4154 ;; registers match and cases where we can use cltd.
4155 (define_split
4156   [(set (match_operand:DI 0 "register_operand" "")
4157         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4158    (clobber (reg:CC FLAGS_REG))
4159    (clobber (match_scratch:SI 2 ""))]
4160   "reload_completed"
4161   [(const_int 0)]
4162 {
4163   split_di (&operands[0], 1, &operands[3], &operands[4]);
4164
4165   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4166     emit_move_insn (operands[3], operands[1]);
4167
4168   /* Generate a cltd if possible and doing so it profitable.  */
4169   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4170       && true_regnum (operands[3]) == AX_REG)
4171     {
4172       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4173       DONE;
4174     }
4175
4176   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4177     emit_move_insn (operands[4], operands[1]);
4178
4179   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4180   DONE;
4181 })
4182
4183 (define_insn "extendhisi2"
4184   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4185         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4186   ""
4187 {
4188   switch (get_attr_prefix_0f (insn))
4189     {
4190     case 0:
4191       return "{cwtl|cwde}";
4192     default:
4193       return "movs{wl|x}\t{%1, %0|%0, %1}";
4194     }
4195 }
4196   [(set_attr "type" "imovx")
4197    (set_attr "mode" "SI")
4198    (set (attr "prefix_0f")
4199      ;; movsx is short decodable while cwtl is vector decoded.
4200      (if_then_else (and (eq_attr "cpu" "!k6")
4201                         (eq_attr "alternative" "0"))
4202         (const_string "0")
4203         (const_string "1")))
4204    (set (attr "modrm")
4205      (if_then_else (eq_attr "prefix_0f" "0")
4206         (const_string "0")
4207         (const_string "1")))])
4208
4209 (define_insn "*extendhisi2_zext"
4210   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4211         (zero_extend:DI
4212           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4213   "TARGET_64BIT"
4214 {
4215   switch (get_attr_prefix_0f (insn))
4216     {
4217     case 0:
4218       return "{cwtl|cwde}";
4219     default:
4220       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4221     }
4222 }
4223   [(set_attr "type" "imovx")
4224    (set_attr "mode" "SI")
4225    (set (attr "prefix_0f")
4226      ;; movsx is short decodable while cwtl is vector decoded.
4227      (if_then_else (and (eq_attr "cpu" "!k6")
4228                         (eq_attr "alternative" "0"))
4229         (const_string "0")
4230         (const_string "1")))
4231    (set (attr "modrm")
4232      (if_then_else (eq_attr "prefix_0f" "0")
4233         (const_string "0")
4234         (const_string "1")))])
4235
4236 (define_insn "extendqihi2"
4237   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4238         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4239   ""
4240 {
4241   switch (get_attr_prefix_0f (insn))
4242     {
4243     case 0:
4244       return "{cbtw|cbw}";
4245     default:
4246       return "movs{bw|x}\t{%1, %0|%0, %1}";
4247     }
4248 }
4249   [(set_attr "type" "imovx")
4250    (set_attr "mode" "HI")
4251    (set (attr "prefix_0f")
4252      ;; movsx is short decodable while cwtl is vector decoded.
4253      (if_then_else (and (eq_attr "cpu" "!k6")
4254                         (eq_attr "alternative" "0"))
4255         (const_string "0")
4256         (const_string "1")))
4257    (set (attr "modrm")
4258      (if_then_else (eq_attr "prefix_0f" "0")
4259         (const_string "0")
4260         (const_string "1")))])
4261
4262 (define_insn "extendqisi2"
4263   [(set (match_operand:SI 0 "register_operand" "=r")
4264         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4265   ""
4266   "movs{bl|x}\t{%1, %0|%0, %1}"
4267    [(set_attr "type" "imovx")
4268     (set_attr "mode" "SI")])
4269
4270 (define_insn "*extendqisi2_zext"
4271   [(set (match_operand:DI 0 "register_operand" "=r")
4272         (zero_extend:DI
4273           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4274   "TARGET_64BIT"
4275   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4276    [(set_attr "type" "imovx")
4277     (set_attr "mode" "SI")])
4278 \f
4279 ;; Conversions between float and double.
4280
4281 ;; These are all no-ops in the model used for the 80387.  So just
4282 ;; emit moves.
4283
4284 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4285 (define_insn "*dummy_extendsfdf2"
4286   [(set (match_operand:DF 0 "push_operand" "=<")
4287         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4288   "0"
4289   "#")
4290
4291 (define_split
4292   [(set (match_operand:DF 0 "push_operand" "")
4293         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4294   ""
4295   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4296    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4297
4298 (define_insn "*dummy_extendsfxf2"
4299   [(set (match_operand:XF 0 "push_operand" "=<")
4300         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4301   "0"
4302   "#")
4303
4304 (define_split
4305   [(set (match_operand:XF 0 "push_operand" "")
4306         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4307   ""
4308   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4309    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4310   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4311
4312 (define_split
4313   [(set (match_operand:XF 0 "push_operand" "")
4314         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4315   ""
4316   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4317    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4318   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4319
4320 (define_expand "extendsfdf2"
4321   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4322         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4323   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4324 {
4325   /* ??? Needed for compress_float_constant since all fp constants
4326      are LEGITIMATE_CONSTANT_P.  */
4327   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4328     {
4329       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4330           && standard_80387_constant_p (operands[1]) > 0)
4331         {
4332           operands[1] = simplify_const_unary_operation
4333             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4334           emit_move_insn_1 (operands[0], operands[1]);
4335           DONE;
4336         }
4337       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4338     }
4339 })
4340
4341 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4342    cvtss2sd:
4343       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4344       cvtps2pd xmm2,xmm1
4345    We do the conversion post reload to avoid producing of 128bit spills
4346    that might lead to ICE on 32bit target.  The sequence unlikely combine
4347    anyway.  */
4348 (define_split
4349   [(set (match_operand:DF 0 "register_operand" "")
4350         (float_extend:DF
4351           (match_operand:SF 1 "nonimmediate_operand" "")))]
4352   "TARGET_USE_VECTOR_FP_CONVERTS
4353    && optimize_insn_for_speed_p ()
4354    && reload_completed && SSE_REG_P (operands[0])"
4355    [(set (match_dup 2)
4356          (float_extend:V2DF
4357            (vec_select:V2SF
4358              (match_dup 3)
4359              (parallel [(const_int 0) (const_int 1)]))))]
4360 {
4361   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4362   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4363   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4364      Try to avoid move when unpacking can be done in source.  */
4365   if (REG_P (operands[1]))
4366     {
4367       /* If it is unsafe to overwrite upper half of source, we need
4368          to move to destination and unpack there.  */
4369       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4370            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4371           && true_regnum (operands[0]) != true_regnum (operands[1]))
4372         {
4373           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4374           emit_move_insn (tmp, operands[1]);
4375         }
4376       else
4377         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4378       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4379                                              operands[3]));
4380     }
4381   else
4382     emit_insn (gen_vec_setv4sf_0 (operands[3],
4383                                   CONST0_RTX (V4SFmode), operands[1]));
4384 })
4385
4386 (define_insn "*extendsfdf2_mixed"
4387   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4388         (float_extend:DF
4389           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4390   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4391 {
4392   switch (which_alternative)
4393     {
4394     case 0:
4395     case 1:
4396       return output_387_reg_move (insn, operands);
4397
4398     case 2:
4399       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4400
4401     default:
4402       gcc_unreachable ();
4403     }
4404 }
4405   [(set_attr "type" "fmov,fmov,ssecvt")
4406    (set_attr "prefix" "orig,orig,maybe_vex")
4407    (set_attr "mode" "SF,XF,DF")])
4408
4409 (define_insn "*extendsfdf2_sse"
4410   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4411         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4412   "TARGET_SSE2 && TARGET_SSE_MATH"
4413   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4414   [(set_attr "type" "ssecvt")
4415    (set_attr "prefix" "maybe_vex")
4416    (set_attr "mode" "DF")])
4417
4418 (define_insn "*extendsfdf2_i387"
4419   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4420         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4421   "TARGET_80387"
4422   "* return output_387_reg_move (insn, operands);"
4423   [(set_attr "type" "fmov")
4424    (set_attr "mode" "SF,XF")])
4425
4426 (define_expand "extend<mode>xf2"
4427   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4428         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4429   "TARGET_80387"
4430 {
4431   /* ??? Needed for compress_float_constant since all fp constants
4432      are LEGITIMATE_CONSTANT_P.  */
4433   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4434     {
4435       if (standard_80387_constant_p (operands[1]) > 0)
4436         {
4437           operands[1] = simplify_const_unary_operation
4438             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4439           emit_move_insn_1 (operands[0], operands[1]);
4440           DONE;
4441         }
4442       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4443     }
4444 })
4445
4446 (define_insn "*extend<mode>xf2_i387"
4447   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4448         (float_extend:XF
4449           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4450   "TARGET_80387"
4451   "* return output_387_reg_move (insn, operands);"
4452   [(set_attr "type" "fmov")
4453    (set_attr "mode" "<MODE>,XF")])
4454
4455 ;; %%% This seems bad bad news.
4456 ;; This cannot output into an f-reg because there is no way to be sure
4457 ;; of truncating in that case.  Otherwise this is just like a simple move
4458 ;; insn.  So we pretend we can output to a reg in order to get better
4459 ;; register preferencing, but we really use a stack slot.
4460
4461 ;; Conversion from DFmode to SFmode.
4462
4463 (define_expand "truncdfsf2"
4464   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4465         (float_truncate:SF
4466           (match_operand:DF 1 "nonimmediate_operand" "")))]
4467   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4468 {
4469   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4470     ;
4471   else if (flag_unsafe_math_optimizations)
4472     ;
4473   else
4474     {
4475       enum ix86_stack_slot slot = (virtuals_instantiated
4476                                    ? SLOT_TEMP
4477                                    : SLOT_VIRTUAL);
4478       rtx temp = assign_386_stack_local (SFmode, slot);
4479       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4480       DONE;
4481     }
4482 })
4483
4484 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4485    cvtsd2ss:
4486       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4487       cvtpd2ps xmm2,xmm1
4488    We do the conversion post reload to avoid producing of 128bit spills
4489    that might lead to ICE on 32bit target.  The sequence unlikely combine
4490    anyway.  */
4491 (define_split
4492   [(set (match_operand:SF 0 "register_operand" "")
4493         (float_truncate:SF
4494           (match_operand:DF 1 "nonimmediate_operand" "")))]
4495   "TARGET_USE_VECTOR_FP_CONVERTS
4496    && optimize_insn_for_speed_p ()
4497    && reload_completed && SSE_REG_P (operands[0])"
4498    [(set (match_dup 2)
4499          (vec_concat:V4SF
4500            (float_truncate:V2SF
4501              (match_dup 4))
4502            (match_dup 3)))]
4503 {
4504   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4505   operands[3] = CONST0_RTX (V2SFmode);
4506   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4507   /* Use movsd for loading from memory, unpcklpd for registers.
4508      Try to avoid move when unpacking can be done in source, or SSE3
4509      movddup is available.  */
4510   if (REG_P (operands[1]))
4511     {
4512       if (!TARGET_SSE3
4513           && true_regnum (operands[0]) != true_regnum (operands[1])
4514           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4515               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4516         {
4517           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4518           emit_move_insn (tmp, operands[1]);
4519           operands[1] = tmp;
4520         }
4521       else if (!TARGET_SSE3)
4522         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4523       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4524     }
4525   else
4526     emit_insn (gen_sse2_loadlpd (operands[4],
4527                                  CONST0_RTX (V2DFmode), operands[1]));
4528 })
4529
4530 (define_expand "truncdfsf2_with_temp"
4531   [(parallel [(set (match_operand:SF 0 "" "")
4532                    (float_truncate:SF (match_operand:DF 1 "" "")))
4533               (clobber (match_operand:SF 2 "" ""))])]
4534   "")
4535
4536 (define_insn "*truncdfsf_fast_mixed"
4537   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4538         (float_truncate:SF
4539           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4540   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4541 {
4542   switch (which_alternative)
4543     {
4544     case 0:
4545       return output_387_reg_move (insn, operands);
4546     case 1:
4547       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4548     default:
4549       gcc_unreachable ();
4550     }
4551 }
4552   [(set_attr "type" "fmov,ssecvt")
4553    (set_attr "prefix" "orig,maybe_vex")
4554    (set_attr "mode" "SF")])
4555
4556 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4557 ;; because nothing we do here is unsafe.
4558 (define_insn "*truncdfsf_fast_sse"
4559   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4560         (float_truncate:SF
4561           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4562   "TARGET_SSE2 && TARGET_SSE_MATH"
4563   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4564   [(set_attr "type" "ssecvt")
4565    (set_attr "prefix" "maybe_vex")
4566    (set_attr "mode" "SF")])
4567
4568 (define_insn "*truncdfsf_fast_i387"
4569   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4570         (float_truncate:SF
4571           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4572   "TARGET_80387 && flag_unsafe_math_optimizations"
4573   "* return output_387_reg_move (insn, operands);"
4574   [(set_attr "type" "fmov")
4575    (set_attr "mode" "SF")])
4576
4577 (define_insn "*truncdfsf_mixed"
4578   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4579         (float_truncate:SF
4580           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4581    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4582   "TARGET_MIX_SSE_I387"
4583 {
4584   switch (which_alternative)
4585     {
4586     case 0:
4587       return output_387_reg_move (insn, operands);
4588     case 1:
4589       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4590
4591     default:
4592       return "#";
4593     }
4594 }
4595   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4596    (set_attr "unit" "*,*,i387,i387,i387")
4597    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4598    (set_attr "mode" "SF")])
4599
4600 (define_insn "*truncdfsf_i387"
4601   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4602         (float_truncate:SF
4603           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4604    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4605   "TARGET_80387"
4606 {
4607   switch (which_alternative)
4608     {
4609     case 0:
4610       return output_387_reg_move (insn, operands);
4611
4612     default:
4613       return "#";
4614     }
4615 }
4616   [(set_attr "type" "fmov,multi,multi,multi")
4617    (set_attr "unit" "*,i387,i387,i387")
4618    (set_attr "mode" "SF")])
4619
4620 (define_insn "*truncdfsf2_i387_1"
4621   [(set (match_operand:SF 0 "memory_operand" "=m")
4622         (float_truncate:SF
4623           (match_operand:DF 1 "register_operand" "f")))]
4624   "TARGET_80387
4625    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4626    && !TARGET_MIX_SSE_I387"
4627   "* return output_387_reg_move (insn, operands);"
4628   [(set_attr "type" "fmov")
4629    (set_attr "mode" "SF")])
4630
4631 (define_split
4632   [(set (match_operand:SF 0 "register_operand" "")
4633         (float_truncate:SF
4634          (match_operand:DF 1 "fp_register_operand" "")))
4635    (clobber (match_operand 2 "" ""))]
4636   "reload_completed"
4637   [(set (match_dup 2) (match_dup 1))
4638    (set (match_dup 0) (match_dup 2))]
4639 {
4640   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4641 })
4642
4643 ;; Conversion from XFmode to {SF,DF}mode
4644
4645 (define_expand "truncxf<mode>2"
4646   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4647                    (float_truncate:MODEF
4648                      (match_operand:XF 1 "register_operand" "")))
4649               (clobber (match_dup 2))])]
4650   "TARGET_80387"
4651 {
4652   if (flag_unsafe_math_optimizations)
4653     {
4654       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4655       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4656       if (reg != operands[0])
4657         emit_move_insn (operands[0], reg);
4658       DONE;
4659     }
4660   else
4661     {
4662      enum ix86_stack_slot slot = (virtuals_instantiated
4663                                   ? SLOT_TEMP
4664                                   : SLOT_VIRTUAL);
4665       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4666     }
4667 })
4668
4669 (define_insn "*truncxfsf2_mixed"
4670   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4671         (float_truncate:SF
4672           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4673    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4674   "TARGET_80387"
4675 {
4676   gcc_assert (!which_alternative);
4677   return output_387_reg_move (insn, operands);
4678 }
4679   [(set_attr "type" "fmov,multi,multi,multi")
4680    (set_attr "unit" "*,i387,i387,i387")
4681    (set_attr "mode" "SF")])
4682
4683 (define_insn "*truncxfdf2_mixed"
4684   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4685         (float_truncate:DF
4686           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4687    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4688   "TARGET_80387"
4689 {
4690   gcc_assert (!which_alternative);
4691   return output_387_reg_move (insn, operands);
4692 }
4693   [(set_attr "type" "fmov,multi,multi,multi")
4694    (set_attr "unit" "*,i387,i387,i387")
4695    (set_attr "mode" "DF")])
4696
4697 (define_insn "truncxf<mode>2_i387_noop"
4698   [(set (match_operand:MODEF 0 "register_operand" "=f")
4699         (float_truncate:MODEF
4700           (match_operand:XF 1 "register_operand" "f")))]
4701   "TARGET_80387 && flag_unsafe_math_optimizations"
4702   "* return output_387_reg_move (insn, operands);"
4703   [(set_attr "type" "fmov")
4704    (set_attr "mode" "<MODE>")])
4705
4706 (define_insn "*truncxf<mode>2_i387"
4707   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4708         (float_truncate:MODEF
4709           (match_operand:XF 1 "register_operand" "f")))]
4710   "TARGET_80387"
4711   "* return output_387_reg_move (insn, operands);"
4712   [(set_attr "type" "fmov")
4713    (set_attr "mode" "<MODE>")])
4714
4715 (define_split
4716   [(set (match_operand:MODEF 0 "register_operand" "")
4717         (float_truncate:MODEF
4718           (match_operand:XF 1 "register_operand" "")))
4719    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4720   "TARGET_80387 && reload_completed"
4721   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4722    (set (match_dup 0) (match_dup 2))]
4723   "")
4724
4725 (define_split
4726   [(set (match_operand:MODEF 0 "memory_operand" "")
4727         (float_truncate:MODEF
4728           (match_operand:XF 1 "register_operand" "")))
4729    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4730   "TARGET_80387"
4731   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4732   "")
4733 \f
4734 ;; Signed conversion to DImode.
4735
4736 (define_expand "fix_truncxfdi2"
4737   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4738                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4739               (clobber (reg:CC FLAGS_REG))])]
4740   "TARGET_80387"
4741 {
4742   if (TARGET_FISTTP)
4743    {
4744      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4745      DONE;
4746    }
4747 })
4748
4749 (define_expand "fix_trunc<mode>di2"
4750   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4751                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4752               (clobber (reg:CC FLAGS_REG))])]
4753   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4754 {
4755   if (TARGET_FISTTP
4756       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4757    {
4758      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4759      DONE;
4760    }
4761   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4762    {
4763      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4764      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4765      if (out != operands[0])
4766         emit_move_insn (operands[0], out);
4767      DONE;
4768    }
4769 })
4770
4771 ;; Signed conversion to SImode.
4772
4773 (define_expand "fix_truncxfsi2"
4774   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4775                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "TARGET_80387"
4778 {
4779   if (TARGET_FISTTP)
4780    {
4781      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4782      DONE;
4783    }
4784 })
4785
4786 (define_expand "fix_trunc<mode>si2"
4787   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4788                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4789               (clobber (reg:CC FLAGS_REG))])]
4790   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4791 {
4792   if (TARGET_FISTTP
4793       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4794    {
4795      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4796      DONE;
4797    }
4798   if (SSE_FLOAT_MODE_P (<MODE>mode))
4799    {
4800      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4801      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4802      if (out != operands[0])
4803         emit_move_insn (operands[0], out);
4804      DONE;
4805    }
4806 })
4807
4808 ;; Signed conversion to HImode.
4809
4810 (define_expand "fix_trunc<mode>hi2"
4811   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4812                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4813               (clobber (reg:CC FLAGS_REG))])]
4814   "TARGET_80387
4815    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4816 {
4817   if (TARGET_FISTTP)
4818    {
4819      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4820      DONE;
4821    }
4822 })
4823
4824 ;; Unsigned conversion to SImode.
4825
4826 (define_expand "fixuns_trunc<mode>si2"
4827   [(parallel
4828     [(set (match_operand:SI 0 "register_operand" "")
4829           (unsigned_fix:SI
4830             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4831      (use (match_dup 2))
4832      (clobber (match_scratch:<ssevecmode> 3 ""))
4833      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4834   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4835 {
4836   enum machine_mode mode = <MODE>mode;
4837   enum machine_mode vecmode = <ssevecmode>mode;
4838   REAL_VALUE_TYPE TWO31r;
4839   rtx two31;
4840
4841   if (optimize_insn_for_size_p ())
4842     FAIL;
4843
4844   real_ldexp (&TWO31r, &dconst1, 31);
4845   two31 = const_double_from_real_value (TWO31r, mode);
4846   two31 = ix86_build_const_vector (mode, true, two31);
4847   operands[2] = force_reg (vecmode, two31);
4848 })
4849
4850 (define_insn_and_split "*fixuns_trunc<mode>_1"
4851   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4852         (unsigned_fix:SI
4853           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4854    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4855    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4856    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4857   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4858    && optimize_function_for_speed_p (cfun)"
4859   "#"
4860   "&& reload_completed"
4861   [(const_int 0)]
4862 {
4863   ix86_split_convert_uns_si_sse (operands);
4864   DONE;
4865 })
4866
4867 ;; Unsigned conversion to HImode.
4868 ;; Without these patterns, we'll try the unsigned SI conversion which
4869 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4870
4871 (define_expand "fixuns_trunc<mode>hi2"
4872   [(set (match_dup 2)
4873         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4874    (set (match_operand:HI 0 "nonimmediate_operand" "")
4875         (subreg:HI (match_dup 2) 0))]
4876   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4877   "operands[2] = gen_reg_rtx (SImode);")
4878
4879 ;; When SSE is available, it is always faster to use it!
4880 (define_insn "fix_trunc<mode>di_sse"
4881   [(set (match_operand:DI 0 "register_operand" "=r,r")
4882         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4883   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4884    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4885   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4886   [(set_attr "type" "sseicvt")
4887    (set_attr "prefix" "maybe_vex")
4888    (set_attr "prefix_rex" "1")
4889    (set_attr "mode" "<MODE>")
4890    (set_attr "athlon_decode" "double,vector")
4891    (set_attr "amdfam10_decode" "double,double")])
4892
4893 (define_insn "fix_trunc<mode>si_sse"
4894   [(set (match_operand:SI 0 "register_operand" "=r,r")
4895         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4896   "SSE_FLOAT_MODE_P (<MODE>mode)
4897    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4898   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4899   [(set_attr "type" "sseicvt")
4900    (set_attr "prefix" "maybe_vex")
4901    (set_attr "mode" "<MODE>")
4902    (set_attr "athlon_decode" "double,vector")
4903    (set_attr "amdfam10_decode" "double,double")])
4904
4905 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4906 (define_peephole2
4907   [(set (match_operand:MODEF 0 "register_operand" "")
4908         (match_operand:MODEF 1 "memory_operand" ""))
4909    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4910         (fix:SSEMODEI24 (match_dup 0)))]
4911   "TARGET_SHORTEN_X87_SSE
4912    && peep2_reg_dead_p (2, operands[0])"
4913   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4914   "")
4915
4916 ;; Avoid vector decoded forms of the instruction.
4917 (define_peephole2
4918   [(match_scratch:DF 2 "Y2")
4919    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4920         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4921   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4922   [(set (match_dup 2) (match_dup 1))
4923    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4924   "")
4925
4926 (define_peephole2
4927   [(match_scratch:SF 2 "x")
4928    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4929         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4930   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4931   [(set (match_dup 2) (match_dup 1))
4932    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4933   "")
4934
4935 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4936   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4937         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4938   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4939    && TARGET_FISTTP
4940    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4941          && (TARGET_64BIT || <MODE>mode != DImode))
4942         && TARGET_SSE_MATH)
4943    && can_create_pseudo_p ()"
4944   "#"
4945   "&& 1"
4946   [(const_int 0)]
4947 {
4948   if (memory_operand (operands[0], VOIDmode))
4949     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4950   else
4951     {
4952       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4953       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4954                                                             operands[1],
4955                                                             operands[2]));
4956     }
4957   DONE;
4958 }
4959   [(set_attr "type" "fisttp")
4960    (set_attr "mode" "<MODE>")])
4961
4962 (define_insn "fix_trunc<mode>_i387_fisttp"
4963   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4964         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4965    (clobber (match_scratch:XF 2 "=&1f"))]
4966   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4967    && TARGET_FISTTP
4968    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4969          && (TARGET_64BIT || <MODE>mode != DImode))
4970         && TARGET_SSE_MATH)"
4971   "* return output_fix_trunc (insn, operands, 1);"
4972   [(set_attr "type" "fisttp")
4973    (set_attr "mode" "<MODE>")])
4974
4975 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4976   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4977         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4978    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4979    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4980   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4981    && TARGET_FISTTP
4982    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4983         && (TARGET_64BIT || <MODE>mode != DImode))
4984         && TARGET_SSE_MATH)"
4985   "#"
4986   [(set_attr "type" "fisttp")
4987    (set_attr "mode" "<MODE>")])
4988
4989 (define_split
4990   [(set (match_operand:X87MODEI 0 "register_operand" "")
4991         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4992    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4993    (clobber (match_scratch 3 ""))]
4994   "reload_completed"
4995   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4996               (clobber (match_dup 3))])
4997    (set (match_dup 0) (match_dup 2))]
4998   "")
4999
5000 (define_split
5001   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5002         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5003    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5004    (clobber (match_scratch 3 ""))]
5005   "reload_completed"
5006   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5007               (clobber (match_dup 3))])]
5008   "")
5009
5010 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5011 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5012 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5013 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5014 ;; function in i386.c.
5015 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5016   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5017         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5018    (clobber (reg:CC FLAGS_REG))]
5019   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5020    && !TARGET_FISTTP
5021    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5022          && (TARGET_64BIT || <MODE>mode != DImode))
5023    && can_create_pseudo_p ()"
5024   "#"
5025   "&& 1"
5026   [(const_int 0)]
5027 {
5028   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5029
5030   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5031   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5032   if (memory_operand (operands[0], VOIDmode))
5033     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5034                                          operands[2], operands[3]));
5035   else
5036     {
5037       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5038       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5039                                                      operands[2], operands[3],
5040                                                      operands[4]));
5041     }
5042   DONE;
5043 }
5044   [(set_attr "type" "fistp")
5045    (set_attr "i387_cw" "trunc")
5046    (set_attr "mode" "<MODE>")])
5047
5048 (define_insn "fix_truncdi_i387"
5049   [(set (match_operand:DI 0 "memory_operand" "=m")
5050         (fix:DI (match_operand 1 "register_operand" "f")))
5051    (use (match_operand:HI 2 "memory_operand" "m"))
5052    (use (match_operand:HI 3 "memory_operand" "m"))
5053    (clobber (match_scratch:XF 4 "=&1f"))]
5054   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5055    && !TARGET_FISTTP
5056    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5057   "* return output_fix_trunc (insn, operands, 0);"
5058   [(set_attr "type" "fistp")
5059    (set_attr "i387_cw" "trunc")
5060    (set_attr "mode" "DI")])
5061
5062 (define_insn "fix_truncdi_i387_with_temp"
5063   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5064         (fix:DI (match_operand 1 "register_operand" "f,f")))
5065    (use (match_operand:HI 2 "memory_operand" "m,m"))
5066    (use (match_operand:HI 3 "memory_operand" "m,m"))
5067    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5068    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5069   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5070    && !TARGET_FISTTP
5071    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5072   "#"
5073   [(set_attr "type" "fistp")
5074    (set_attr "i387_cw" "trunc")
5075    (set_attr "mode" "DI")])
5076
5077 (define_split
5078   [(set (match_operand:DI 0 "register_operand" "")
5079         (fix:DI (match_operand 1 "register_operand" "")))
5080    (use (match_operand:HI 2 "memory_operand" ""))
5081    (use (match_operand:HI 3 "memory_operand" ""))
5082    (clobber (match_operand:DI 4 "memory_operand" ""))
5083    (clobber (match_scratch 5 ""))]
5084   "reload_completed"
5085   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5086               (use (match_dup 2))
5087               (use (match_dup 3))
5088               (clobber (match_dup 5))])
5089    (set (match_dup 0) (match_dup 4))]
5090   "")
5091
5092 (define_split
5093   [(set (match_operand:DI 0 "memory_operand" "")
5094         (fix:DI (match_operand 1 "register_operand" "")))
5095    (use (match_operand:HI 2 "memory_operand" ""))
5096    (use (match_operand:HI 3 "memory_operand" ""))
5097    (clobber (match_operand:DI 4 "memory_operand" ""))
5098    (clobber (match_scratch 5 ""))]
5099   "reload_completed"
5100   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5101               (use (match_dup 2))
5102               (use (match_dup 3))
5103               (clobber (match_dup 5))])]
5104   "")
5105
5106 (define_insn "fix_trunc<mode>_i387"
5107   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5108         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5109    (use (match_operand:HI 2 "memory_operand" "m"))
5110    (use (match_operand:HI 3 "memory_operand" "m"))]
5111   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5112    && !TARGET_FISTTP
5113    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5114   "* return output_fix_trunc (insn, operands, 0);"
5115   [(set_attr "type" "fistp")
5116    (set_attr "i387_cw" "trunc")
5117    (set_attr "mode" "<MODE>")])
5118
5119 (define_insn "fix_trunc<mode>_i387_with_temp"
5120   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5121         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5122    (use (match_operand:HI 2 "memory_operand" "m,m"))
5123    (use (match_operand:HI 3 "memory_operand" "m,m"))
5124    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5125   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5126    && !TARGET_FISTTP
5127    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5128   "#"
5129   [(set_attr "type" "fistp")
5130    (set_attr "i387_cw" "trunc")
5131    (set_attr "mode" "<MODE>")])
5132
5133 (define_split
5134   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5135         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5136    (use (match_operand:HI 2 "memory_operand" ""))
5137    (use (match_operand:HI 3 "memory_operand" ""))
5138    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5139   "reload_completed"
5140   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5141               (use (match_dup 2))
5142               (use (match_dup 3))])
5143    (set (match_dup 0) (match_dup 4))]
5144   "")
5145
5146 (define_split
5147   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5148         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5149    (use (match_operand:HI 2 "memory_operand" ""))
5150    (use (match_operand:HI 3 "memory_operand" ""))
5151    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5152   "reload_completed"
5153   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5154               (use (match_dup 2))
5155               (use (match_dup 3))])]
5156   "")
5157
5158 (define_insn "x86_fnstcw_1"
5159   [(set (match_operand:HI 0 "memory_operand" "=m")
5160         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5161   "TARGET_80387"
5162   "fnstcw\t%0"
5163   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5164    (set_attr "mode" "HI")
5165    (set_attr "unit" "i387")])
5166
5167 (define_insn "x86_fldcw_1"
5168   [(set (reg:HI FPCR_REG)
5169         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5170   "TARGET_80387"
5171   "fldcw\t%0"
5172   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5173    (set_attr "mode" "HI")
5174    (set_attr "unit" "i387")
5175    (set_attr "athlon_decode" "vector")
5176    (set_attr "amdfam10_decode" "vector")])
5177 \f
5178 ;; Conversion between fixed point and floating point.
5179
5180 ;; Even though we only accept memory inputs, the backend _really_
5181 ;; wants to be able to do this between registers.
5182
5183 (define_expand "floathi<mode>2"
5184   [(set (match_operand:X87MODEF 0 "register_operand" "")
5185         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5186   "TARGET_80387
5187    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5188        || TARGET_MIX_SSE_I387)"
5189   "")
5190
5191 ;; Pre-reload splitter to add memory clobber to the pattern.
5192 (define_insn_and_split "*floathi<mode>2_1"
5193   [(set (match_operand:X87MODEF 0 "register_operand" "")
5194         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5195   "TARGET_80387
5196    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5197        || TARGET_MIX_SSE_I387)
5198    && can_create_pseudo_p ()"
5199   "#"
5200   "&& 1"
5201   [(parallel [(set (match_dup 0)
5202               (float:X87MODEF (match_dup 1)))
5203    (clobber (match_dup 2))])]
5204   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5205
5206 (define_insn "*floathi<mode>2_i387_with_temp"
5207   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5208         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5209   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5210   "TARGET_80387
5211    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5212        || TARGET_MIX_SSE_I387)"
5213   "#"
5214   [(set_attr "type" "fmov,multi")
5215    (set_attr "mode" "<MODE>")
5216    (set_attr "unit" "*,i387")
5217    (set_attr "fp_int_src" "true")])
5218
5219 (define_insn "*floathi<mode>2_i387"
5220   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5221         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5222   "TARGET_80387
5223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5224        || TARGET_MIX_SSE_I387)"
5225   "fild%Z1\t%1"
5226   [(set_attr "type" "fmov")
5227    (set_attr "mode" "<MODE>")
5228    (set_attr "fp_int_src" "true")])
5229
5230 (define_split
5231   [(set (match_operand:X87MODEF 0 "register_operand" "")
5232         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5233    (clobber (match_operand:HI 2 "memory_operand" ""))]
5234   "TARGET_80387
5235    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5236        || TARGET_MIX_SSE_I387)
5237    && reload_completed"
5238   [(set (match_dup 2) (match_dup 1))
5239    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5240   "")
5241
5242 (define_split
5243   [(set (match_operand:X87MODEF 0 "register_operand" "")
5244         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5245    (clobber (match_operand:HI 2 "memory_operand" ""))]
5246    "TARGET_80387
5247     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5248         || TARGET_MIX_SSE_I387)
5249     && reload_completed"
5250   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5251   "")
5252
5253 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5254   [(set (match_operand:X87MODEF 0 "register_operand" "")
5255         (float:X87MODEF
5256           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5257   "TARGET_80387
5258    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5260   "
5261 {
5262   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5263         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5264       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5265     {
5266       rtx reg = gen_reg_rtx (XFmode);
5267       rtx insn;
5268
5269       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5270
5271       if (<X87MODEF:MODE>mode == SFmode)
5272         insn = gen_truncxfsf2 (operands[0], reg);
5273       else if (<X87MODEF:MODE>mode == DFmode)
5274         insn = gen_truncxfdf2 (operands[0], reg);
5275       else
5276         gcc_unreachable ();
5277
5278       emit_insn (insn);
5279       DONE;
5280     }
5281 }")
5282
5283 ;; Pre-reload splitter to add memory clobber to the pattern.
5284 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5285   [(set (match_operand:X87MODEF 0 "register_operand" "")
5286         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5287   "((TARGET_80387
5288      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5289      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5290            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5291          || TARGET_MIX_SSE_I387))
5292     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5293         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5294         && ((<SSEMODEI24:MODE>mode == SImode
5295              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5296              && optimize_function_for_speed_p (cfun)
5297              && flag_trapping_math)
5298             || !(TARGET_INTER_UNIT_CONVERSIONS
5299                  || optimize_function_for_size_p (cfun)))))
5300    && can_create_pseudo_p ()"
5301   "#"
5302   "&& 1"
5303   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5304               (clobber (match_dup 2))])]
5305 {
5306   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5307
5308   /* Avoid store forwarding (partial memory) stall penalty
5309      by passing DImode value through XMM registers.  */
5310   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5311       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5312       && optimize_function_for_speed_p (cfun))
5313     {
5314       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5315                                                             operands[1],
5316                                                             operands[2]));
5317       DONE;
5318     }
5319 })
5320
5321 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5322   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5323         (float:MODEF
5324           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5325    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5326   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5327    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5328   "#"
5329   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5330    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5331    (set_attr "unit" "*,i387,*,*,*")
5332    (set_attr "athlon_decode" "*,*,double,direct,double")
5333    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5334    (set_attr "fp_int_src" "true")])
5335
5336 (define_insn "*floatsi<mode>2_vector_mixed"
5337   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5338         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5339   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5340    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5341   "@
5342    fild%Z1\t%1
5343    #"
5344   [(set_attr "type" "fmov,sseicvt")
5345    (set_attr "mode" "<MODE>,<ssevecmode>")
5346    (set_attr "unit" "i387,*")
5347    (set_attr "athlon_decode" "*,direct")
5348    (set_attr "amdfam10_decode" "*,double")
5349    (set_attr "fp_int_src" "true")])
5350
5351 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5352   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5353         (float:MODEF
5354           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5355   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5356   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5357    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5358   "#"
5359   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5360    (set_attr "mode" "<MODEF:MODE>")
5361    (set_attr "unit" "*,i387,*,*")
5362    (set_attr "athlon_decode" "*,*,double,direct")
5363    (set_attr "amdfam10_decode" "*,*,vector,double")
5364    (set_attr "fp_int_src" "true")])
5365
5366 (define_split
5367   [(set (match_operand:MODEF 0 "register_operand" "")
5368         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5369    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5370   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5371    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5372    && TARGET_INTER_UNIT_CONVERSIONS
5373    && reload_completed
5374    && (SSE_REG_P (operands[0])
5375        || (GET_CODE (operands[0]) == SUBREG
5376            && SSE_REG_P (operands[0])))"
5377   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5378   "")
5379
5380 (define_split
5381   [(set (match_operand:MODEF 0 "register_operand" "")
5382         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5383    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5384   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5385    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5386    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5387    && reload_completed
5388    && (SSE_REG_P (operands[0])
5389        || (GET_CODE (operands[0]) == SUBREG
5390            && SSE_REG_P (operands[0])))"
5391   [(set (match_dup 2) (match_dup 1))
5392    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5393   "")
5394
5395 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5396   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5397         (float:MODEF
5398           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5399   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5400    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5401    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5402   "@
5403    fild%Z1\t%1
5404    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5405    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5406   [(set_attr "type" "fmov,sseicvt,sseicvt")
5407    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5408    (set_attr "mode" "<MODEF:MODE>")
5409    (set (attr "prefix_rex")
5410      (if_then_else
5411        (and (eq_attr "prefix" "maybe_vex")
5412             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5413        (const_string "1")
5414        (const_string "*")))
5415    (set_attr "unit" "i387,*,*")
5416    (set_attr "athlon_decode" "*,double,direct")
5417    (set_attr "amdfam10_decode" "*,vector,double")
5418    (set_attr "fp_int_src" "true")])
5419
5420 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5421   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5422         (float:MODEF
5423           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5424   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5425    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5426    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5427   "@
5428    fild%Z1\t%1
5429    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5430   [(set_attr "type" "fmov,sseicvt")
5431    (set_attr "prefix" "orig,maybe_vex")
5432    (set_attr "mode" "<MODEF:MODE>")
5433    (set (attr "prefix_rex")
5434      (if_then_else
5435        (and (eq_attr "prefix" "maybe_vex")
5436             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5437        (const_string "1")
5438        (const_string "*")))
5439    (set_attr "athlon_decode" "*,direct")
5440    (set_attr "amdfam10_decode" "*,double")
5441    (set_attr "fp_int_src" "true")])
5442
5443 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5444   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5445         (float:MODEF
5446           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5447    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5448   "TARGET_SSE2 && TARGET_SSE_MATH
5449    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5450   "#"
5451   [(set_attr "type" "sseicvt")
5452    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5453    (set_attr "athlon_decode" "double,direct,double")
5454    (set_attr "amdfam10_decode" "vector,double,double")
5455    (set_attr "fp_int_src" "true")])
5456
5457 (define_insn "*floatsi<mode>2_vector_sse"
5458   [(set (match_operand:MODEF 0 "register_operand" "=x")
5459         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5460   "TARGET_SSE2 && TARGET_SSE_MATH
5461    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5462   "#"
5463   [(set_attr "type" "sseicvt")
5464    (set_attr "mode" "<MODE>")
5465    (set_attr "athlon_decode" "direct")
5466    (set_attr "amdfam10_decode" "double")
5467    (set_attr "fp_int_src" "true")])
5468
5469 (define_split
5470   [(set (match_operand:MODEF 0 "register_operand" "")
5471         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5472    (clobber (match_operand:SI 2 "memory_operand" ""))]
5473   "TARGET_SSE2 && TARGET_SSE_MATH
5474    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5475    && reload_completed
5476    && (SSE_REG_P (operands[0])
5477        || (GET_CODE (operands[0]) == SUBREG
5478            && SSE_REG_P (operands[0])))"
5479   [(const_int 0)]
5480 {
5481   rtx op1 = operands[1];
5482
5483   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5484                                      <MODE>mode, 0);
5485   if (GET_CODE (op1) == SUBREG)
5486     op1 = SUBREG_REG (op1);
5487
5488   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5489     {
5490       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5491       emit_insn (gen_sse2_loadld (operands[4],
5492                                   CONST0_RTX (V4SImode), operands[1]));
5493     }
5494   /* We can ignore possible trapping value in the
5495      high part of SSE register for non-trapping math. */
5496   else if (SSE_REG_P (op1) && !flag_trapping_math)
5497     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5498   else
5499     {
5500       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5501       emit_move_insn (operands[2], operands[1]);
5502       emit_insn (gen_sse2_loadld (operands[4],
5503                                   CONST0_RTX (V4SImode), operands[2]));
5504     }
5505   emit_insn
5506     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5507   DONE;
5508 })
5509
5510 (define_split
5511   [(set (match_operand:MODEF 0 "register_operand" "")
5512         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5513    (clobber (match_operand:SI 2 "memory_operand" ""))]
5514   "TARGET_SSE2 && TARGET_SSE_MATH
5515    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5516    && reload_completed
5517    && (SSE_REG_P (operands[0])
5518        || (GET_CODE (operands[0]) == SUBREG
5519            && SSE_REG_P (operands[0])))"
5520   [(const_int 0)]
5521 {
5522   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5523                                      <MODE>mode, 0);
5524   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5525
5526   emit_insn (gen_sse2_loadld (operands[4],
5527                               CONST0_RTX (V4SImode), operands[1]));
5528   emit_insn
5529     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5530   DONE;
5531 })
5532
5533 (define_split
5534   [(set (match_operand:MODEF 0 "register_operand" "")
5535         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5536   "TARGET_SSE2 && TARGET_SSE_MATH
5537    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5538    && reload_completed
5539    && (SSE_REG_P (operands[0])
5540        || (GET_CODE (operands[0]) == SUBREG
5541            && SSE_REG_P (operands[0])))"
5542   [(const_int 0)]
5543 {
5544   rtx op1 = operands[1];
5545
5546   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5547                                      <MODE>mode, 0);
5548   if (GET_CODE (op1) == SUBREG)
5549     op1 = SUBREG_REG (op1);
5550
5551   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5552     {
5553       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5554       emit_insn (gen_sse2_loadld (operands[4],
5555                                   CONST0_RTX (V4SImode), operands[1]));
5556     }
5557   /* We can ignore possible trapping value in the
5558      high part of SSE register for non-trapping math. */
5559   else if (SSE_REG_P (op1) && !flag_trapping_math)
5560     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5561   else
5562     gcc_unreachable ();
5563   emit_insn
5564     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5565   DONE;
5566 })
5567
5568 (define_split
5569   [(set (match_operand:MODEF 0 "register_operand" "")
5570         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5571   "TARGET_SSE2 && TARGET_SSE_MATH
5572    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5573    && reload_completed
5574    && (SSE_REG_P (operands[0])
5575        || (GET_CODE (operands[0]) == SUBREG
5576            && SSE_REG_P (operands[0])))"
5577   [(const_int 0)]
5578 {
5579   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5580                                      <MODE>mode, 0);
5581   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5582
5583   emit_insn (gen_sse2_loadld (operands[4],
5584                               CONST0_RTX (V4SImode), operands[1]));
5585   emit_insn
5586     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5587   DONE;
5588 })
5589
5590 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5591   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5592         (float:MODEF
5593           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5594   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5595   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5596    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5597   "#"
5598   [(set_attr "type" "sseicvt")
5599    (set_attr "mode" "<MODEF:MODE>")
5600    (set_attr "athlon_decode" "double,direct")
5601    (set_attr "amdfam10_decode" "vector,double")
5602    (set_attr "fp_int_src" "true")])
5603
5604 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5605   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5606         (float:MODEF
5607           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5608   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5609    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5610    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5611   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5612   [(set_attr "type" "sseicvt")
5613    (set_attr "prefix" "maybe_vex")
5614    (set_attr "mode" "<MODEF:MODE>")
5615    (set (attr "prefix_rex")
5616      (if_then_else
5617        (and (eq_attr "prefix" "maybe_vex")
5618             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5619        (const_string "1")
5620        (const_string "*")))
5621    (set_attr "athlon_decode" "double,direct")
5622    (set_attr "amdfam10_decode" "vector,double")
5623    (set_attr "fp_int_src" "true")])
5624
5625 (define_split
5626   [(set (match_operand:MODEF 0 "register_operand" "")
5627         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5628    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5629   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5630    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5631    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5632    && reload_completed
5633    && (SSE_REG_P (operands[0])
5634        || (GET_CODE (operands[0]) == SUBREG
5635            && SSE_REG_P (operands[0])))"
5636   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5637   "")
5638
5639 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5640   [(set (match_operand:MODEF 0 "register_operand" "=x")
5641         (float:MODEF
5642           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5643   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5644    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5645    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5646   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5647   [(set_attr "type" "sseicvt")
5648    (set_attr "prefix" "maybe_vex")
5649    (set_attr "mode" "<MODEF:MODE>")
5650    (set (attr "prefix_rex")
5651      (if_then_else
5652        (and (eq_attr "prefix" "maybe_vex")
5653             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5654        (const_string "1")
5655        (const_string "*")))
5656    (set_attr "athlon_decode" "direct")
5657    (set_attr "amdfam10_decode" "double")
5658    (set_attr "fp_int_src" "true")])
5659
5660 (define_split
5661   [(set (match_operand:MODEF 0 "register_operand" "")
5662         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5663    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5664   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5665    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5666    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5667    && reload_completed
5668    && (SSE_REG_P (operands[0])
5669        || (GET_CODE (operands[0]) == SUBREG
5670            && SSE_REG_P (operands[0])))"
5671   [(set (match_dup 2) (match_dup 1))
5672    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5673   "")
5674
5675 (define_split
5676   [(set (match_operand:MODEF 0 "register_operand" "")
5677         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5678    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5679   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5680    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5681    && reload_completed
5682    && (SSE_REG_P (operands[0])
5683        || (GET_CODE (operands[0]) == SUBREG
5684            && SSE_REG_P (operands[0])))"
5685   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5686   "")
5687
5688 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5689   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5690         (float:X87MODEF
5691           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5692   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5693   "TARGET_80387
5694    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5695   "@
5696    fild%Z1\t%1
5697    #"
5698   [(set_attr "type" "fmov,multi")
5699    (set_attr "mode" "<X87MODEF:MODE>")
5700    (set_attr "unit" "*,i387")
5701    (set_attr "fp_int_src" "true")])
5702
5703 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5704   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5705         (float:X87MODEF
5706           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5707   "TARGET_80387
5708    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5709   "fild%Z1\t%1"
5710   [(set_attr "type" "fmov")
5711    (set_attr "mode" "<X87MODEF:MODE>")
5712    (set_attr "fp_int_src" "true")])
5713
5714 (define_split
5715   [(set (match_operand:X87MODEF 0 "register_operand" "")
5716         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5717    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5718   "TARGET_80387
5719    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5720    && reload_completed
5721    && FP_REG_P (operands[0])"
5722   [(set (match_dup 2) (match_dup 1))
5723    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5724   "")
5725
5726 (define_split
5727   [(set (match_operand:X87MODEF 0 "register_operand" "")
5728         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5729    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5730   "TARGET_80387
5731    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5732    && reload_completed
5733    && FP_REG_P (operands[0])"
5734   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5735   "")
5736
5737 ;; Avoid store forwarding (partial memory) stall penalty
5738 ;; by passing DImode value through XMM registers.  */
5739
5740 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5741   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5742         (float:X87MODEF
5743           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5744    (clobber (match_scratch:V4SI 3 "=X,x"))
5745    (clobber (match_scratch:V4SI 4 "=X,x"))
5746    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5747   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5748    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5749    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5750   "#"
5751   [(set_attr "type" "multi")
5752    (set_attr "mode" "<X87MODEF:MODE>")
5753    (set_attr "unit" "i387")
5754    (set_attr "fp_int_src" "true")])
5755
5756 (define_split
5757   [(set (match_operand:X87MODEF 0 "register_operand" "")
5758         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5759    (clobber (match_scratch:V4SI 3 ""))
5760    (clobber (match_scratch:V4SI 4 ""))
5761    (clobber (match_operand:DI 2 "memory_operand" ""))]
5762   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5763    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5764    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5765    && reload_completed
5766    && FP_REG_P (operands[0])"
5767   [(set (match_dup 2) (match_dup 3))
5768    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5769 {
5770   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5771      Assemble the 64-bit DImode value in an xmm register.  */
5772   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5773                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5774   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5775                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5776   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5777                                          operands[4]));
5778
5779   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5780 })
5781
5782 (define_split
5783   [(set (match_operand:X87MODEF 0 "register_operand" "")
5784         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5785    (clobber (match_scratch:V4SI 3 ""))
5786    (clobber (match_scratch:V4SI 4 ""))
5787    (clobber (match_operand:DI 2 "memory_operand" ""))]
5788   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5789    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5790    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5791    && reload_completed
5792    && FP_REG_P (operands[0])"
5793   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5794   "")
5795
5796 ;; Avoid store forwarding (partial memory) stall penalty by extending
5797 ;; SImode value to DImode through XMM register instead of pushing two
5798 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5799 ;; targets benefit from this optimization. Also note that fild
5800 ;; loads from memory only.
5801
5802 (define_insn "*floatunssi<mode>2_1"
5803   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5804         (unsigned_float:X87MODEF
5805           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5806    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5807    (clobber (match_scratch:SI 3 "=X,x"))]
5808   "!TARGET_64BIT
5809    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5810    && TARGET_SSE"
5811   "#"
5812   [(set_attr "type" "multi")
5813    (set_attr "mode" "<MODE>")])
5814
5815 (define_split
5816   [(set (match_operand:X87MODEF 0 "register_operand" "")
5817         (unsigned_float:X87MODEF
5818           (match_operand:SI 1 "register_operand" "")))
5819    (clobber (match_operand:DI 2 "memory_operand" ""))
5820    (clobber (match_scratch:SI 3 ""))]
5821   "!TARGET_64BIT
5822    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5823    && TARGET_SSE
5824    && reload_completed"
5825   [(set (match_dup 2) (match_dup 1))
5826    (set (match_dup 0)
5827         (float:X87MODEF (match_dup 2)))]
5828   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5829
5830 (define_split
5831   [(set (match_operand:X87MODEF 0 "register_operand" "")
5832         (unsigned_float:X87MODEF
5833           (match_operand:SI 1 "memory_operand" "")))
5834    (clobber (match_operand:DI 2 "memory_operand" ""))
5835    (clobber (match_scratch:SI 3 ""))]
5836   "!TARGET_64BIT
5837    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5838    && TARGET_SSE
5839    && reload_completed"
5840   [(set (match_dup 2) (match_dup 3))
5841    (set (match_dup 0)
5842         (float:X87MODEF (match_dup 2)))]
5843 {
5844   emit_move_insn (operands[3], operands[1]);
5845   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5846 })
5847
5848 (define_expand "floatunssi<mode>2"
5849   [(parallel
5850      [(set (match_operand:X87MODEF 0 "register_operand" "")
5851            (unsigned_float:X87MODEF
5852              (match_operand:SI 1 "nonimmediate_operand" "")))
5853       (clobber (match_dup 2))
5854       (clobber (match_scratch:SI 3 ""))])]
5855   "!TARGET_64BIT
5856    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5857         && TARGET_SSE)
5858        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5859 {
5860   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5861     {
5862       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5863       DONE;
5864     }
5865   else
5866     {
5867       enum ix86_stack_slot slot = (virtuals_instantiated
5868                                    ? SLOT_TEMP
5869                                    : SLOT_VIRTUAL);
5870       operands[2] = assign_386_stack_local (DImode, slot);
5871     }
5872 })
5873
5874 (define_expand "floatunsdisf2"
5875   [(use (match_operand:SF 0 "register_operand" ""))
5876    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5877   "TARGET_64BIT && TARGET_SSE_MATH"
5878   "x86_emit_floatuns (operands); DONE;")
5879
5880 (define_expand "floatunsdidf2"
5881   [(use (match_operand:DF 0 "register_operand" ""))
5882    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5883   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5884    && TARGET_SSE2 && TARGET_SSE_MATH"
5885 {
5886   if (TARGET_64BIT)
5887     x86_emit_floatuns (operands);
5888   else
5889     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5890   DONE;
5891 })
5892 \f
5893 ;; Add instructions
5894
5895 (define_expand "add<mode>3"
5896   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5897         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5898                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5899   ""
5900   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5901
5902 (define_insn_and_split "*add<dwi>3_doubleword"
5903   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5904         (plus:<DWI>
5905           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5906           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5907    (clobber (reg:CC FLAGS_REG))]
5908   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5909   "#"
5910   "reload_completed"
5911   [(parallel [(set (reg:CC FLAGS_REG)
5912                    (unspec:CC [(match_dup 1) (match_dup 2)]
5913                               UNSPEC_ADD_CARRY))
5914               (set (match_dup 0)
5915                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5916    (parallel [(set (match_dup 3)
5917                    (plus:DWIH
5918                      (match_dup 4)
5919                      (plus:DWIH
5920                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5921                        (match_dup 5))))
5922               (clobber (reg:CC FLAGS_REG))])]
5923   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5924
5925 (define_insn "*add<mode>3_cc"
5926   [(set (reg:CC FLAGS_REG)
5927         (unspec:CC
5928           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5929            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5930           UNSPEC_ADD_CARRY))
5931    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5932         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5933   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5934   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5935   [(set_attr "type" "alu")
5936    (set_attr "mode" "<MODE>")])
5937
5938 (define_insn "addqi3_cc"
5939   [(set (reg:CC FLAGS_REG)
5940         (unspec:CC
5941           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5942            (match_operand:QI 2 "general_operand" "qn,qm")]
5943           UNSPEC_ADD_CARRY))
5944    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5945         (plus:QI (match_dup 1) (match_dup 2)))]
5946   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5947   "add{b}\t{%2, %0|%0, %2}"
5948   [(set_attr "type" "alu")
5949    (set_attr "mode" "QI")])
5950
5951 (define_insn "*lea_1"
5952   [(set (match_operand:DWIH 0 "register_operand" "=r")
5953         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5954   ""
5955   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5956   [(set_attr "type" "lea")
5957    (set_attr "mode" "<MODE>")])
5958
5959 (define_insn "*lea_2"
5960   [(set (match_operand:SI 0 "register_operand" "=r")
5961         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5962   "TARGET_64BIT"
5963   "lea{l}\t{%a1, %0|%0, %a1}"
5964   [(set_attr "type" "lea")
5965    (set_attr "mode" "SI")])
5966
5967 (define_insn "*lea_2_zext"
5968   [(set (match_operand:DI 0 "register_operand" "=r")
5969         (zero_extend:DI
5970           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5971   "TARGET_64BIT"
5972   "lea{l}\t{%a1, %k0|%k0, %a1}"
5973   [(set_attr "type" "lea")
5974    (set_attr "mode" "SI")])
5975
5976 (define_insn "*add<mode>_1"
5977   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5978         (plus:SWI48
5979           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5980           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5981    (clobber (reg:CC FLAGS_REG))]
5982   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5983 {
5984   switch (get_attr_type (insn))
5985     {
5986     case TYPE_LEA:
5987       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5988       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5989
5990     case TYPE_INCDEC:
5991       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5992       if (operands[2] == const1_rtx)
5993         return "inc{<imodesuffix>}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{<imodesuffix>}\t%0";
5998         }
5999
6000     default:
6001       /* Use add as much as possible to replace lea for AGU optimization. */
6002       if (which_alternative == 2 && TARGET_OPT_AGU)
6003         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6004         
6005       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6006
6007       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6008          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6009       if (CONST_INT_P (operands[2])
6010           /* Avoid overflows.  */
6011           && (<MODE>mode != DImode
6012               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6013           && (INTVAL (operands[2]) == 128
6014               || (INTVAL (operands[2]) < 0
6015                   && INTVAL (operands[2]) != -128)))
6016         {
6017           operands[2] = GEN_INT (-INTVAL (operands[2]));
6018           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6019         }
6020       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6021     }
6022 }
6023   [(set (attr "type")
6024      (cond [(and (eq_attr "alternative" "2") 
6025                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6026               (const_string "lea")
6027             (eq_attr "alternative" "3")
6028               (const_string "lea")
6029             ; Current assemblers are broken and do not allow @GOTOFF in
6030             ; ought but a memory context.
6031             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6032               (const_string "lea")
6033             (match_operand:SWI48 2 "incdec_operand" "")
6034               (const_string "incdec")
6035            ]
6036            (const_string "alu")))
6037    (set (attr "length_immediate")
6038       (if_then_else
6039         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6040         (const_string "1")
6041         (const_string "*")))
6042    (set_attr "mode" "<MODE>")])
6043
6044 ;; It may seem that nonimmediate operand is proper one for operand 1.
6045 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6046 ;; we take care in ix86_binary_operator_ok to not allow two memory
6047 ;; operands so proper swapping will be done in reload.  This allow
6048 ;; patterns constructed from addsi_1 to match.
6049
6050 (define_insn "*addsi_1_zext"
6051   [(set (match_operand:DI 0 "register_operand" "=r,r")
6052         (zero_extend:DI
6053           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6054                    (match_operand:SI 2 "general_operand" "g,li"))))
6055    (clobber (reg:CC FLAGS_REG))]
6056   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6057 {
6058   switch (get_attr_type (insn))
6059     {
6060     case TYPE_LEA:
6061       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6062       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6063
6064     case TYPE_INCDEC:
6065       if (operands[2] == const1_rtx)
6066         return "inc{l}\t%k0";
6067       else
6068         {
6069           gcc_assert (operands[2] == constm1_rtx);
6070           return "dec{l}\t%k0";
6071         }
6072
6073     default:
6074       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6075          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6076       if (CONST_INT_P (operands[2])
6077           && (INTVAL (operands[2]) == 128
6078               || (INTVAL (operands[2]) < 0
6079                   && INTVAL (operands[2]) != -128)))
6080         {
6081           operands[2] = GEN_INT (-INTVAL (operands[2]));
6082           return "sub{l}\t{%2, %k0|%k0, %2}";
6083         }
6084       return "add{l}\t{%2, %k0|%k0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (cond [(eq_attr "alternative" "1")
6089               (const_string "lea")
6090             ; Current assemblers are broken and do not allow @GOTOFF in
6091             ; ought but a memory context.
6092             (match_operand:SI 2 "pic_symbolic_operand" "")
6093               (const_string "lea")
6094             (match_operand:SI 2 "incdec_operand" "")
6095               (const_string "incdec")
6096            ]
6097            (const_string "alu")))
6098    (set (attr "length_immediate")
6099       (if_then_else
6100         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6101         (const_string "1")
6102         (const_string "*")))
6103    (set_attr "mode" "SI")])
6104
6105 (define_insn "*addhi_1"
6106   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6107         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6108                  (match_operand:HI 2 "general_operand" "rn,rm")))
6109    (clobber (reg:CC FLAGS_REG))]
6110   "TARGET_PARTIAL_REG_STALL
6111    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6112 {
6113   switch (get_attr_type (insn))
6114     {
6115     case TYPE_INCDEC:
6116       if (operands[2] == const1_rtx)
6117         return "inc{w}\t%0";
6118       else
6119         {
6120           gcc_assert (operands[2] == constm1_rtx);
6121           return "dec{w}\t%0";
6122         }
6123
6124     default:
6125       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6127       if (CONST_INT_P (operands[2])
6128           && (INTVAL (operands[2]) == 128
6129               || (INTVAL (operands[2]) < 0
6130                   && INTVAL (operands[2]) != -128)))
6131         {
6132           operands[2] = GEN_INT (-INTVAL (operands[2]));
6133           return "sub{w}\t{%2, %0|%0, %2}";
6134         }
6135       return "add{w}\t{%2, %0|%0, %2}";
6136     }
6137 }
6138   [(set (attr "type")
6139      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6140         (const_string "incdec")
6141         (const_string "alu")))
6142    (set (attr "length_immediate")
6143       (if_then_else
6144         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6145         (const_string "1")
6146         (const_string "*")))
6147    (set_attr "mode" "HI")])
6148
6149 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6150 ;; type optimizations enabled by define-splits.  This is not important
6151 ;; for PII, and in fact harmful because of partial register stalls.
6152
6153 (define_insn "*addhi_1_lea"
6154   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6155         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6156                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6157    (clobber (reg:CC FLAGS_REG))]
6158   "!TARGET_PARTIAL_REG_STALL
6159    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6160 {
6161   switch (get_attr_type (insn))
6162     {
6163     case TYPE_LEA:
6164       return "#";
6165     case TYPE_INCDEC:
6166       if (operands[2] == const1_rtx)
6167         return "inc{w}\t%0";
6168       else
6169         {
6170           gcc_assert (operands[2] == constm1_rtx);
6171           return "dec{w}\t%0";
6172         }
6173
6174     default:
6175       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6177       if (CONST_INT_P (operands[2])
6178           && (INTVAL (operands[2]) == 128
6179               || (INTVAL (operands[2]) < 0
6180                   && INTVAL (operands[2]) != -128)))
6181         {
6182           operands[2] = GEN_INT (-INTVAL (operands[2]));
6183           return "sub{w}\t{%2, %0|%0, %2}";
6184         }
6185       return "add{w}\t{%2, %0|%0, %2}";
6186     }
6187 }
6188   [(set (attr "type")
6189      (if_then_else (eq_attr "alternative" "2")
6190         (const_string "lea")
6191         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6192            (const_string "incdec")
6193            (const_string "alu"))))
6194    (set (attr "length_immediate")
6195       (if_then_else
6196         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6197         (const_string "1")
6198         (const_string "*")))
6199    (set_attr "mode" "HI,HI,SI")])
6200
6201 (define_insn "*addqi_1"
6202   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6203         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6204                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6205    (clobber (reg:CC FLAGS_REG))]
6206   "TARGET_PARTIAL_REG_STALL
6207    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6208 {
6209   int widen = (which_alternative == 2);
6210   switch (get_attr_type (insn))
6211     {
6212     case TYPE_INCDEC:
6213       if (operands[2] == const1_rtx)
6214         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6215       else
6216         {
6217           gcc_assert (operands[2] == constm1_rtx);
6218           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6219         }
6220
6221     default:
6222       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6223          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6224       if (CONST_INT_P (operands[2])
6225           && (INTVAL (operands[2]) == 128
6226               || (INTVAL (operands[2]) < 0
6227                   && INTVAL (operands[2]) != -128)))
6228         {
6229           operands[2] = GEN_INT (-INTVAL (operands[2]));
6230           if (widen)
6231             return "sub{l}\t{%2, %k0|%k0, %2}";
6232           else
6233             return "sub{b}\t{%2, %0|%0, %2}";
6234         }
6235       if (widen)
6236         return "add{l}\t{%k2, %k0|%k0, %k2}";
6237       else
6238         return "add{b}\t{%2, %0|%0, %2}";
6239     }
6240 }
6241   [(set (attr "type")
6242      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6243         (const_string "incdec")
6244         (const_string "alu")))
6245    (set (attr "length_immediate")
6246       (if_then_else
6247         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6248         (const_string "1")
6249         (const_string "*")))
6250    (set_attr "mode" "QI,QI,SI")])
6251
6252 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6253 (define_insn "*addqi_1_lea"
6254   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6255         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6256                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6257    (clobber (reg:CC FLAGS_REG))]
6258   "!TARGET_PARTIAL_REG_STALL
6259    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6260 {
6261   int widen = (which_alternative == 2);
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_LEA:
6265       return "#";
6266     case TYPE_INCDEC:
6267       if (operands[2] == const1_rtx)
6268         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6269       else
6270         {
6271           gcc_assert (operands[2] == constm1_rtx);
6272           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6273         }
6274
6275     default:
6276       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6277          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6278       if (CONST_INT_P (operands[2])
6279           && (INTVAL (operands[2]) == 128
6280               || (INTVAL (operands[2]) < 0
6281                   && INTVAL (operands[2]) != -128)))
6282         {
6283           operands[2] = GEN_INT (-INTVAL (operands[2]));
6284           if (widen)
6285             return "sub{l}\t{%2, %k0|%k0, %2}";
6286           else
6287             return "sub{b}\t{%2, %0|%0, %2}";
6288         }
6289       if (widen)
6290         return "add{l}\t{%k2, %k0|%k0, %k2}";
6291       else
6292         return "add{b}\t{%2, %0|%0, %2}";
6293     }
6294 }
6295   [(set (attr "type")
6296      (if_then_else (eq_attr "alternative" "3")
6297         (const_string "lea")
6298         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6299            (const_string "incdec")
6300            (const_string "alu"))))
6301    (set (attr "length_immediate")
6302       (if_then_else
6303         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6304         (const_string "1")
6305         (const_string "*")))
6306    (set_attr "mode" "QI,QI,SI,SI")])
6307
6308 (define_insn "*addqi_1_slp"
6309   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6310         (plus:QI (match_dup 0)
6311                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6312    (clobber (reg:CC FLAGS_REG))]
6313   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6314    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6315 {
6316   switch (get_attr_type (insn))
6317     {
6318     case TYPE_INCDEC:
6319       if (operands[1] == const1_rtx)
6320         return "inc{b}\t%0";
6321       else
6322         {
6323           gcc_assert (operands[1] == constm1_rtx);
6324           return "dec{b}\t%0";
6325         }
6326
6327     default:
6328       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6329       if (CONST_INT_P (operands[1])
6330           && INTVAL (operands[1]) < 0)
6331         {
6332           operands[1] = GEN_INT (-INTVAL (operands[1]));
6333           return "sub{b}\t{%1, %0|%0, %1}";
6334         }
6335       return "add{b}\t{%1, %0|%0, %1}";
6336     }
6337 }
6338   [(set (attr "type")
6339      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6340         (const_string "incdec")
6341         (const_string "alu1")))
6342    (set (attr "memory")
6343      (if_then_else (match_operand 1 "memory_operand" "")
6344         (const_string "load")
6345         (const_string "none")))
6346    (set_attr "mode" "QI")])
6347
6348 (define_insn "*add<mode>_2"
6349   [(set (reg FLAGS_REG)
6350         (compare
6351           (plus:SWI48
6352             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6353             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6354           (const_int 0)))
6355    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6356         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6357   "ix86_match_ccmode (insn, CCGOCmode)
6358    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6359    /* Current assemblers are broken and do not allow @GOTOFF in
6360       ought but a memory context.  */
6361    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6362 {
6363   switch (get_attr_type (insn))
6364     {
6365     case TYPE_INCDEC:
6366       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6367       if (operands[2] == const1_rtx)
6368         return "inc{<imodesuffix>}\t%0";
6369       else
6370         {
6371           gcc_assert (operands[2] == constm1_rtx);
6372           return "dec{<imodesuffix>}\t%0";
6373         }
6374
6375     default:
6376       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6377       /* ???? In DImode, we ought to handle there the 32bit case too
6378          - do we need new constraint?  */
6379       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6380          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6381       if (CONST_INT_P (operands[2])
6382           /* Avoid overflows.  */
6383           && (<MODE>mode != DImode
6384               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6385           && (INTVAL (operands[2]) == 128
6386               || (INTVAL (operands[2]) < 0
6387                   && INTVAL (operands[2]) != -128)))
6388         {
6389           operands[2] = GEN_INT (-INTVAL (operands[2]));
6390           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6391         }
6392       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6393     }
6394 }
6395   [(set (attr "type")
6396      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6397         (const_string "incdec")
6398         (const_string "alu")))
6399    (set (attr "length_immediate")
6400       (if_then_else
6401         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6402         (const_string "1")
6403         (const_string "*")))
6404    (set_attr "mode" "<MODE>")])
6405
6406 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6407 (define_insn "*addsi_2_zext"
6408   [(set (reg FLAGS_REG)
6409         (compare
6410           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6411                    (match_operand:SI 2 "general_operand" "g"))
6412           (const_int 0)))
6413    (set (match_operand:DI 0 "register_operand" "=r")
6414         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6415   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6416    && ix86_binary_operator_ok (PLUS, SImode, operands)
6417    /* Current assemblers are broken and do not allow @GOTOFF in
6418       ought but a memory context.  */
6419    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6420 {
6421   switch (get_attr_type (insn))
6422     {
6423     case TYPE_INCDEC:
6424       if (operands[2] == const1_rtx)
6425         return "inc{l}\t%k0";
6426       else
6427         {
6428           gcc_assert (operands[2] == constm1_rtx);
6429           return "dec{l}\t%k0";
6430         }
6431
6432     default:
6433       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6434          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6435       if (CONST_INT_P (operands[2])
6436           && (INTVAL (operands[2]) == 128
6437               || (INTVAL (operands[2]) < 0
6438                   && INTVAL (operands[2]) != -128)))
6439         {
6440           operands[2] = GEN_INT (-INTVAL (operands[2]));
6441           return "sub{l}\t{%2, %k0|%k0, %2}";
6442         }
6443       return "add{l}\t{%2, %k0|%k0, %2}";
6444     }
6445 }
6446   [(set (attr "type")
6447      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6448         (const_string "incdec")
6449         (const_string "alu")))
6450    (set (attr "length_immediate")
6451       (if_then_else
6452         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6453         (const_string "1")
6454         (const_string "*")))
6455    (set_attr "mode" "SI")])
6456
6457 (define_insn "*addhi_2"
6458   [(set (reg FLAGS_REG)
6459         (compare
6460           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6461                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6462           (const_int 0)))
6463    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6464         (plus:HI (match_dup 1) (match_dup 2)))]
6465   "ix86_match_ccmode (insn, CCGOCmode)
6466    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6467 {
6468   switch (get_attr_type (insn))
6469     {
6470     case TYPE_INCDEC:
6471       if (operands[2] == const1_rtx)
6472         return "inc{w}\t%0";
6473       else
6474         {
6475           gcc_assert (operands[2] == constm1_rtx);
6476           return "dec{w}\t%0";
6477         }
6478
6479     default:
6480       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6481          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6482       if (CONST_INT_P (operands[2])
6483           && (INTVAL (operands[2]) == 128
6484               || (INTVAL (operands[2]) < 0
6485                   && INTVAL (operands[2]) != -128)))
6486         {
6487           operands[2] = GEN_INT (-INTVAL (operands[2]));
6488           return "sub{w}\t{%2, %0|%0, %2}";
6489         }
6490       return "add{w}\t{%2, %0|%0, %2}";
6491     }
6492 }
6493   [(set (attr "type")
6494      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6495         (const_string "incdec")
6496         (const_string "alu")))
6497    (set (attr "length_immediate")
6498       (if_then_else
6499         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6500         (const_string "1")
6501         (const_string "*")))
6502    (set_attr "mode" "HI")])
6503
6504 (define_insn "*addqi_2"
6505   [(set (reg FLAGS_REG)
6506         (compare
6507           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6508                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6509           (const_int 0)))
6510    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6511         (plus:QI (match_dup 1) (match_dup 2)))]
6512   "ix86_match_ccmode (insn, CCGOCmode)
6513    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6514 {
6515   switch (get_attr_type (insn))
6516     {
6517     case TYPE_INCDEC:
6518       if (operands[2] == const1_rtx)
6519         return "inc{b}\t%0";
6520       else
6521         {
6522           gcc_assert (operands[2] == constm1_rtx
6523                       || (CONST_INT_P (operands[2])
6524                           && INTVAL (operands[2]) == 255));
6525           return "dec{b}\t%0";
6526         }
6527
6528     default:
6529       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6530       if (CONST_INT_P (operands[2])
6531           && INTVAL (operands[2]) < 0)
6532         {
6533           operands[2] = GEN_INT (-INTVAL (operands[2]));
6534           return "sub{b}\t{%2, %0|%0, %2}";
6535         }
6536       return "add{b}\t{%2, %0|%0, %2}";
6537     }
6538 }
6539   [(set (attr "type")
6540      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6541         (const_string "incdec")
6542         (const_string "alu")))
6543    (set_attr "mode" "QI")])
6544
6545 (define_insn "*add<mode>_3"
6546   [(set (reg FLAGS_REG)
6547         (compare
6548           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6549           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6550    (clobber (match_scratch:SWI48 0 "=r"))]
6551   "ix86_match_ccmode (insn, CCZmode)
6552    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6553    /* Current assemblers are broken and do not allow @GOTOFF in
6554       ought but a memory context.  */
6555    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6556 {
6557   switch (get_attr_type (insn))
6558     {
6559     case TYPE_INCDEC:
6560       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6561       if (operands[2] == const1_rtx)
6562         return "inc{<imodesuffix>}\t%0";
6563       else
6564         {
6565           gcc_assert (operands[2] == constm1_rtx);
6566           return "dec{<imodesuffix>}\t%0";
6567         }
6568
6569     default:
6570       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6571       /* ???? In DImode, we ought to handle there the 32bit case too
6572          - do we need new constraint?  */
6573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6575       if (CONST_INT_P (operands[2])
6576           /* Avoid overflows.  */
6577           && (<MODE>mode != DImode
6578               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6579           && (INTVAL (operands[2]) == 128
6580               || (INTVAL (operands[2]) < 0
6581                   && INTVAL (operands[2]) != -128)))
6582         {
6583           operands[2] = GEN_INT (-INTVAL (operands[2]));
6584           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6585         }
6586       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6587     }
6588 }
6589   [(set (attr "type")
6590      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6591         (const_string "incdec")
6592         (const_string "alu")))
6593    (set (attr "length_immediate")
6594       (if_then_else
6595         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6596         (const_string "1")
6597         (const_string "*")))
6598    (set_attr "mode" "<MODE>")])
6599
6600 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6601 (define_insn "*addsi_3_zext"
6602   [(set (reg FLAGS_REG)
6603         (compare
6604           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6605           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6606    (set (match_operand:DI 0 "register_operand" "=r")
6607         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6608   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6609    && ix86_binary_operator_ok (PLUS, SImode, operands)
6610    /* Current assemblers are broken and do not allow @GOTOFF in
6611       ought but a memory context.  */
6612    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6613 {
6614   switch (get_attr_type (insn))
6615     {
6616     case TYPE_INCDEC:
6617       if (operands[2] == const1_rtx)
6618         return "inc{l}\t%k0";
6619       else
6620         {
6621           gcc_assert (operands[2] == constm1_rtx);
6622           return "dec{l}\t%k0";
6623         }
6624
6625     default:
6626       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6627          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6628       if (CONST_INT_P (operands[2])
6629           && (INTVAL (operands[2]) == 128
6630               || (INTVAL (operands[2]) < 0
6631                   && INTVAL (operands[2]) != -128)))
6632         {
6633           operands[2] = GEN_INT (-INTVAL (operands[2]));
6634           return "sub{l}\t{%2, %k0|%k0, %2}";
6635         }
6636       return "add{l}\t{%2, %k0|%k0, %2}";
6637     }
6638 }
6639   [(set (attr "type")
6640      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6641         (const_string "incdec")
6642         (const_string "alu")))
6643    (set (attr "length_immediate")
6644       (if_then_else
6645         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6646         (const_string "1")
6647         (const_string "*")))
6648    (set_attr "mode" "SI")])
6649
6650 (define_insn "*addhi_3"
6651   [(set (reg FLAGS_REG)
6652         (compare
6653           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6654           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6655    (clobber (match_scratch:HI 0 "=r"))]
6656   "ix86_match_ccmode (insn, CCZmode)
6657    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6658 {
6659   switch (get_attr_type (insn))
6660     {
6661     case TYPE_INCDEC:
6662       if (operands[2] == const1_rtx)
6663         return "inc{w}\t%0";
6664       else
6665         {
6666           gcc_assert (operands[2] == constm1_rtx);
6667           return "dec{w}\t%0";
6668         }
6669
6670     default:
6671       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6672          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6673       if (CONST_INT_P (operands[2])
6674           && (INTVAL (operands[2]) == 128
6675               || (INTVAL (operands[2]) < 0
6676                   && INTVAL (operands[2]) != -128)))
6677         {
6678           operands[2] = GEN_INT (-INTVAL (operands[2]));
6679           return "sub{w}\t{%2, %0|%0, %2}";
6680         }
6681       return "add{w}\t{%2, %0|%0, %2}";
6682     }
6683 }
6684   [(set (attr "type")
6685      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6686         (const_string "incdec")
6687         (const_string "alu")))
6688    (set (attr "length_immediate")
6689       (if_then_else
6690         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6691         (const_string "1")
6692         (const_string "*")))
6693    (set_attr "mode" "HI")])
6694
6695 (define_insn "*addqi_3"
6696   [(set (reg FLAGS_REG)
6697         (compare
6698           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6699           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6700    (clobber (match_scratch:QI 0 "=q"))]
6701   "ix86_match_ccmode (insn, CCZmode)
6702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6703 {
6704   switch (get_attr_type (insn))
6705     {
6706     case TYPE_INCDEC:
6707       if (operands[2] == const1_rtx)
6708         return "inc{b}\t%0";
6709       else
6710         {
6711           gcc_assert (operands[2] == constm1_rtx
6712                       || (CONST_INT_P (operands[2])
6713                           && INTVAL (operands[2]) == 255));
6714           return "dec{b}\t%0";
6715         }
6716
6717     default:
6718       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6719       if (CONST_INT_P (operands[2])
6720           && INTVAL (operands[2]) < 0)
6721         {
6722           operands[2] = GEN_INT (-INTVAL (operands[2]));
6723           return "sub{b}\t{%2, %0|%0, %2}";
6724         }
6725       return "add{b}\t{%2, %0|%0, %2}";
6726     }
6727 }
6728   [(set (attr "type")
6729      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6730         (const_string "incdec")
6731         (const_string "alu")))
6732    (set_attr "mode" "QI")])
6733
6734 ; For comparisons against 1, -1 and 128, we may generate better code
6735 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6736 ; is matched then.  We can't accept general immediate, because for
6737 ; case of overflows,  the result is messed up.
6738 ; This pattern also don't hold of 0x8000000000000000, since the value
6739 ; overflows when negated.
6740 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6741 ; only for comparisons not depending on it.
6742
6743 (define_insn "*adddi_4"
6744   [(set (reg FLAGS_REG)
6745         (compare
6746           (match_operand:DI 1 "nonimmediate_operand" "0")
6747           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6748    (clobber (match_scratch:DI 0 "=rm"))]
6749   "TARGET_64BIT
6750    && ix86_match_ccmode (insn, CCGCmode)"
6751 {
6752   switch (get_attr_type (insn))
6753     {
6754     case TYPE_INCDEC:
6755       if (operands[2] == constm1_rtx)
6756         return "inc{q}\t%0";
6757       else
6758         {
6759           gcc_assert (operands[2] == const1_rtx);
6760           return "dec{q}\t%0";
6761         }
6762
6763     default:
6764       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6765       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6766          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6767       if ((INTVAL (operands[2]) == -128
6768            || (INTVAL (operands[2]) > 0
6769                && INTVAL (operands[2]) != 128))
6770           /* Avoid overflows.  */
6771           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6772         return "sub{q}\t{%2, %0|%0, %2}";
6773       operands[2] = GEN_INT (-INTVAL (operands[2]));
6774       return "add{q}\t{%2, %0|%0, %2}";
6775     }
6776 }
6777   [(set (attr "type")
6778      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6779         (const_string "incdec")
6780         (const_string "alu")))
6781    (set (attr "length_immediate")
6782       (if_then_else
6783         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6784         (const_string "1")
6785         (const_string "*")))
6786    (set_attr "mode" "DI")])
6787
6788 ; For comparisons against 1, -1 and 128, we may generate better code
6789 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6790 ; is matched then.  We can't accept general immediate, because for
6791 ; case of overflows,  the result is messed up.
6792 ; This pattern also don't hold of 0x80000000, since the value overflows
6793 ; when negated.
6794 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6795 ; only for comparisons not depending on it.
6796
6797 (define_insn "*addsi_4"
6798   [(set (reg FLAGS_REG)
6799         (compare
6800           (match_operand:SI 1 "nonimmediate_operand" "0")
6801           (match_operand:SI 2 "const_int_operand" "n")))
6802    (clobber (match_scratch:SI 0 "=rm"))]
6803   "ix86_match_ccmode (insn, CCGCmode)
6804    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6805 {
6806   switch (get_attr_type (insn))
6807     {
6808     case TYPE_INCDEC:
6809       if (operands[2] == constm1_rtx)
6810         return "inc{l}\t%0";
6811       else
6812         {
6813           gcc_assert (operands[2] == const1_rtx);
6814           return "dec{l}\t%0";
6815         }
6816
6817     default:
6818       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6819       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6820          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6821       if ((INTVAL (operands[2]) == -128
6822            || (INTVAL (operands[2]) > 0
6823                && INTVAL (operands[2]) != 128)))
6824         return "sub{l}\t{%2, %0|%0, %2}";
6825       operands[2] = GEN_INT (-INTVAL (operands[2]));
6826       return "add{l}\t{%2, %0|%0, %2}";
6827     }
6828 }
6829   [(set (attr "type")
6830      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6831         (const_string "incdec")
6832         (const_string "alu")))
6833    (set (attr "length_immediate")
6834       (if_then_else
6835         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6836         (const_string "1")
6837         (const_string "*")))
6838    (set_attr "mode" "SI")])
6839
6840 ; See comments above addsi_4 for details.
6841
6842 (define_insn "*addhi_4"
6843   [(set (reg FLAGS_REG)
6844         (compare
6845           (match_operand:HI 1 "nonimmediate_operand" "0")
6846           (match_operand:HI 2 "const_int_operand" "n")))
6847    (clobber (match_scratch:HI 0 "=rm"))]
6848   "ix86_match_ccmode (insn, CCGCmode)
6849    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6850 {
6851   switch (get_attr_type (insn))
6852     {
6853     case TYPE_INCDEC:
6854       if (operands[2] == constm1_rtx)
6855         return "inc{w}\t%0";
6856       else
6857         {
6858           gcc_assert (operands[2] == const1_rtx);
6859           return "dec{w}\t%0";
6860         }
6861
6862     default:
6863       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6864       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6865          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6866       if ((INTVAL (operands[2]) == -128
6867            || (INTVAL (operands[2]) > 0
6868                && INTVAL (operands[2]) != 128)))
6869         return "sub{w}\t{%2, %0|%0, %2}";
6870       operands[2] = GEN_INT (-INTVAL (operands[2]));
6871       return "add{w}\t{%2, %0|%0, %2}";
6872     }
6873 }
6874   [(set (attr "type")
6875      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6876         (const_string "incdec")
6877         (const_string "alu")))
6878    (set (attr "length_immediate")
6879       (if_then_else
6880         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6881         (const_string "1")
6882         (const_string "*")))
6883    (set_attr "mode" "HI")])
6884
6885 ; See comments above addsi_4 for details.
6886
6887 (define_insn "*addqi_4"
6888   [(set (reg FLAGS_REG)
6889         (compare
6890           (match_operand:QI 1 "nonimmediate_operand" "0")
6891           (match_operand:QI 2 "const_int_operand" "n")))
6892    (clobber (match_scratch:QI 0 "=qm"))]
6893   "ix86_match_ccmode (insn, CCGCmode)
6894    && (INTVAL (operands[2]) & 0xff) != 0x80"
6895 {
6896   switch (get_attr_type (insn))
6897     {
6898     case TYPE_INCDEC:
6899       if (operands[2] == constm1_rtx
6900           || (CONST_INT_P (operands[2])
6901               && INTVAL (operands[2]) == 255))
6902         return "inc{b}\t%0";
6903       else
6904         {
6905           gcc_assert (operands[2] == const1_rtx);
6906           return "dec{b}\t%0";
6907         }
6908
6909     default:
6910       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6911       if (INTVAL (operands[2]) < 0)
6912         {
6913           operands[2] = GEN_INT (-INTVAL (operands[2]));
6914           return "add{b}\t{%2, %0|%0, %2}";
6915         }
6916       return "sub{b}\t{%2, %0|%0, %2}";
6917     }
6918 }
6919   [(set (attr "type")
6920      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6921         (const_string "incdec")
6922         (const_string "alu")))
6923    (set_attr "mode" "QI")])
6924
6925 (define_insn "*add<mode>_5"
6926   [(set (reg FLAGS_REG)
6927         (compare
6928           (plus:SWI48
6929             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6930             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6931           (const_int 0)))
6932    (clobber (match_scratch:SWI48 0 "=r"))]
6933   "ix86_match_ccmode (insn, CCGOCmode)
6934    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6935    /* Current assemblers are broken and do not allow @GOTOFF in
6936       ought but a memory context.  */
6937    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6938 {
6939   switch (get_attr_type (insn))
6940     {
6941     case TYPE_INCDEC:
6942       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6943       if (operands[2] == const1_rtx)
6944         return "inc{<imodesuffix>}\t%0";
6945       else
6946         {
6947           gcc_assert (operands[2] == constm1_rtx);
6948           return "dec{<imodesuffix>}\t%0";
6949         }
6950
6951     default:
6952       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6953       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6954          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6955       if (CONST_INT_P (operands[2])
6956           /* Avoid overflows.  */
6957           && (<MODE>mode != DImode
6958               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6959           && (INTVAL (operands[2]) == 128
6960               || (INTVAL (operands[2]) < 0
6961                   && INTVAL (operands[2]) != -128)))
6962         {
6963           operands[2] = GEN_INT (-INTVAL (operands[2]));
6964           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6965         }
6966       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6967     }
6968 }
6969   [(set (attr "type")
6970      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6971         (const_string "incdec")
6972         (const_string "alu")))
6973    (set (attr "length_immediate")
6974       (if_then_else
6975         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6976         (const_string "1")
6977         (const_string "*")))
6978    (set_attr "mode" "<MODE>")])
6979
6980 (define_insn "*addhi_5"
6981   [(set (reg FLAGS_REG)
6982         (compare
6983           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6984                    (match_operand:HI 2 "general_operand" "rmn"))
6985           (const_int 0)))
6986    (clobber (match_scratch:HI 0 "=r"))]
6987   "ix86_match_ccmode (insn, CCGOCmode)
6988    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6989 {
6990   switch (get_attr_type (insn))
6991     {
6992     case TYPE_INCDEC:
6993       if (operands[2] == const1_rtx)
6994         return "inc{w}\t%0";
6995       else
6996         {
6997           gcc_assert (operands[2] == constm1_rtx);
6998           return "dec{w}\t%0";
6999         }
7000
7001     default:
7002       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7003          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7004       if (CONST_INT_P (operands[2])
7005           && (INTVAL (operands[2]) == 128
7006               || (INTVAL (operands[2]) < 0
7007                   && INTVAL (operands[2]) != -128)))
7008         {
7009           operands[2] = GEN_INT (-INTVAL (operands[2]));
7010           return "sub{w}\t{%2, %0|%0, %2}";
7011         }
7012       return "add{w}\t{%2, %0|%0, %2}";
7013     }
7014 }
7015   [(set (attr "type")
7016      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7017         (const_string "incdec")
7018         (const_string "alu")))
7019    (set (attr "length_immediate")
7020       (if_then_else
7021         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7022         (const_string "1")
7023         (const_string "*")))
7024    (set_attr "mode" "HI")])
7025
7026 (define_insn "*addqi_5"
7027   [(set (reg FLAGS_REG)
7028         (compare
7029           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7030                    (match_operand:QI 2 "general_operand" "qmn"))
7031           (const_int 0)))
7032    (clobber (match_scratch:QI 0 "=q"))]
7033   "ix86_match_ccmode (insn, CCGOCmode)
7034    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035 {
7036   switch (get_attr_type (insn))
7037     {
7038     case TYPE_INCDEC:
7039       if (operands[2] == const1_rtx)
7040         return "inc{b}\t%0";
7041       else
7042         {
7043           gcc_assert (operands[2] == constm1_rtx
7044                       || (CONST_INT_P (operands[2])
7045                           && INTVAL (operands[2]) == 255));
7046           return "dec{b}\t%0";
7047         }
7048
7049     default:
7050       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7051       if (CONST_INT_P (operands[2])
7052           && INTVAL (operands[2]) < 0)
7053         {
7054           operands[2] = GEN_INT (-INTVAL (operands[2]));
7055           return "sub{b}\t{%2, %0|%0, %2}";
7056         }
7057       return "add{b}\t{%2, %0|%0, %2}";
7058     }
7059 }
7060   [(set (attr "type")
7061      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7062         (const_string "incdec")
7063         (const_string "alu")))
7064    (set_attr "mode" "QI")])
7065
7066 (define_insn "*addqi_ext_1_rex64"
7067   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7068                          (const_int 8)
7069                          (const_int 8))
7070         (plus:SI
7071           (zero_extract:SI
7072             (match_operand 1 "ext_register_operand" "0")
7073             (const_int 8)
7074             (const_int 8))
7075           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7076    (clobber (reg:CC FLAGS_REG))]
7077   "TARGET_64BIT"
7078 {
7079   switch (get_attr_type (insn))
7080     {
7081     case TYPE_INCDEC:
7082       if (operands[2] == const1_rtx)
7083         return "inc{b}\t%h0";
7084       else
7085         {
7086           gcc_assert (operands[2] == constm1_rtx
7087                       || (CONST_INT_P (operands[2])
7088                           && INTVAL (operands[2]) == 255));
7089           return "dec{b}\t%h0";
7090         }
7091
7092     default:
7093       return "add{b}\t{%2, %h0|%h0, %2}";
7094     }
7095 }
7096   [(set (attr "type")
7097      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7098         (const_string "incdec")
7099         (const_string "alu")))
7100    (set_attr "modrm" "1")
7101    (set_attr "mode" "QI")])
7102
7103 (define_insn "addqi_ext_1"
7104   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7105                          (const_int 8)
7106                          (const_int 8))
7107         (plus:SI
7108           (zero_extract:SI
7109             (match_operand 1 "ext_register_operand" "0")
7110             (const_int 8)
7111             (const_int 8))
7112           (match_operand:QI 2 "general_operand" "Qmn")))
7113    (clobber (reg:CC FLAGS_REG))]
7114   "!TARGET_64BIT"
7115 {
7116   switch (get_attr_type (insn))
7117     {
7118     case TYPE_INCDEC:
7119       if (operands[2] == const1_rtx)
7120         return "inc{b}\t%h0";
7121       else
7122         {
7123           gcc_assert (operands[2] == constm1_rtx
7124                       || (CONST_INT_P (operands[2])
7125                           && INTVAL (operands[2]) == 255));
7126           return "dec{b}\t%h0";
7127         }
7128
7129     default:
7130       return "add{b}\t{%2, %h0|%h0, %2}";
7131     }
7132 }
7133   [(set (attr "type")
7134      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7135         (const_string "incdec")
7136         (const_string "alu")))
7137    (set_attr "modrm" "1")
7138    (set_attr "mode" "QI")])
7139
7140 (define_insn "*addqi_ext_2"
7141   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7142                          (const_int 8)
7143                          (const_int 8))
7144         (plus:SI
7145           (zero_extract:SI
7146             (match_operand 1 "ext_register_operand" "%0")
7147             (const_int 8)
7148             (const_int 8))
7149           (zero_extract:SI
7150             (match_operand 2 "ext_register_operand" "Q")
7151             (const_int 8)
7152             (const_int 8))))
7153    (clobber (reg:CC FLAGS_REG))]
7154   ""
7155   "add{b}\t{%h2, %h0|%h0, %h2}"
7156   [(set_attr "type" "alu")
7157    (set_attr "mode" "QI")])
7158
7159 ;; The lea patterns for non-Pmodes needs to be matched by
7160 ;; several insns converted to real lea by splitters.
7161
7162 (define_insn_and_split "*lea_general_1"
7163   [(set (match_operand 0 "register_operand" "=r")
7164         (plus (plus (match_operand 1 "index_register_operand" "l")
7165                     (match_operand 2 "register_operand" "r"))
7166               (match_operand 3 "immediate_operand" "i")))]
7167   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7168     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7169    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7170    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7171    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7172    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7173        || GET_MODE (operands[3]) == VOIDmode)"
7174   "#"
7175   "&& reload_completed"
7176   [(const_int 0)]
7177 {
7178   rtx pat;
7179   operands[0] = gen_lowpart (SImode, operands[0]);
7180   operands[1] = gen_lowpart (Pmode, operands[1]);
7181   operands[2] = gen_lowpart (Pmode, operands[2]);
7182   operands[3] = gen_lowpart (Pmode, operands[3]);
7183   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7184                       operands[3]);
7185   if (Pmode != SImode)
7186     pat = gen_rtx_SUBREG (SImode, pat, 0);
7187   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7188   DONE;
7189 }
7190   [(set_attr "type" "lea")
7191    (set_attr "mode" "SI")])
7192
7193 (define_insn_and_split "*lea_general_1_zext"
7194   [(set (match_operand:DI 0 "register_operand" "=r")
7195         (zero_extend:DI
7196           (plus:SI (plus:SI
7197                      (match_operand:SI 1 "index_register_operand" "l")
7198                      (match_operand:SI 2 "register_operand" "r"))
7199                    (match_operand:SI 3 "immediate_operand" "i"))))]
7200   "TARGET_64BIT"
7201   "#"
7202   "&& reload_completed"
7203   [(set (match_dup 0)
7204         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7205                                                      (match_dup 2))
7206                                             (match_dup 3)) 0)))]
7207 {
7208   operands[1] = gen_lowpart (Pmode, operands[1]);
7209   operands[2] = gen_lowpart (Pmode, operands[2]);
7210   operands[3] = gen_lowpart (Pmode, operands[3]);
7211 }
7212   [(set_attr "type" "lea")
7213    (set_attr "mode" "SI")])
7214
7215 (define_insn_and_split "*lea_general_2"
7216   [(set (match_operand 0 "register_operand" "=r")
7217         (plus (mult (match_operand 1 "index_register_operand" "l")
7218                     (match_operand 2 "const248_operand" "i"))
7219               (match_operand 3 "nonmemory_operand" "ri")))]
7220   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7221     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7222    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7223    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7224    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7225        || GET_MODE (operands[3]) == VOIDmode)"
7226   "#"
7227   "&& reload_completed"
7228   [(const_int 0)]
7229 {
7230   rtx pat;
7231   operands[0] = gen_lowpart (SImode, operands[0]);
7232   operands[1] = gen_lowpart (Pmode, operands[1]);
7233   operands[3] = gen_lowpart (Pmode, operands[3]);
7234   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7235                       operands[3]);
7236   if (Pmode != SImode)
7237     pat = gen_rtx_SUBREG (SImode, pat, 0);
7238   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7239   DONE;
7240 }
7241   [(set_attr "type" "lea")
7242    (set_attr "mode" "SI")])
7243
7244 (define_insn_and_split "*lea_general_2_zext"
7245   [(set (match_operand:DI 0 "register_operand" "=r")
7246         (zero_extend:DI
7247           (plus:SI (mult:SI
7248                      (match_operand:SI 1 "index_register_operand" "l")
7249                      (match_operand:SI 2 "const248_operand" "n"))
7250                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7251   "TARGET_64BIT"
7252   "#"
7253   "&& reload_completed"
7254   [(set (match_dup 0)
7255         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7256                                                      (match_dup 2))
7257                                             (match_dup 3)) 0)))]
7258 {
7259   operands[1] = gen_lowpart (Pmode, operands[1]);
7260   operands[3] = gen_lowpart (Pmode, operands[3]);
7261 }
7262   [(set_attr "type" "lea")
7263    (set_attr "mode" "SI")])
7264
7265 (define_insn_and_split "*lea_general_3"
7266   [(set (match_operand 0 "register_operand" "=r")
7267         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7268                           (match_operand 2 "const248_operand" "i"))
7269                     (match_operand 3 "register_operand" "r"))
7270               (match_operand 4 "immediate_operand" "i")))]
7271   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7272     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7273    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7274    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7275    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7276   "#"
7277   "&& reload_completed"
7278   [(const_int 0)]
7279 {
7280   rtx pat;
7281   operands[0] = gen_lowpart (SImode, operands[0]);
7282   operands[1] = gen_lowpart (Pmode, operands[1]);
7283   operands[3] = gen_lowpart (Pmode, operands[3]);
7284   operands[4] = gen_lowpart (Pmode, operands[4]);
7285   pat = gen_rtx_PLUS (Pmode,
7286                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7287                                                          operands[2]),
7288                                     operands[3]),
7289                       operands[4]);
7290   if (Pmode != SImode)
7291     pat = gen_rtx_SUBREG (SImode, pat, 0);
7292   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7293   DONE;
7294 }
7295   [(set_attr "type" "lea")
7296    (set_attr "mode" "SI")])
7297
7298 (define_insn_and_split "*lea_general_3_zext"
7299   [(set (match_operand:DI 0 "register_operand" "=r")
7300         (zero_extend:DI
7301           (plus:SI (plus:SI
7302                      (mult:SI
7303                        (match_operand:SI 1 "index_register_operand" "l")
7304                        (match_operand:SI 2 "const248_operand" "n"))
7305                      (match_operand:SI 3 "register_operand" "r"))
7306                    (match_operand:SI 4 "immediate_operand" "i"))))]
7307   "TARGET_64BIT"
7308   "#"
7309   "&& reload_completed"
7310   [(set (match_dup 0)
7311         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7312                                                               (match_dup 2))
7313                                                      (match_dup 3))
7314                                             (match_dup 4)) 0)))]
7315 {
7316   operands[1] = gen_lowpart (Pmode, operands[1]);
7317   operands[3] = gen_lowpart (Pmode, operands[3]);
7318   operands[4] = gen_lowpart (Pmode, operands[4]);
7319 }
7320   [(set_attr "type" "lea")
7321    (set_attr "mode" "SI")])
7322
7323 ;; Convert lea to the lea pattern to avoid flags dependency.
7324 (define_split
7325   [(set (match_operand:DI 0 "register_operand" "")
7326         (plus:DI (match_operand:DI 1 "register_operand" "")
7327                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7328    (clobber (reg:CC FLAGS_REG))]
7329   "TARGET_64BIT && reload_completed 
7330    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7331   [(set (match_dup 0)
7332         (plus:DI (match_dup 1)
7333                  (match_dup 2)))]
7334   "")
7335
7336 ;; Convert lea to the lea pattern to avoid flags dependency.
7337 (define_split
7338   [(set (match_operand 0 "register_operand" "")
7339         (plus (match_operand 1 "register_operand" "")
7340               (match_operand 2 "nonmemory_operand" "")))
7341    (clobber (reg:CC FLAGS_REG))]
7342   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7343   [(const_int 0)]
7344 {
7345   rtx pat;
7346   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7347      may confuse gen_lowpart.  */
7348   if (GET_MODE (operands[0]) != Pmode)
7349     {
7350       operands[1] = gen_lowpart (Pmode, operands[1]);
7351       operands[2] = gen_lowpart (Pmode, operands[2]);
7352     }
7353   operands[0] = gen_lowpart (SImode, operands[0]);
7354   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7355   if (Pmode != SImode)
7356     pat = gen_rtx_SUBREG (SImode, pat, 0);
7357   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7358   DONE;
7359 })
7360
7361 ;; Convert lea to the lea pattern to avoid flags dependency.
7362 (define_split
7363   [(set (match_operand:DI 0 "register_operand" "")
7364         (zero_extend:DI
7365           (plus:SI (match_operand:SI 1 "register_operand" "")
7366                    (match_operand:SI 2 "nonmemory_operand" ""))))
7367    (clobber (reg:CC FLAGS_REG))]
7368   "TARGET_64BIT && reload_completed
7369    && true_regnum (operands[0]) != true_regnum (operands[1])"
7370   [(set (match_dup 0)
7371         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7372 {
7373   operands[1] = gen_lowpart (Pmode, operands[1]);
7374   operands[2] = gen_lowpart (Pmode, operands[2]);
7375 })
7376 \f
7377 ;; Subtract instructions
7378
7379 (define_expand "sub<mode>3"
7380   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7381         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7382                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7383   ""
7384   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7385
7386 (define_insn_and_split "*sub<dwi>3_doubleword"
7387   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7388         (minus:<DWI>
7389           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7390           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7393   "#"
7394   "reload_completed"
7395   [(parallel [(set (reg:CC FLAGS_REG)
7396                    (compare:CC (match_dup 1) (match_dup 2)))
7397               (set (match_dup 0)
7398                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7399    (parallel [(set (match_dup 3)
7400                    (minus:DWIH
7401                      (match_dup 4)
7402                      (plus:DWIH
7403                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7404                        (match_dup 5))))
7405               (clobber (reg:CC FLAGS_REG))])]
7406   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7407
7408 (define_insn "*sub<mode>_1"
7409   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7410         (minus:SWI
7411           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7412           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7413    (clobber (reg:CC FLAGS_REG))]
7414   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7415   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7416   [(set_attr "type" "alu")
7417    (set_attr "mode" "<MODE>")])
7418
7419 (define_insn "*subsi_1_zext"
7420   [(set (match_operand:DI 0 "register_operand" "=r")
7421         (zero_extend:DI
7422           (minus:SI (match_operand:SI 1 "register_operand" "0")
7423                     (match_operand:SI 2 "general_operand" "g"))))
7424    (clobber (reg:CC FLAGS_REG))]
7425   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7426   "sub{l}\t{%2, %k0|%k0, %2}"
7427   [(set_attr "type" "alu")
7428    (set_attr "mode" "SI")])
7429
7430 (define_insn "*subqi_1_slp"
7431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7432         (minus:QI (match_dup 0)
7433                   (match_operand:QI 1 "general_operand" "qn,qm")))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7436    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7437   "sub{b}\t{%1, %0|%0, %1}"
7438   [(set_attr "type" "alu1")
7439    (set_attr "mode" "QI")])
7440
7441 (define_insn "*sub<mode>_2"
7442   [(set (reg FLAGS_REG)
7443         (compare
7444           (minus:SWI
7445             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7446             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7447           (const_int 0)))
7448    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7449         (minus:SWI (match_dup 1) (match_dup 2)))]
7450   "ix86_match_ccmode (insn, CCGOCmode)
7451    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7452   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7453   [(set_attr "type" "alu")
7454    (set_attr "mode" "<MODE>")])
7455
7456 (define_insn "*subsi_2_zext"
7457   [(set (reg FLAGS_REG)
7458         (compare
7459           (minus:SI (match_operand:SI 1 "register_operand" "0")
7460                     (match_operand:SI 2 "general_operand" "g"))
7461           (const_int 0)))
7462    (set (match_operand:DI 0 "register_operand" "=r")
7463         (zero_extend:DI
7464           (minus:SI (match_dup 1)
7465                     (match_dup 2))))]
7466   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7467    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7468   "sub{l}\t{%2, %k0|%k0, %2}"
7469   [(set_attr "type" "alu")
7470    (set_attr "mode" "SI")])
7471
7472 (define_insn "*sub<mode>_3"
7473   [(set (reg FLAGS_REG)
7474         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7475                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7476    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7477         (minus:SWI (match_dup 1) (match_dup 2)))]
7478   "ix86_match_ccmode (insn, CCmode)
7479    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7480   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7481   [(set_attr "type" "alu")
7482    (set_attr "mode" "<MODE>")])
7483
7484 (define_insn "*subsi_3_zext"
7485   [(set (reg FLAGS_REG)
7486         (compare (match_operand:SI 1 "register_operand" "0")
7487                  (match_operand:SI 2 "general_operand" "g")))
7488    (set (match_operand:DI 0 "register_operand" "=r")
7489         (zero_extend:DI
7490           (minus:SI (match_dup 1)
7491                     (match_dup 2))))]
7492   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7493    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7494   "sub{l}\t{%2, %1|%1, %2}"
7495   [(set_attr "type" "alu")
7496    (set_attr "mode" "SI")])
7497 \f
7498 ;; Add with carry and subtract with borrow
7499
7500 (define_expand "<plusminus_insn><mode>3_carry"
7501   [(parallel
7502     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7503           (plusminus:SWI
7504             (match_operand:SWI 1 "nonimmediate_operand" "")
7505             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7506                        [(match_operand 3 "flags_reg_operand" "")
7507                         (const_int 0)])
7508                       (match_operand:SWI 2 "<general_operand>" ""))))
7509      (clobber (reg:CC FLAGS_REG))])]
7510   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7511   "")
7512
7513 (define_insn "*<plusminus_insn><mode>3_carry"
7514   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7515         (plusminus:SWI
7516           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7517           (plus:SWI
7518             (match_operator 3 "ix86_carry_flag_operator"
7519              [(reg FLAGS_REG) (const_int 0)])
7520             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7521    (clobber (reg:CC FLAGS_REG))]
7522   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7523   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7524   [(set_attr "type" "alu")
7525    (set_attr "use_carry" "1")
7526    (set_attr "pent_pair" "pu")
7527    (set_attr "mode" "<MODE>")])
7528
7529 (define_insn "*addsi3_carry_zext"
7530   [(set (match_operand:DI 0 "register_operand" "=r")
7531         (zero_extend:DI
7532           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7533                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7534                              [(reg FLAGS_REG) (const_int 0)])
7535                             (match_operand:SI 2 "general_operand" "g")))))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7538   "adc{l}\t{%2, %k0|%k0, %2}"
7539   [(set_attr "type" "alu")
7540    (set_attr "use_carry" "1")
7541    (set_attr "pent_pair" "pu")
7542    (set_attr "mode" "SI")])
7543
7544 (define_insn "*subsi3_carry_zext"
7545   [(set (match_operand:DI 0 "register_operand" "=r")
7546         (zero_extend:DI
7547           (minus:SI (match_operand:SI 1 "register_operand" "0")
7548                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7549                               [(reg FLAGS_REG) (const_int 0)])
7550                              (match_operand:SI 2 "general_operand" "g")))))
7551    (clobber (reg:CC FLAGS_REG))]
7552   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7553   "sbb{l}\t{%2, %k0|%k0, %2}"
7554   [(set_attr "type" "alu")
7555    (set_attr "pent_pair" "pu")
7556    (set_attr "mode" "SI")])
7557 \f
7558 ;; Overflow setting add and subtract instructions
7559
7560 (define_insn "*add<mode>3_cconly_overflow"
7561   [(set (reg:CCC FLAGS_REG)
7562         (compare:CCC
7563           (plus:SWI
7564             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7565             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7566           (match_dup 1)))
7567    (clobber (match_scratch:SWI 0 "=<r>"))]
7568   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7569   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7570   [(set_attr "type" "alu")
7571    (set_attr "mode" "<MODE>")])
7572
7573 (define_insn "*sub<mode>3_cconly_overflow"
7574   [(set (reg:CCC FLAGS_REG)
7575         (compare:CCC
7576           (minus:SWI
7577             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7578             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7579           (match_dup 0)))]
7580   ""
7581   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7582   [(set_attr "type" "icmp")
7583    (set_attr "mode" "<MODE>")])
7584
7585 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7586   [(set (reg:CCC FLAGS_REG)
7587         (compare:CCC
7588             (plusminus:SWI
7589                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7590                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7591             (match_dup 1)))
7592    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7593         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7594   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7595   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7596   [(set_attr "type" "alu")
7597    (set_attr "mode" "<MODE>")])
7598
7599 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7600   [(set (reg:CCC FLAGS_REG)
7601         (compare:CCC
7602           (plusminus:SI
7603             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7604             (match_operand:SI 2 "general_operand" "g"))
7605           (match_dup 1)))
7606    (set (match_operand:DI 0 "register_operand" "=r")
7607         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7608   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7609   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7610   [(set_attr "type" "alu")
7611    (set_attr "mode" "SI")])
7612
7613 ;; The patterns that match these are at the end of this file.
7614
7615 (define_expand "<plusminus_insn>xf3"
7616   [(set (match_operand:XF 0 "register_operand" "")
7617         (plusminus:XF
7618           (match_operand:XF 1 "register_operand" "")
7619           (match_operand:XF 2 "register_operand" "")))]
7620   "TARGET_80387"
7621   "")
7622
7623 (define_expand "<plusminus_insn><mode>3"
7624   [(set (match_operand:MODEF 0 "register_operand" "")
7625         (plusminus:MODEF
7626           (match_operand:MODEF 1 "register_operand" "")
7627           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7628   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7629     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7630   "")
7631 \f
7632 ;; Multiply instructions
7633
7634 (define_expand "mul<mode>3"
7635   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7636                    (mult:SWIM248
7637                      (match_operand:SWIM248 1 "register_operand" "")
7638                      (match_operand:SWIM248 2 "<general_operand>" "")))
7639               (clobber (reg:CC FLAGS_REG))])]
7640   ""
7641   "")
7642
7643 (define_expand "mulqi3"
7644   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7645                    (mult:QI
7646                      (match_operand:QI 1 "register_operand" "")
7647                      (match_operand:QI 2 "nonimmediate_operand" "")))
7648               (clobber (reg:CC FLAGS_REG))])]
7649   "TARGET_QIMODE_MATH"
7650   "")
7651
7652 ;; On AMDFAM10
7653 ;; IMUL reg32/64, reg32/64, imm8        Direct
7654 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7655 ;; IMUL reg32/64, reg32/64, imm32       Direct
7656 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7657 ;; IMUL reg32/64, reg32/64              Direct
7658 ;; IMUL reg32/64, mem32/64              Direct
7659
7660 (define_insn "*mul<mode>3_1"
7661   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7662         (mult:SWI48
7663           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7664           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7665    (clobber (reg:CC FLAGS_REG))]
7666   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7667   "@
7668    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7669    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7670    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7671   [(set_attr "type" "imul")
7672    (set_attr "prefix_0f" "0,0,1")
7673    (set (attr "athlon_decode")
7674         (cond [(eq_attr "cpu" "athlon")
7675                   (const_string "vector")
7676                (eq_attr "alternative" "1")
7677                   (const_string "vector")
7678                (and (eq_attr "alternative" "2")
7679                     (match_operand 1 "memory_operand" ""))
7680                   (const_string "vector")]
7681               (const_string "direct")))
7682    (set (attr "amdfam10_decode")
7683         (cond [(and (eq_attr "alternative" "0,1")
7684                     (match_operand 1 "memory_operand" ""))
7685                   (const_string "vector")]
7686               (const_string "direct")))
7687    (set_attr "mode" "<MODE>")])
7688
7689 (define_insn "*mulsi3_1_zext"
7690   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7691         (zero_extend:DI
7692           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7693                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7694    (clobber (reg:CC FLAGS_REG))]
7695   "TARGET_64BIT
7696    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7697   "@
7698    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7699    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7700    imul{l}\t{%2, %k0|%k0, %2}"
7701   [(set_attr "type" "imul")
7702    (set_attr "prefix_0f" "0,0,1")
7703    (set (attr "athlon_decode")
7704         (cond [(eq_attr "cpu" "athlon")
7705                   (const_string "vector")
7706                (eq_attr "alternative" "1")
7707                   (const_string "vector")
7708                (and (eq_attr "alternative" "2")
7709                     (match_operand 1 "memory_operand" ""))
7710                   (const_string "vector")]
7711               (const_string "direct")))
7712    (set (attr "amdfam10_decode")
7713         (cond [(and (eq_attr "alternative" "0,1")
7714                     (match_operand 1 "memory_operand" ""))
7715                   (const_string "vector")]
7716               (const_string "direct")))
7717    (set_attr "mode" "SI")])
7718
7719 ;; On AMDFAM10
7720 ;; IMUL reg16, reg16, imm8      VectorPath
7721 ;; IMUL reg16, mem16, imm8      VectorPath
7722 ;; IMUL reg16, reg16, imm16     VectorPath
7723 ;; IMUL reg16, mem16, imm16     VectorPath
7724 ;; IMUL reg16, reg16            Direct
7725 ;; IMUL reg16, mem16            Direct
7726
7727 (define_insn "*mulhi3_1"
7728   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7729         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7730                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7731    (clobber (reg:CC FLAGS_REG))]
7732   "TARGET_HIMODE_MATH
7733    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7734   "@
7735    imul{w}\t{%2, %1, %0|%0, %1, %2}
7736    imul{w}\t{%2, %1, %0|%0, %1, %2}
7737    imul{w}\t{%2, %0|%0, %2}"
7738   [(set_attr "type" "imul")
7739    (set_attr "prefix_0f" "0,0,1")
7740    (set (attr "athlon_decode")
7741         (cond [(eq_attr "cpu" "athlon")
7742                   (const_string "vector")
7743                (eq_attr "alternative" "1,2")
7744                   (const_string "vector")]
7745               (const_string "direct")))
7746    (set (attr "amdfam10_decode")
7747         (cond [(eq_attr "alternative" "0,1")
7748                   (const_string "vector")]
7749               (const_string "direct")))
7750    (set_attr "mode" "HI")])
7751
7752 ;;On AMDFAM10
7753 ;; MUL reg8     Direct
7754 ;; MUL mem8     Direct
7755
7756 (define_insn "*mulqi3_1"
7757   [(set (match_operand:QI 0 "register_operand" "=a")
7758         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7759                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "TARGET_QIMODE_MATH
7762    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7763   "mul{b}\t%2"
7764   [(set_attr "type" "imul")
7765    (set_attr "length_immediate" "0")
7766    (set (attr "athlon_decode")
7767      (if_then_else (eq_attr "cpu" "athlon")
7768         (const_string "vector")
7769         (const_string "direct")))
7770    (set_attr "amdfam10_decode" "direct")
7771    (set_attr "mode" "QI")])
7772
7773 (define_expand "<u>mul<mode><dwi>3"
7774   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7775                    (mult:<DWI>
7776                      (any_extend:<DWI>
7777                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7778                      (any_extend:<DWI>
7779                        (match_operand:DWIH 2 "register_operand" ""))))
7780               (clobber (reg:CC FLAGS_REG))])]
7781   ""
7782   "")
7783
7784 (define_expand "<u>mulqihi3"
7785   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7786                    (mult:HI
7787                      (any_extend:HI
7788                        (match_operand:QI 1 "nonimmediate_operand" ""))
7789                      (any_extend:HI
7790                        (match_operand:QI 2 "register_operand" ""))))
7791               (clobber (reg:CC FLAGS_REG))])]
7792   "TARGET_QIMODE_MATH"
7793   "")
7794
7795 (define_insn "*<u>mul<mode><dwi>3_1"
7796   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7797         (mult:<DWI>
7798           (any_extend:<DWI>
7799             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7800           (any_extend:<DWI>
7801             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7802    (clobber (reg:CC FLAGS_REG))]
7803   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7804   "<sgnprefix>mul{<imodesuffix>}\t%2"
7805   [(set_attr "type" "imul")
7806    (set_attr "length_immediate" "0")
7807    (set (attr "athlon_decode")
7808      (if_then_else (eq_attr "cpu" "athlon")
7809         (const_string "vector")
7810         (const_string "double")))
7811    (set_attr "amdfam10_decode" "double")
7812    (set_attr "mode" "<MODE>")])
7813
7814 (define_insn "*<u>mulqihi3_1"
7815   [(set (match_operand:HI 0 "register_operand" "=a")
7816         (mult:HI
7817           (any_extend:HI
7818             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7819           (any_extend:HI
7820             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7821    (clobber (reg:CC FLAGS_REG))]
7822   "TARGET_QIMODE_MATH
7823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7824   "<sgnprefix>mul{b}\t%2"
7825   [(set_attr "type" "imul")
7826    (set_attr "length_immediate" "0")
7827    (set (attr "athlon_decode")
7828      (if_then_else (eq_attr "cpu" "athlon")
7829         (const_string "vector")
7830         (const_string "direct")))
7831    (set_attr "amdfam10_decode" "direct")
7832    (set_attr "mode" "QI")])
7833
7834 (define_expand "<s>mul<mode>3_highpart"
7835   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7836                    (truncate:SWI48
7837                      (lshiftrt:<DWI>
7838                        (mult:<DWI>
7839                          (any_extend:<DWI>
7840                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7841                          (any_extend:<DWI>
7842                            (match_operand:SWI48 2 "register_operand" "")))
7843                        (match_dup 4))))
7844               (clobber (match_scratch:SWI48 3 ""))
7845               (clobber (reg:CC FLAGS_REG))])]
7846   ""
7847   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7848
7849 (define_insn "*<s>muldi3_highpart_1"
7850   [(set (match_operand:DI 0 "register_operand" "=d")
7851         (truncate:DI
7852           (lshiftrt:TI
7853             (mult:TI
7854               (any_extend:TI
7855                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7856               (any_extend:TI
7857                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7858             (const_int 64))))
7859    (clobber (match_scratch:DI 3 "=1"))
7860    (clobber (reg:CC FLAGS_REG))]
7861   "TARGET_64BIT
7862    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7863   "<sgnprefix>mul{q}\t%2"
7864   [(set_attr "type" "imul")
7865    (set_attr "length_immediate" "0")
7866    (set (attr "athlon_decode")
7867      (if_then_else (eq_attr "cpu" "athlon")
7868         (const_string "vector")
7869         (const_string "double")))
7870    (set_attr "amdfam10_decode" "double")
7871    (set_attr "mode" "DI")])
7872
7873 (define_insn "*<s>mulsi3_highpart_1"
7874   [(set (match_operand:SI 0 "register_operand" "=d")
7875         (truncate:SI
7876           (lshiftrt:DI
7877             (mult:DI
7878               (any_extend:DI
7879                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7880               (any_extend:DI
7881                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7882             (const_int 32))))
7883    (clobber (match_scratch:SI 3 "=1"))
7884    (clobber (reg:CC FLAGS_REG))]
7885   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7886   "<sgnprefix>mul{l}\t%2"
7887   [(set_attr "type" "imul")
7888    (set_attr "length_immediate" "0")
7889    (set (attr "athlon_decode")
7890      (if_then_else (eq_attr "cpu" "athlon")
7891         (const_string "vector")
7892         (const_string "double")))
7893    (set_attr "amdfam10_decode" "double")
7894    (set_attr "mode" "SI")])
7895
7896 (define_insn "*<s>mulsi3_highpart_zext"
7897   [(set (match_operand:DI 0 "register_operand" "=d")
7898         (zero_extend:DI (truncate:SI
7899           (lshiftrt:DI
7900             (mult:DI (any_extend:DI
7901                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7902                      (any_extend:DI
7903                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7904             (const_int 32)))))
7905    (clobber (match_scratch:SI 3 "=1"))
7906    (clobber (reg:CC FLAGS_REG))]
7907   "TARGET_64BIT
7908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7909   "<sgnprefix>mul{l}\t%2"
7910   [(set_attr "type" "imul")
7911    (set_attr "length_immediate" "0")
7912    (set (attr "athlon_decode")
7913      (if_then_else (eq_attr "cpu" "athlon")
7914         (const_string "vector")
7915         (const_string "double")))
7916    (set_attr "amdfam10_decode" "double")
7917    (set_attr "mode" "SI")])
7918
7919 ;; The patterns that match these are at the end of this file.
7920
7921 (define_expand "mulxf3"
7922   [(set (match_operand:XF 0 "register_operand" "")
7923         (mult:XF (match_operand:XF 1 "register_operand" "")
7924                  (match_operand:XF 2 "register_operand" "")))]
7925   "TARGET_80387"
7926   "")
7927
7928 (define_expand "mul<mode>3"
7929   [(set (match_operand:MODEF 0 "register_operand" "")
7930         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7931                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7932   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7933     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7934   "")
7935 \f
7936 ;; Divide instructions
7937
7938 (define_insn "<u>divqi3"
7939   [(set (match_operand:QI 0 "register_operand" "=a")
7940         (any_div:QI
7941           (match_operand:HI 1 "register_operand" "0")
7942           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7943    (clobber (reg:CC FLAGS_REG))]
7944   "TARGET_QIMODE_MATH"
7945   "<sgnprefix>div{b}\t%2"
7946   [(set_attr "type" "idiv")
7947    (set_attr "mode" "QI")])
7948
7949 ;; The patterns that match these are at the end of this file.
7950
7951 (define_expand "divxf3"
7952   [(set (match_operand:XF 0 "register_operand" "")
7953         (div:XF (match_operand:XF 1 "register_operand" "")
7954                 (match_operand:XF 2 "register_operand" "")))]
7955   "TARGET_80387"
7956   "")
7957
7958 (define_expand "divdf3"
7959   [(set (match_operand:DF 0 "register_operand" "")
7960         (div:DF (match_operand:DF 1 "register_operand" "")
7961                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7962    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7963     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7964    "")
7965
7966 (define_expand "divsf3"
7967   [(set (match_operand:SF 0 "register_operand" "")
7968         (div:SF (match_operand:SF 1 "register_operand" "")
7969                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7970   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7971     || TARGET_SSE_MATH"
7972 {
7973   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7974       && flag_finite_math_only && !flag_trapping_math
7975       && flag_unsafe_math_optimizations)
7976     {
7977       ix86_emit_swdivsf (operands[0], operands[1],
7978                          operands[2], SFmode);
7979       DONE;
7980     }
7981 })
7982 \f
7983 ;; Divmod instructions.
7984
7985 (define_expand "divmod<mode>4"
7986   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7987                    (div:SWIM248
7988                      (match_operand:SWIM248 1 "register_operand" "")
7989                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7990               (set (match_operand:SWIM248 3 "register_operand" "")
7991                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7992               (clobber (reg:CC FLAGS_REG))])]
7993   ""
7994   "")
7995
7996 (define_insn_and_split "*divmod<mode>4"
7997   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7998         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7999                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8000    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8001         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8002    (clobber (reg:CC FLAGS_REG))]
8003   ""
8004   "#"
8005   "&& reload_completed"
8006   [(parallel [(set (match_dup 1)
8007                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8008               (clobber (reg:CC FLAGS_REG))])
8009    (parallel [(set (match_dup 0)
8010                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8011               (set (match_dup 1)
8012                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8013               (use (match_dup 1))
8014               (clobber (reg:CC FLAGS_REG))])]
8015 {
8016   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8017
8018   if (<MODE>mode != HImode
8019       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8020     operands[4] = operands[2];
8021   else
8022     {
8023       /* Avoid use of cltd in favor of a mov+shift.  */
8024       emit_move_insn (operands[1], operands[2]);
8025       operands[4] = operands[1];
8026     }
8027 }
8028   [(set_attr "type" "multi")
8029    (set_attr "mode" "<MODE>")])
8030
8031 (define_insn "*divmod<mode>4_noext"
8032   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8033         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8034                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8035    (set (match_operand:SWIM248 1 "register_operand" "=d")
8036         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8037    (use (match_operand:SWIM248 4 "register_operand" "1"))
8038    (clobber (reg:CC FLAGS_REG))]
8039   ""
8040   "idiv{<imodesuffix>}\t%3"
8041   [(set_attr "type" "idiv")
8042    (set_attr "mode" "<MODE>")])
8043
8044 (define_expand "udivmod<mode>4"
8045   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8046                    (udiv:SWIM248
8047                      (match_operand:SWIM248 1 "register_operand" "")
8048                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8049               (set (match_operand:SWIM248 3 "register_operand" "")
8050                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8051               (clobber (reg:CC FLAGS_REG))])]
8052   ""
8053   "")
8054
8055 (define_insn_and_split "*udivmod<mode>4"
8056   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8057         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8058                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8059    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8060         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8061    (clobber (reg:CC FLAGS_REG))]
8062   ""
8063   "#"
8064   "&& reload_completed"
8065   [(set (match_dup 1) (const_int 0))
8066    (parallel [(set (match_dup 0)
8067                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8068               (set (match_dup 1)
8069                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8070               (use (match_dup 1))
8071               (clobber (reg:CC FLAGS_REG))])]
8072   ""
8073   [(set_attr "type" "multi")
8074    (set_attr "mode" "<MODE>")])
8075
8076 (define_insn "*udivmod<mode>4_noext"
8077   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8078         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8079                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8080    (set (match_operand:SWIM248 1 "register_operand" "=d")
8081         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8082    (use (match_operand:SWIM248 4 "register_operand" "1"))
8083    (clobber (reg:CC FLAGS_REG))]
8084   ""
8085   "div{<imodesuffix>}\t%3"
8086   [(set_attr "type" "idiv")
8087    (set_attr "mode" "<MODE>")])
8088
8089 ;; We cannot use div/idiv for double division, because it causes
8090 ;; "division by zero" on the overflow and that's not what we expect
8091 ;; from truncate.  Because true (non truncating) double division is
8092 ;; never generated, we can't create this insn anyway.
8093 ;
8094 ;(define_insn ""
8095 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8096 ;       (truncate:SI
8097 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8098 ;                  (zero_extend:DI
8099 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8100 ;   (set (match_operand:SI 3 "register_operand" "=d")
8101 ;       (truncate:SI
8102 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8103 ;   (clobber (reg:CC FLAGS_REG))]
8104 ;  ""
8105 ;  "div{l}\t{%2, %0|%0, %2}"
8106 ;  [(set_attr "type" "idiv")])
8107 \f
8108 ;;- Logical AND instructions
8109
8110 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8111 ;; Note that this excludes ah.
8112
8113 (define_insn "*testdi_1_rex64"
8114   [(set (reg FLAGS_REG)
8115         (compare
8116           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8117                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8118           (const_int 0)))]
8119   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8120    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8121   "@
8122    test{l}\t{%k1, %k0|%k0, %k1}
8123    test{l}\t{%k1, %k0|%k0, %k1}
8124    test{q}\t{%1, %0|%0, %1}
8125    test{q}\t{%1, %0|%0, %1}
8126    test{q}\t{%1, %0|%0, %1}"
8127   [(set_attr "type" "test")
8128    (set_attr "modrm" "0,1,0,1,1")
8129    (set_attr "mode" "SI,SI,DI,DI,DI")
8130    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8131
8132 (define_insn "testsi_1"
8133   [(set (reg FLAGS_REG)
8134         (compare
8135           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8136                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8137           (const_int 0)))]
8138   "ix86_match_ccmode (insn, CCNOmode)
8139    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8140   "test{l}\t{%1, %0|%0, %1}"
8141   [(set_attr "type" "test")
8142    (set_attr "modrm" "0,1,1")
8143    (set_attr "mode" "SI")
8144    (set_attr "pent_pair" "uv,np,uv")])
8145
8146 (define_expand "testsi_ccno_1"
8147   [(set (reg:CCNO FLAGS_REG)
8148         (compare:CCNO
8149           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8150                   (match_operand:SI 1 "nonmemory_operand" ""))
8151           (const_int 0)))]
8152   ""
8153   "")
8154
8155 (define_insn "*testhi_1"
8156   [(set (reg FLAGS_REG)
8157         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8158                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8159                  (const_int 0)))]
8160   "ix86_match_ccmode (insn, CCNOmode)
8161    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8162   "test{w}\t{%1, %0|%0, %1}"
8163   [(set_attr "type" "test")
8164    (set_attr "modrm" "0,1,1")
8165    (set_attr "mode" "HI")
8166    (set_attr "pent_pair" "uv,np,uv")])
8167
8168 (define_expand "testqi_ccz_1"
8169   [(set (reg:CCZ FLAGS_REG)
8170         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8171                              (match_operand:QI 1 "nonmemory_operand" ""))
8172                  (const_int 0)))]
8173   ""
8174   "")
8175
8176 (define_insn "*testqi_1_maybe_si"
8177   [(set (reg FLAGS_REG)
8178         (compare
8179           (and:QI
8180             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8181             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8182           (const_int 0)))]
8183    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8184     && ix86_match_ccmode (insn,
8185                          CONST_INT_P (operands[1])
8186                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8187 {
8188   if (which_alternative == 3)
8189     {
8190       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8191         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8192       return "test{l}\t{%1, %k0|%k0, %1}";
8193     }
8194   return "test{b}\t{%1, %0|%0, %1}";
8195 }
8196   [(set_attr "type" "test")
8197    (set_attr "modrm" "0,1,1,1")
8198    (set_attr "mode" "QI,QI,QI,SI")
8199    (set_attr "pent_pair" "uv,np,uv,np")])
8200
8201 (define_insn "*testqi_1"
8202   [(set (reg FLAGS_REG)
8203         (compare
8204           (and:QI
8205             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8206             (match_operand:QI 1 "general_operand" "n,n,qn"))
8207           (const_int 0)))]
8208   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8209    && ix86_match_ccmode (insn, CCNOmode)"
8210   "test{b}\t{%1, %0|%0, %1}"
8211   [(set_attr "type" "test")
8212    (set_attr "modrm" "0,1,1")
8213    (set_attr "mode" "QI")
8214    (set_attr "pent_pair" "uv,np,uv")])
8215
8216 (define_expand "testqi_ext_ccno_0"
8217   [(set (reg:CCNO FLAGS_REG)
8218         (compare:CCNO
8219           (and:SI
8220             (zero_extract:SI
8221               (match_operand 0 "ext_register_operand" "")
8222               (const_int 8)
8223               (const_int 8))
8224             (match_operand 1 "const_int_operand" ""))
8225           (const_int 0)))]
8226   ""
8227   "")
8228
8229 (define_insn "*testqi_ext_0"
8230   [(set (reg FLAGS_REG)
8231         (compare
8232           (and:SI
8233             (zero_extract:SI
8234               (match_operand 0 "ext_register_operand" "Q")
8235               (const_int 8)
8236               (const_int 8))
8237             (match_operand 1 "const_int_operand" "n"))
8238           (const_int 0)))]
8239   "ix86_match_ccmode (insn, CCNOmode)"
8240   "test{b}\t{%1, %h0|%h0, %1}"
8241   [(set_attr "type" "test")
8242    (set_attr "mode" "QI")
8243    (set_attr "length_immediate" "1")
8244    (set_attr "modrm" "1")
8245    (set_attr "pent_pair" "np")])
8246
8247 (define_insn "*testqi_ext_1"
8248   [(set (reg FLAGS_REG)
8249         (compare
8250           (and:SI
8251             (zero_extract:SI
8252               (match_operand 0 "ext_register_operand" "Q")
8253               (const_int 8)
8254               (const_int 8))
8255             (zero_extend:SI
8256               (match_operand:QI 1 "general_operand" "Qm")))
8257           (const_int 0)))]
8258   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8259    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8260   "test{b}\t{%1, %h0|%h0, %1}"
8261   [(set_attr "type" "test")
8262    (set_attr "mode" "QI")])
8263
8264 (define_insn "*testqi_ext_1_rex64"
8265   [(set (reg FLAGS_REG)
8266         (compare
8267           (and:SI
8268             (zero_extract:SI
8269               (match_operand 0 "ext_register_operand" "Q")
8270               (const_int 8)
8271               (const_int 8))
8272             (zero_extend:SI
8273               (match_operand:QI 1 "register_operand" "Q")))
8274           (const_int 0)))]
8275   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8276   "test{b}\t{%1, %h0|%h0, %1}"
8277   [(set_attr "type" "test")
8278    (set_attr "mode" "QI")])
8279
8280 (define_insn "*testqi_ext_2"
8281   [(set (reg FLAGS_REG)
8282         (compare
8283           (and:SI
8284             (zero_extract:SI
8285               (match_operand 0 "ext_register_operand" "Q")
8286               (const_int 8)
8287               (const_int 8))
8288             (zero_extract:SI
8289               (match_operand 1 "ext_register_operand" "Q")
8290               (const_int 8)
8291               (const_int 8)))
8292           (const_int 0)))]
8293   "ix86_match_ccmode (insn, CCNOmode)"
8294   "test{b}\t{%h1, %h0|%h0, %h1}"
8295   [(set_attr "type" "test")
8296    (set_attr "mode" "QI")])
8297
8298 ;; Combine likes to form bit extractions for some tests.  Humor it.
8299 (define_insn "*testqi_ext_3"
8300   [(set (reg FLAGS_REG)
8301         (compare (zero_extract:SI
8302                    (match_operand 0 "nonimmediate_operand" "rm")
8303                    (match_operand:SI 1 "const_int_operand" "")
8304                    (match_operand:SI 2 "const_int_operand" ""))
8305                  (const_int 0)))]
8306   "ix86_match_ccmode (insn, CCNOmode)
8307    && INTVAL (operands[1]) > 0
8308    && INTVAL (operands[2]) >= 0
8309    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8310    && (GET_MODE (operands[0]) == SImode
8311        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8312        || GET_MODE (operands[0]) == HImode
8313        || GET_MODE (operands[0]) == QImode)"
8314   "#")
8315
8316 (define_insn "*testqi_ext_3_rex64"
8317   [(set (reg FLAGS_REG)
8318         (compare (zero_extract:DI
8319                    (match_operand 0 "nonimmediate_operand" "rm")
8320                    (match_operand:DI 1 "const_int_operand" "")
8321                    (match_operand:DI 2 "const_int_operand" ""))
8322                  (const_int 0)))]
8323   "TARGET_64BIT
8324    && ix86_match_ccmode (insn, CCNOmode)
8325    && INTVAL (operands[1]) > 0
8326    && INTVAL (operands[2]) >= 0
8327    /* Ensure that resulting mask is zero or sign extended operand.  */
8328    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8329        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8330            && INTVAL (operands[1]) > 32))
8331    && (GET_MODE (operands[0]) == SImode
8332        || GET_MODE (operands[0]) == DImode
8333        || GET_MODE (operands[0]) == HImode
8334        || GET_MODE (operands[0]) == QImode)"
8335   "#")
8336
8337 (define_split
8338   [(set (match_operand 0 "flags_reg_operand" "")
8339         (match_operator 1 "compare_operator"
8340           [(zero_extract
8341              (match_operand 2 "nonimmediate_operand" "")
8342              (match_operand 3 "const_int_operand" "")
8343              (match_operand 4 "const_int_operand" ""))
8344            (const_int 0)]))]
8345   "ix86_match_ccmode (insn, CCNOmode)"
8346   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8347 {
8348   rtx val = operands[2];
8349   HOST_WIDE_INT len = INTVAL (operands[3]);
8350   HOST_WIDE_INT pos = INTVAL (operands[4]);
8351   HOST_WIDE_INT mask;
8352   enum machine_mode mode, submode;
8353
8354   mode = GET_MODE (val);
8355   if (MEM_P (val))
8356     {
8357       /* ??? Combine likes to put non-volatile mem extractions in QImode
8358          no matter the size of the test.  So find a mode that works.  */
8359       if (! MEM_VOLATILE_P (val))
8360         {
8361           mode = smallest_mode_for_size (pos + len, MODE_INT);
8362           val = adjust_address (val, mode, 0);
8363         }
8364     }
8365   else if (GET_CODE (val) == SUBREG
8366            && (submode = GET_MODE (SUBREG_REG (val)),
8367                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8368            && pos + len <= GET_MODE_BITSIZE (submode)
8369            && GET_MODE_CLASS (submode) == MODE_INT)
8370     {
8371       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8372       mode = submode;
8373       val = SUBREG_REG (val);
8374     }
8375   else if (mode == HImode && pos + len <= 8)
8376     {
8377       /* Small HImode tests can be converted to QImode.  */
8378       mode = QImode;
8379       val = gen_lowpart (QImode, val);
8380     }
8381
8382   if (len == HOST_BITS_PER_WIDE_INT)
8383     mask = -1;
8384   else
8385     mask = ((HOST_WIDE_INT)1 << len) - 1;
8386   mask <<= pos;
8387
8388   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8389 })
8390
8391 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8392 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8393 ;; this is relatively important trick.
8394 ;; Do the conversion only post-reload to avoid limiting of the register class
8395 ;; to QI regs.
8396 (define_split
8397   [(set (match_operand 0 "flags_reg_operand" "")
8398         (match_operator 1 "compare_operator"
8399           [(and (match_operand 2 "register_operand" "")
8400                 (match_operand 3 "const_int_operand" ""))
8401            (const_int 0)]))]
8402    "reload_completed
8403     && QI_REG_P (operands[2])
8404     && GET_MODE (operands[2]) != QImode
8405     && ((ix86_match_ccmode (insn, CCZmode)
8406          && !(INTVAL (operands[3]) & ~(255 << 8)))
8407         || (ix86_match_ccmode (insn, CCNOmode)
8408             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8409   [(set (match_dup 0)
8410         (match_op_dup 1
8411           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8412                    (match_dup 3))
8413            (const_int 0)]))]
8414   "operands[2] = gen_lowpart (SImode, operands[2]);
8415    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8416
8417 (define_split
8418   [(set (match_operand 0 "flags_reg_operand" "")
8419         (match_operator 1 "compare_operator"
8420           [(and (match_operand 2 "nonimmediate_operand" "")
8421                 (match_operand 3 "const_int_operand" ""))
8422            (const_int 0)]))]
8423    "reload_completed
8424     && GET_MODE (operands[2]) != QImode
8425     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8426     && ((ix86_match_ccmode (insn, CCZmode)
8427          && !(INTVAL (operands[3]) & ~255))
8428         || (ix86_match_ccmode (insn, CCNOmode)
8429             && !(INTVAL (operands[3]) & ~127)))"
8430   [(set (match_dup 0)
8431         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8432                          (const_int 0)]))]
8433   "operands[2] = gen_lowpart (QImode, operands[2]);
8434    operands[3] = gen_lowpart (QImode, operands[3]);")
8435
8436
8437 ;; %%% This used to optimize known byte-wide and operations to memory,
8438 ;; and sometimes to QImode registers.  If this is considered useful,
8439 ;; it should be done with splitters.
8440
8441 (define_expand "anddi3"
8442   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8443         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8444                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8445   "TARGET_64BIT"
8446   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8447
8448 (define_insn "*anddi_1_rex64"
8449   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8450         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8451                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8454 {
8455   switch (get_attr_type (insn))
8456     {
8457     case TYPE_IMOVX:
8458       {
8459         enum machine_mode mode;
8460
8461         gcc_assert (CONST_INT_P (operands[2]));
8462         if (INTVAL (operands[2]) == 0xff)
8463           mode = QImode;
8464         else
8465           {
8466             gcc_assert (INTVAL (operands[2]) == 0xffff);
8467             mode = HImode;
8468           }
8469
8470         operands[1] = gen_lowpart (mode, operands[1]);
8471         if (mode == QImode)
8472           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8473         else
8474           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8475       }
8476
8477     default:
8478       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8479       if (get_attr_mode (insn) == MODE_SI)
8480         return "and{l}\t{%k2, %k0|%k0, %k2}";
8481       else
8482         return "and{q}\t{%2, %0|%0, %2}";
8483     }
8484 }
8485   [(set_attr "type" "alu,alu,alu,imovx")
8486    (set_attr "length_immediate" "*,*,*,0")
8487    (set (attr "prefix_rex")
8488      (if_then_else
8489        (and (eq_attr "type" "imovx")
8490             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8491                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8492        (const_string "1")
8493        (const_string "*")))
8494    (set_attr "mode" "SI,DI,DI,SI")])
8495
8496 (define_insn "*anddi_2"
8497   [(set (reg FLAGS_REG)
8498         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8499                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8500                  (const_int 0)))
8501    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8502         (and:DI (match_dup 1) (match_dup 2)))]
8503   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8504    && ix86_binary_operator_ok (AND, DImode, operands)"
8505   "@
8506    and{l}\t{%k2, %k0|%k0, %k2}
8507    and{q}\t{%2, %0|%0, %2}
8508    and{q}\t{%2, %0|%0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "mode" "SI,DI,DI")])
8511
8512 (define_expand "andsi3"
8513   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8514         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8515                 (match_operand:SI 2 "general_operand" "")))]
8516   ""
8517   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8518
8519 (define_insn "*andsi_1"
8520   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8521         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8522                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8523    (clobber (reg:CC FLAGS_REG))]
8524   "ix86_binary_operator_ok (AND, SImode, operands)"
8525 {
8526   switch (get_attr_type (insn))
8527     {
8528     case TYPE_IMOVX:
8529       {
8530         enum machine_mode mode;
8531
8532         gcc_assert (CONST_INT_P (operands[2]));
8533         if (INTVAL (operands[2]) == 0xff)
8534           mode = QImode;
8535         else
8536           {
8537             gcc_assert (INTVAL (operands[2]) == 0xffff);
8538             mode = HImode;
8539           }
8540
8541         operands[1] = gen_lowpart (mode, operands[1]);
8542         if (mode == QImode)
8543           return "movz{bl|x}\t{%1, %0|%0, %1}";
8544         else
8545           return "movz{wl|x}\t{%1, %0|%0, %1}";
8546       }
8547
8548     default:
8549       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8550       return "and{l}\t{%2, %0|%0, %2}";
8551     }
8552 }
8553   [(set_attr "type" "alu,alu,imovx")
8554    (set (attr "prefix_rex")
8555      (if_then_else
8556        (and (eq_attr "type" "imovx")
8557             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8558                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8559        (const_string "1")
8560        (const_string "*")))
8561    (set_attr "length_immediate" "*,*,0")
8562    (set_attr "mode" "SI")])
8563
8564 (define_split
8565   [(set (match_operand 0 "register_operand" "")
8566         (and (match_dup 0)
8567              (const_int -65536)))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8570   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8571   "operands[1] = gen_lowpart (HImode, operands[0]);")
8572
8573 (define_split
8574   [(set (match_operand 0 "ext_register_operand" "")
8575         (and (match_dup 0)
8576              (const_int -256)))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8579   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8580   "operands[1] = gen_lowpart (QImode, operands[0]);")
8581
8582 (define_split
8583   [(set (match_operand 0 "ext_register_operand" "")
8584         (and (match_dup 0)
8585              (const_int -65281)))
8586    (clobber (reg:CC FLAGS_REG))]
8587   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8588   [(parallel [(set (zero_extract:SI (match_dup 0)
8589                                     (const_int 8)
8590                                     (const_int 8))
8591                    (xor:SI
8592                      (zero_extract:SI (match_dup 0)
8593                                       (const_int 8)
8594                                       (const_int 8))
8595                      (zero_extract:SI (match_dup 0)
8596                                       (const_int 8)
8597                                       (const_int 8))))
8598               (clobber (reg:CC FLAGS_REG))])]
8599   "operands[0] = gen_lowpart (SImode, operands[0]);")
8600
8601 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8602 (define_insn "*andsi_1_zext"
8603   [(set (match_operand:DI 0 "register_operand" "=r")
8604         (zero_extend:DI
8605           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8606                   (match_operand:SI 2 "general_operand" "g"))))
8607    (clobber (reg:CC FLAGS_REG))]
8608   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8609   "and{l}\t{%2, %k0|%k0, %2}"
8610   [(set_attr "type" "alu")
8611    (set_attr "mode" "SI")])
8612
8613 (define_insn "*andsi_2"
8614   [(set (reg FLAGS_REG)
8615         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8616                          (match_operand:SI 2 "general_operand" "g,ri"))
8617                  (const_int 0)))
8618    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8619         (and:SI (match_dup 1) (match_dup 2)))]
8620   "ix86_match_ccmode (insn, CCNOmode)
8621    && ix86_binary_operator_ok (AND, SImode, operands)"
8622   "and{l}\t{%2, %0|%0, %2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "SI")])
8625
8626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8627 (define_insn "*andsi_2_zext"
8628   [(set (reg FLAGS_REG)
8629         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8630                          (match_operand:SI 2 "general_operand" "g"))
8631                  (const_int 0)))
8632    (set (match_operand:DI 0 "register_operand" "=r")
8633         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8634   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8635    && ix86_binary_operator_ok (AND, SImode, operands)"
8636   "and{l}\t{%2, %k0|%k0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "SI")])
8639
8640 (define_expand "andhi3"
8641   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8642         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8643                 (match_operand:HI 2 "general_operand" "")))]
8644   "TARGET_HIMODE_MATH"
8645   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8646
8647 (define_insn "*andhi_1"
8648   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8649         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8650                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8651    (clobber (reg:CC FLAGS_REG))]
8652   "ix86_binary_operator_ok (AND, HImode, operands)"
8653 {
8654   switch (get_attr_type (insn))
8655     {
8656     case TYPE_IMOVX:
8657       gcc_assert (CONST_INT_P (operands[2]));
8658       gcc_assert (INTVAL (operands[2]) == 0xff);
8659       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8660
8661     default:
8662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8663
8664       return "and{w}\t{%2, %0|%0, %2}";
8665     }
8666 }
8667   [(set_attr "type" "alu,alu,imovx")
8668    (set_attr "length_immediate" "*,*,0")
8669    (set (attr "prefix_rex")
8670      (if_then_else
8671        (and (eq_attr "type" "imovx")
8672             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8673        (const_string "1")
8674        (const_string "*")))
8675    (set_attr "mode" "HI,HI,SI")])
8676
8677 (define_insn "*andhi_2"
8678   [(set (reg FLAGS_REG)
8679         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8680                          (match_operand:HI 2 "general_operand" "rmn,rn"))
8681                  (const_int 0)))
8682    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8683         (and:HI (match_dup 1) (match_dup 2)))]
8684   "ix86_match_ccmode (insn, CCNOmode)
8685    && ix86_binary_operator_ok (AND, HImode, operands)"
8686   "and{w}\t{%2, %0|%0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "HI")])
8689
8690 (define_expand "andqi3"
8691   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8692         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8693                 (match_operand:QI 2 "general_operand" "")))]
8694   "TARGET_QIMODE_MATH"
8695   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8696
8697 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8698 (define_insn "*andqi_1"
8699   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8700         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8701                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8702    (clobber (reg:CC FLAGS_REG))]
8703   "ix86_binary_operator_ok (AND, QImode, operands)"
8704   "@
8705    and{b}\t{%2, %0|%0, %2}
8706    and{b}\t{%2, %0|%0, %2}
8707    and{l}\t{%k2, %k0|%k0, %k2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "mode" "QI,QI,SI")])
8710
8711 (define_insn "*andqi_1_slp"
8712   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8713         (and:QI (match_dup 0)
8714                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8715    (clobber (reg:CC FLAGS_REG))]
8716   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8717    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8718   "and{b}\t{%1, %0|%0, %1}"
8719   [(set_attr "type" "alu1")
8720    (set_attr "mode" "QI")])
8721
8722 (define_insn "*andqi_2_maybe_si"
8723   [(set (reg FLAGS_REG)
8724         (compare (and:QI
8725                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8726                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8727                  (const_int 0)))
8728    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8729         (and:QI (match_dup 1) (match_dup 2)))]
8730   "ix86_binary_operator_ok (AND, QImode, operands)
8731    && ix86_match_ccmode (insn,
8732                          CONST_INT_P (operands[2])
8733                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8734 {
8735   if (which_alternative == 2)
8736     {
8737       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8738         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8739       return "and{l}\t{%2, %k0|%k0, %2}";
8740     }
8741   return "and{b}\t{%2, %0|%0, %2}";
8742 }
8743   [(set_attr "type" "alu")
8744    (set_attr "mode" "QI,QI,SI")])
8745
8746 (define_insn "*andqi_2"
8747   [(set (reg FLAGS_REG)
8748         (compare (and:QI
8749                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8750                    (match_operand:QI 2 "general_operand" "qmn,qn"))
8751                  (const_int 0)))
8752    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8753         (and:QI (match_dup 1) (match_dup 2)))]
8754   "ix86_match_ccmode (insn, CCNOmode)
8755    && ix86_binary_operator_ok (AND, QImode, operands)"
8756   "and{b}\t{%2, %0|%0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "mode" "QI")])
8759
8760 (define_insn "*andqi_2_slp"
8761   [(set (reg FLAGS_REG)
8762         (compare (and:QI
8763                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8764                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8765                  (const_int 0)))
8766    (set (strict_low_part (match_dup 0))
8767         (and:QI (match_dup 0) (match_dup 1)))]
8768   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8769    && ix86_match_ccmode (insn, CCNOmode)
8770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8771   "and{b}\t{%1, %0|%0, %1}"
8772   [(set_attr "type" "alu1")
8773    (set_attr "mode" "QI")])
8774
8775 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8776 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8777 ;; for a QImode operand, which of course failed.
8778
8779 (define_insn "andqi_ext_0"
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           (match_operand 2 "const_int_operand" "n")))
8789    (clobber (reg:CC FLAGS_REG))]
8790   ""
8791   "and{b}\t{%2, %h0|%h0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "length_immediate" "1")
8794    (set_attr "modrm" "1")
8795    (set_attr "mode" "QI")])
8796
8797 ;; Generated by peephole translating test to and.  This shows up
8798 ;; often in fp comparisons.
8799
8800 (define_insn "*andqi_ext_0_cc"
8801   [(set (reg FLAGS_REG)
8802         (compare
8803           (and:SI
8804             (zero_extract:SI
8805               (match_operand 1 "ext_register_operand" "0")
8806               (const_int 8)
8807               (const_int 8))
8808             (match_operand 2 "const_int_operand" "n"))
8809           (const_int 0)))
8810    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8811                          (const_int 8)
8812                          (const_int 8))
8813         (and:SI
8814           (zero_extract:SI
8815             (match_dup 1)
8816             (const_int 8)
8817             (const_int 8))
8818           (match_dup 2)))]
8819   "ix86_match_ccmode (insn, CCNOmode)"
8820   "and{b}\t{%2, %h0|%h0, %2}"
8821   [(set_attr "type" "alu")
8822    (set_attr "length_immediate" "1")
8823    (set_attr "modrm" "1")
8824    (set_attr "mode" "QI")])
8825
8826 (define_insn "*andqi_ext_1"
8827   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8828                          (const_int 8)
8829                          (const_int 8))
8830         (and:SI
8831           (zero_extract:SI
8832             (match_operand 1 "ext_register_operand" "0")
8833             (const_int 8)
8834             (const_int 8))
8835           (zero_extend:SI
8836             (match_operand:QI 2 "general_operand" "Qm"))))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "!TARGET_64BIT"
8839   "and{b}\t{%2, %h0|%h0, %2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "length_immediate" "0")
8842    (set_attr "mode" "QI")])
8843
8844 (define_insn "*andqi_ext_1_rex64"
8845   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8846                          (const_int 8)
8847                          (const_int 8))
8848         (and:SI
8849           (zero_extract:SI
8850             (match_operand 1 "ext_register_operand" "0")
8851             (const_int 8)
8852             (const_int 8))
8853           (zero_extend:SI
8854             (match_operand 2 "ext_register_operand" "Q"))))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "TARGET_64BIT"
8857   "and{b}\t{%2, %h0|%h0, %2}"
8858   [(set_attr "type" "alu")
8859    (set_attr "length_immediate" "0")
8860    (set_attr "mode" "QI")])
8861
8862 (define_insn "*andqi_ext_2"
8863   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8864                          (const_int 8)
8865                          (const_int 8))
8866         (and:SI
8867           (zero_extract:SI
8868             (match_operand 1 "ext_register_operand" "%0")
8869             (const_int 8)
8870             (const_int 8))
8871           (zero_extract:SI
8872             (match_operand 2 "ext_register_operand" "Q")
8873             (const_int 8)
8874             (const_int 8))))
8875    (clobber (reg:CC FLAGS_REG))]
8876   ""
8877   "and{b}\t{%h2, %h0|%h0, %h2}"
8878   [(set_attr "type" "alu")
8879    (set_attr "length_immediate" "0")
8880    (set_attr "mode" "QI")])
8881
8882 ;; Convert wide AND instructions with immediate operand to shorter QImode
8883 ;; equivalents when possible.
8884 ;; Don't do the splitting with memory operands, since it introduces risk
8885 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8886 ;; for size, but that can (should?) be handled by generic code instead.
8887 (define_split
8888   [(set (match_operand 0 "register_operand" "")
8889         (and (match_operand 1 "register_operand" "")
8890              (match_operand 2 "const_int_operand" "")))
8891    (clobber (reg:CC FLAGS_REG))]
8892    "reload_completed
8893     && QI_REG_P (operands[0])
8894     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8895     && !(~INTVAL (operands[2]) & ~(255 << 8))
8896     && GET_MODE (operands[0]) != QImode"
8897   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8898                    (and:SI (zero_extract:SI (match_dup 1)
8899                                             (const_int 8) (const_int 8))
8900                            (match_dup 2)))
8901               (clobber (reg:CC FLAGS_REG))])]
8902   "operands[0] = gen_lowpart (SImode, operands[0]);
8903    operands[1] = gen_lowpart (SImode, operands[1]);
8904    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8905
8906 ;; Since AND can be encoded with sign extended immediate, this is only
8907 ;; profitable when 7th bit is not set.
8908 (define_split
8909   [(set (match_operand 0 "register_operand" "")
8910         (and (match_operand 1 "general_operand" "")
8911              (match_operand 2 "const_int_operand" "")))
8912    (clobber (reg:CC FLAGS_REG))]
8913    "reload_completed
8914     && ANY_QI_REG_P (operands[0])
8915     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8916     && !(~INTVAL (operands[2]) & ~255)
8917     && !(INTVAL (operands[2]) & 128)
8918     && GET_MODE (operands[0]) != QImode"
8919   [(parallel [(set (strict_low_part (match_dup 0))
8920                    (and:QI (match_dup 1)
8921                            (match_dup 2)))
8922               (clobber (reg:CC FLAGS_REG))])]
8923   "operands[0] = gen_lowpart (QImode, operands[0]);
8924    operands[1] = gen_lowpart (QImode, operands[1]);
8925    operands[2] = gen_lowpart (QImode, operands[2]);")
8926 \f
8927 ;; Logical inclusive OR instructions
8928
8929 ;; %%% This used to optimize known byte-wide and operations to memory.
8930 ;; If this is considered useful, it should be done with splitters.
8931
8932 (define_expand "iordi3"
8933   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8934         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8935                 (match_operand:DI 2 "x86_64_general_operand" "")))]
8936   "TARGET_64BIT"
8937   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8938
8939 (define_insn "*iordi_1_rex64"
8940   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8941         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8942                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "TARGET_64BIT
8945    && ix86_binary_operator_ok (IOR, DImode, operands)"
8946   "or{q}\t{%2, %0|%0, %2}"
8947   [(set_attr "type" "alu")
8948    (set_attr "mode" "DI")])
8949
8950 (define_insn "*iordi_2_rex64"
8951   [(set (reg FLAGS_REG)
8952         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8953                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8954                  (const_int 0)))
8955    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8956         (ior:DI (match_dup 1) (match_dup 2)))]
8957   "TARGET_64BIT
8958    && ix86_match_ccmode (insn, CCNOmode)
8959    && ix86_binary_operator_ok (IOR, DImode, operands)"
8960   "or{q}\t{%2, %0|%0, %2}"
8961   [(set_attr "type" "alu")
8962    (set_attr "mode" "DI")])
8963
8964 (define_insn "*iordi_3_rex64"
8965   [(set (reg FLAGS_REG)
8966         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8967                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8968                  (const_int 0)))
8969    (clobber (match_scratch:DI 0 "=r"))]
8970   "TARGET_64BIT
8971    && ix86_match_ccmode (insn, CCNOmode)
8972    && ix86_binary_operator_ok (IOR, DImode, operands)"
8973   "or{q}\t{%2, %0|%0, %2}"
8974   [(set_attr "type" "alu")
8975    (set_attr "mode" "DI")])
8976
8977
8978 (define_expand "iorsi3"
8979   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8980         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8981                 (match_operand:SI 2 "general_operand" "")))]
8982   ""
8983   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8984
8985 (define_insn "*iorsi_1"
8986   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8987         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8988                 (match_operand:SI 2 "general_operand" "ri,g")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "ix86_binary_operator_ok (IOR, SImode, operands)"
8991   "or{l}\t{%2, %0|%0, %2}"
8992   [(set_attr "type" "alu")
8993    (set_attr "mode" "SI")])
8994
8995 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8996 (define_insn "*iorsi_1_zext"
8997   [(set (match_operand:DI 0 "register_operand" "=r")
8998         (zero_extend:DI
8999           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9000                   (match_operand:SI 2 "general_operand" "g"))))
9001    (clobber (reg:CC FLAGS_REG))]
9002   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9003   "or{l}\t{%2, %k0|%k0, %2}"
9004   [(set_attr "type" "alu")
9005    (set_attr "mode" "SI")])
9006
9007 (define_insn "*iorsi_1_zext_imm"
9008   [(set (match_operand:DI 0 "register_operand" "=r")
9009         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9010                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9011    (clobber (reg:CC FLAGS_REG))]
9012   "TARGET_64BIT"
9013   "or{l}\t{%2, %k0|%k0, %2}"
9014   [(set_attr "type" "alu")
9015    (set_attr "mode" "SI")])
9016
9017 (define_insn "*iorsi_2"
9018   [(set (reg FLAGS_REG)
9019         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9020                          (match_operand:SI 2 "general_operand" "g,ri"))
9021                  (const_int 0)))
9022    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9023         (ior:SI (match_dup 1) (match_dup 2)))]
9024   "ix86_match_ccmode (insn, CCNOmode)
9025    && ix86_binary_operator_ok (IOR, SImode, operands)"
9026   "or{l}\t{%2, %0|%0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "mode" "SI")])
9029
9030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9031 ;; ??? Special case for immediate operand is missing - it is tricky.
9032 (define_insn "*iorsi_2_zext"
9033   [(set (reg FLAGS_REG)
9034         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9035                          (match_operand:SI 2 "general_operand" "g"))
9036                  (const_int 0)))
9037    (set (match_operand:DI 0 "register_operand" "=r")
9038         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9039   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9040    && ix86_binary_operator_ok (IOR, SImode, operands)"
9041   "or{l}\t{%2, %k0|%k0, %2}"
9042   [(set_attr "type" "alu")
9043    (set_attr "mode" "SI")])
9044
9045 (define_insn "*iorsi_2_zext_imm"
9046   [(set (reg FLAGS_REG)
9047         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9048                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9049                  (const_int 0)))
9050    (set (match_operand:DI 0 "register_operand" "=r")
9051         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9052   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9053    && ix86_binary_operator_ok (IOR, SImode, operands)"
9054   "or{l}\t{%2, %k0|%k0, %2}"
9055   [(set_attr "type" "alu")
9056    (set_attr "mode" "SI")])
9057
9058 (define_insn "*iorsi_3"
9059   [(set (reg FLAGS_REG)
9060         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9061                          (match_operand:SI 2 "general_operand" "g"))
9062                  (const_int 0)))
9063    (clobber (match_scratch:SI 0 "=r"))]
9064   "ix86_match_ccmode (insn, CCNOmode)
9065    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9066   "or{l}\t{%2, %0|%0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "mode" "SI")])
9069
9070 (define_expand "iorhi3"
9071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073                 (match_operand:HI 2 "general_operand" "")))]
9074   "TARGET_HIMODE_MATH"
9075   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9076
9077 (define_insn "*iorhi_1"
9078   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9079         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9080                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "ix86_binary_operator_ok (IOR, HImode, operands)"
9083   "or{w}\t{%2, %0|%0, %2}"
9084   [(set_attr "type" "alu")
9085    (set_attr "mode" "HI")])
9086
9087 (define_insn "*iorhi_2"
9088   [(set (reg FLAGS_REG)
9089         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9090                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9091                  (const_int 0)))
9092    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9093         (ior:HI (match_dup 1) (match_dup 2)))]
9094   "ix86_match_ccmode (insn, CCNOmode)
9095    && ix86_binary_operator_ok (IOR, HImode, operands)"
9096   "or{w}\t{%2, %0|%0, %2}"
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "HI")])
9099
9100 (define_insn "*iorhi_3"
9101   [(set (reg FLAGS_REG)
9102         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9103                          (match_operand:HI 2 "general_operand" "rmn"))
9104                  (const_int 0)))
9105    (clobber (match_scratch:HI 0 "=r"))]
9106   "ix86_match_ccmode (insn, CCNOmode)
9107    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9108   "or{w}\t{%2, %0|%0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "HI")])
9111
9112 (define_expand "iorqi3"
9113   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9114         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9115                 (match_operand:QI 2 "general_operand" "")))]
9116   "TARGET_QIMODE_MATH"
9117   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9118
9119 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9120 (define_insn "*iorqi_1"
9121   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9122         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9123                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "ix86_binary_operator_ok (IOR, QImode, operands)"
9126   "@
9127    or{b}\t{%2, %0|%0, %2}
9128    or{b}\t{%2, %0|%0, %2}
9129    or{l}\t{%k2, %k0|%k0, %k2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "QI,QI,SI")])
9132
9133 (define_insn "*iorqi_1_slp"
9134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9135         (ior:QI (match_dup 0)
9136                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9139    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9140   "or{b}\t{%1, %0|%0, %1}"
9141   [(set_attr "type" "alu1")
9142    (set_attr "mode" "QI")])
9143
9144 (define_insn "*iorqi_2"
9145   [(set (reg FLAGS_REG)
9146         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9147                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9148                  (const_int 0)))
9149    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9150         (ior:QI (match_dup 1) (match_dup 2)))]
9151   "ix86_match_ccmode (insn, CCNOmode)
9152    && ix86_binary_operator_ok (IOR, QImode, operands)"
9153   "or{b}\t{%2, %0|%0, %2}"
9154   [(set_attr "type" "alu")
9155    (set_attr "mode" "QI")])
9156
9157 (define_insn "*iorqi_2_slp"
9158   [(set (reg FLAGS_REG)
9159         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9160                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9161                  (const_int 0)))
9162    (set (strict_low_part (match_dup 0))
9163         (ior:QI (match_dup 0) (match_dup 1)))]
9164   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9165    && ix86_match_ccmode (insn, CCNOmode)
9166    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9167   "or{b}\t{%1, %0|%0, %1}"
9168   [(set_attr "type" "alu1")
9169    (set_attr "mode" "QI")])
9170
9171 (define_insn "*iorqi_3"
9172   [(set (reg FLAGS_REG)
9173         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9174                          (match_operand:QI 2 "general_operand" "qmn"))
9175                  (const_int 0)))
9176    (clobber (match_scratch:QI 0 "=q"))]
9177   "ix86_match_ccmode (insn, CCNOmode)
9178    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9179   "or{b}\t{%2, %0|%0, %2}"
9180   [(set_attr "type" "alu")
9181    (set_attr "mode" "QI")])
9182
9183 (define_insn "*iorqi_ext_0"
9184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9185                          (const_int 8)
9186                          (const_int 8))
9187         (ior:SI
9188           (zero_extract:SI
9189             (match_operand 1 "ext_register_operand" "0")
9190             (const_int 8)
9191             (const_int 8))
9192           (match_operand 2 "const_int_operand" "n")))
9193    (clobber (reg:CC FLAGS_REG))]
9194   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9195   "or{b}\t{%2, %h0|%h0, %2}"
9196   [(set_attr "type" "alu")
9197    (set_attr "length_immediate" "1")
9198    (set_attr "modrm" "1")
9199    (set_attr "mode" "QI")])
9200
9201 (define_insn "*iorqi_ext_1"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (ior:SI
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (zero_extend:SI
9211             (match_operand:QI 2 "general_operand" "Qm"))))
9212    (clobber (reg:CC FLAGS_REG))]
9213   "!TARGET_64BIT
9214    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9215   "or{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "length_immediate" "0")
9218    (set_attr "mode" "QI")])
9219
9220 (define_insn "*iorqi_ext_1_rex64"
9221   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222                          (const_int 8)
9223                          (const_int 8))
9224         (ior:SI
9225           (zero_extract:SI
9226             (match_operand 1 "ext_register_operand" "0")
9227             (const_int 8)
9228             (const_int 8))
9229           (zero_extend:SI
9230             (match_operand 2 "ext_register_operand" "Q"))))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_64BIT
9233    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9234   "or{b}\t{%2, %h0|%h0, %2}"
9235   [(set_attr "type" "alu")
9236    (set_attr "length_immediate" "0")
9237    (set_attr "mode" "QI")])
9238
9239 (define_insn "*iorqi_ext_2"
9240   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9241                          (const_int 8)
9242                          (const_int 8))
9243         (ior:SI
9244           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9245                            (const_int 8)
9246                            (const_int 8))
9247           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9248                            (const_int 8)
9249                            (const_int 8))))
9250    (clobber (reg:CC FLAGS_REG))]
9251   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9252   "ior{b}\t{%h2, %h0|%h0, %h2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "length_immediate" "0")
9255    (set_attr "mode" "QI")])
9256
9257 (define_split
9258   [(set (match_operand 0 "register_operand" "")
9259         (ior (match_operand 1 "register_operand" "")
9260              (match_operand 2 "const_int_operand" "")))
9261    (clobber (reg:CC FLAGS_REG))]
9262    "reload_completed
9263     && QI_REG_P (operands[0])
9264     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9265     && !(INTVAL (operands[2]) & ~(255 << 8))
9266     && GET_MODE (operands[0]) != QImode"
9267   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9268                    (ior:SI (zero_extract:SI (match_dup 1)
9269                                             (const_int 8) (const_int 8))
9270                            (match_dup 2)))
9271               (clobber (reg:CC FLAGS_REG))])]
9272   "operands[0] = gen_lowpart (SImode, operands[0]);
9273    operands[1] = gen_lowpart (SImode, operands[1]);
9274    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9275
9276 ;; Since OR can be encoded with sign extended immediate, this is only
9277 ;; profitable when 7th bit is set.
9278 (define_split
9279   [(set (match_operand 0 "register_operand" "")
9280         (ior (match_operand 1 "general_operand" "")
9281              (match_operand 2 "const_int_operand" "")))
9282    (clobber (reg:CC FLAGS_REG))]
9283    "reload_completed
9284     && ANY_QI_REG_P (operands[0])
9285     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9286     && !(INTVAL (operands[2]) & ~255)
9287     && (INTVAL (operands[2]) & 128)
9288     && GET_MODE (operands[0]) != QImode"
9289   [(parallel [(set (strict_low_part (match_dup 0))
9290                    (ior:QI (match_dup 1)
9291                            (match_dup 2)))
9292               (clobber (reg:CC FLAGS_REG))])]
9293   "operands[0] = gen_lowpart (QImode, operands[0]);
9294    operands[1] = gen_lowpart (QImode, operands[1]);
9295    operands[2] = gen_lowpart (QImode, operands[2]);")
9296 \f
9297 ;; Logical XOR instructions
9298
9299 ;; %%% This used to optimize known byte-wide and operations to memory.
9300 ;; If this is considered useful, it should be done with splitters.
9301
9302 (define_expand "xordi3"
9303   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9304         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9305                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9306   "TARGET_64BIT"
9307   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9308
9309 (define_insn "*xordi_1_rex64"
9310   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9311         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9312                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9313    (clobber (reg:CC FLAGS_REG))]
9314   "TARGET_64BIT
9315    && ix86_binary_operator_ok (XOR, DImode, operands)"
9316   "xor{q}\t{%2, %0|%0, %2}"
9317   [(set_attr "type" "alu")
9318    (set_attr "mode" "DI")])
9319
9320 (define_insn "*xordi_2_rex64"
9321   [(set (reg FLAGS_REG)
9322         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9323                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9324                  (const_int 0)))
9325    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9326         (xor:DI (match_dup 1) (match_dup 2)))]
9327   "TARGET_64BIT
9328    && ix86_match_ccmode (insn, CCNOmode)
9329    && ix86_binary_operator_ok (XOR, DImode, operands)"
9330   "xor{q}\t{%2, %0|%0, %2}"
9331   [(set_attr "type" "alu")
9332    (set_attr "mode" "DI")])
9333
9334 (define_insn "*xordi_3_rex64"
9335   [(set (reg FLAGS_REG)
9336         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9337                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9338                  (const_int 0)))
9339    (clobber (match_scratch:DI 0 "=r"))]
9340   "TARGET_64BIT
9341    && ix86_match_ccmode (insn, CCNOmode)
9342    && ix86_binary_operator_ok (XOR, DImode, operands)"
9343   "xor{q}\t{%2, %0|%0, %2}"
9344   [(set_attr "type" "alu")
9345    (set_attr "mode" "DI")])
9346
9347 (define_expand "xorsi3"
9348   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9349         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9350                 (match_operand:SI 2 "general_operand" "")))]
9351   ""
9352   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9353
9354 (define_insn "*xorsi_1"
9355   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9356         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9357                 (match_operand:SI 2 "general_operand" "ri,rm")))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "ix86_binary_operator_ok (XOR, SImode, operands)"
9360   "xor{l}\t{%2, %0|%0, %2}"
9361   [(set_attr "type" "alu")
9362    (set_attr "mode" "SI")])
9363
9364 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9365 ;; Add speccase for immediates
9366 (define_insn "*xorsi_1_zext"
9367   [(set (match_operand:DI 0 "register_operand" "=r")
9368         (zero_extend:DI
9369           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9370                   (match_operand:SI 2 "general_operand" "g"))))
9371    (clobber (reg:CC FLAGS_REG))]
9372   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9373   "xor{l}\t{%2, %k0|%k0, %2}"
9374   [(set_attr "type" "alu")
9375    (set_attr "mode" "SI")])
9376
9377 (define_insn "*xorsi_1_zext_imm"
9378   [(set (match_operand:DI 0 "register_operand" "=r")
9379         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9380                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9381    (clobber (reg:CC FLAGS_REG))]
9382   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9383   "xor{l}\t{%2, %k0|%k0, %2}"
9384   [(set_attr "type" "alu")
9385    (set_attr "mode" "SI")])
9386
9387 (define_insn "*xorsi_2"
9388   [(set (reg FLAGS_REG)
9389         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9390                          (match_operand:SI 2 "general_operand" "g,ri"))
9391                  (const_int 0)))
9392    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9393         (xor:SI (match_dup 1) (match_dup 2)))]
9394   "ix86_match_ccmode (insn, CCNOmode)
9395    && ix86_binary_operator_ok (XOR, SImode, operands)"
9396   "xor{l}\t{%2, %0|%0, %2}"
9397   [(set_attr "type" "alu")
9398    (set_attr "mode" "SI")])
9399
9400 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9401 ;; ??? Special case for immediate operand is missing - it is tricky.
9402 (define_insn "*xorsi_2_zext"
9403   [(set (reg FLAGS_REG)
9404         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9405                          (match_operand:SI 2 "general_operand" "g"))
9406                  (const_int 0)))
9407    (set (match_operand:DI 0 "register_operand" "=r")
9408         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9409   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9410    && ix86_binary_operator_ok (XOR, SImode, operands)"
9411   "xor{l}\t{%2, %k0|%k0, %2}"
9412   [(set_attr "type" "alu")
9413    (set_attr "mode" "SI")])
9414
9415 (define_insn "*xorsi_2_zext_imm"
9416   [(set (reg FLAGS_REG)
9417         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9418                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9419                  (const_int 0)))
9420    (set (match_operand:DI 0 "register_operand" "=r")
9421         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9422   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9423    && ix86_binary_operator_ok (XOR, SImode, operands)"
9424   "xor{l}\t{%2, %k0|%k0, %2}"
9425   [(set_attr "type" "alu")
9426    (set_attr "mode" "SI")])
9427
9428 (define_insn "*xorsi_3"
9429   [(set (reg FLAGS_REG)
9430         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9431                          (match_operand:SI 2 "general_operand" "g"))
9432                  (const_int 0)))
9433    (clobber (match_scratch:SI 0 "=r"))]
9434   "ix86_match_ccmode (insn, CCNOmode)
9435    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9436   "xor{l}\t{%2, %0|%0, %2}"
9437   [(set_attr "type" "alu")
9438    (set_attr "mode" "SI")])
9439
9440 (define_expand "xorhi3"
9441   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9442         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9443                 (match_operand:HI 2 "general_operand" "")))]
9444   "TARGET_HIMODE_MATH"
9445   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9446
9447 (define_insn "*xorhi_1"
9448   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9449         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9450                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9451    (clobber (reg:CC FLAGS_REG))]
9452   "ix86_binary_operator_ok (XOR, HImode, operands)"
9453   "xor{w}\t{%2, %0|%0, %2}"
9454   [(set_attr "type" "alu")
9455    (set_attr "mode" "HI")])
9456
9457 (define_insn "*xorhi_2"
9458   [(set (reg FLAGS_REG)
9459         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9460                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9461                  (const_int 0)))
9462    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9463         (xor:HI (match_dup 1) (match_dup 2)))]
9464   "ix86_match_ccmode (insn, CCNOmode)
9465    && ix86_binary_operator_ok (XOR, HImode, operands)"
9466   "xor{w}\t{%2, %0|%0, %2}"
9467   [(set_attr "type" "alu")
9468    (set_attr "mode" "HI")])
9469
9470 (define_insn "*xorhi_3"
9471   [(set (reg FLAGS_REG)
9472         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9473                          (match_operand:HI 2 "general_operand" "rmn"))
9474                  (const_int 0)))
9475    (clobber (match_scratch:HI 0 "=r"))]
9476   "ix86_match_ccmode (insn, CCNOmode)
9477    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9478   "xor{w}\t{%2, %0|%0, %2}"
9479   [(set_attr "type" "alu")
9480    (set_attr "mode" "HI")])
9481
9482 (define_expand "xorqi3"
9483   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9484         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9485                 (match_operand:QI 2 "general_operand" "")))]
9486   "TARGET_QIMODE_MATH"
9487   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9488
9489 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9490 (define_insn "*xorqi_1"
9491   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9492         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9493                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "ix86_binary_operator_ok (XOR, QImode, operands)"
9496   "@
9497    xor{b}\t{%2, %0|%0, %2}
9498    xor{b}\t{%2, %0|%0, %2}
9499    xor{l}\t{%k2, %k0|%k0, %k2}"
9500   [(set_attr "type" "alu")
9501    (set_attr "mode" "QI,QI,SI")])
9502
9503 (define_insn "*xorqi_1_slp"
9504   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9505         (xor:QI (match_dup 0)
9506                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9507    (clobber (reg:CC FLAGS_REG))]
9508   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9509    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9510   "xor{b}\t{%1, %0|%0, %1}"
9511   [(set_attr "type" "alu1")
9512    (set_attr "mode" "QI")])
9513
9514 (define_insn "*xorqi_ext_0"
9515   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9516                          (const_int 8)
9517                          (const_int 8))
9518         (xor:SI
9519           (zero_extract:SI
9520             (match_operand 1 "ext_register_operand" "0")
9521             (const_int 8)
9522             (const_int 8))
9523           (match_operand 2 "const_int_operand" "n")))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9526   "xor{b}\t{%2, %h0|%h0, %2}"
9527   [(set_attr "type" "alu")
9528    (set_attr "length_immediate" "1")
9529    (set_attr "modrm" "1")
9530    (set_attr "mode" "QI")])
9531
9532 (define_insn "*xorqi_ext_1"
9533   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9534                          (const_int 8)
9535                          (const_int 8))
9536         (xor:SI
9537           (zero_extract:SI
9538             (match_operand 1 "ext_register_operand" "0")
9539             (const_int 8)
9540             (const_int 8))
9541           (zero_extend:SI
9542             (match_operand:QI 2 "general_operand" "Qm"))))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "!TARGET_64BIT
9545    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9546   "xor{b}\t{%2, %h0|%h0, %2}"
9547   [(set_attr "type" "alu")
9548    (set_attr "length_immediate" "0")
9549    (set_attr "mode" "QI")])
9550
9551 (define_insn "*xorqi_ext_1_rex64"
9552   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9553                          (const_int 8)
9554                          (const_int 8))
9555         (xor:SI
9556           (zero_extract:SI
9557             (match_operand 1 "ext_register_operand" "0")
9558             (const_int 8)
9559             (const_int 8))
9560           (zero_extend:SI
9561             (match_operand 2 "ext_register_operand" "Q"))))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "TARGET_64BIT
9564    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9565   "xor{b}\t{%2, %h0|%h0, %2}"
9566   [(set_attr "type" "alu")
9567    (set_attr "length_immediate" "0")
9568    (set_attr "mode" "QI")])
9569
9570 (define_insn "*xorqi_ext_2"
9571   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9572                          (const_int 8)
9573                          (const_int 8))
9574         (xor:SI
9575           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9576                            (const_int 8)
9577                            (const_int 8))
9578           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9579                            (const_int 8)
9580                            (const_int 8))))
9581    (clobber (reg:CC FLAGS_REG))]
9582   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9583   "xor{b}\t{%h2, %h0|%h0, %h2}"
9584   [(set_attr "type" "alu")
9585    (set_attr "length_immediate" "0")
9586    (set_attr "mode" "QI")])
9587
9588 (define_insn "*xorqi_cc_1"
9589   [(set (reg FLAGS_REG)
9590         (compare
9591           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9592                   (match_operand:QI 2 "general_operand" "qmn,qn"))
9593           (const_int 0)))
9594    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9595         (xor:QI (match_dup 1) (match_dup 2)))]
9596   "ix86_match_ccmode (insn, CCNOmode)
9597    && ix86_binary_operator_ok (XOR, QImode, operands)"
9598   "xor{b}\t{%2, %0|%0, %2}"
9599   [(set_attr "type" "alu")
9600    (set_attr "mode" "QI")])
9601
9602 (define_insn "*xorqi_2_slp"
9603   [(set (reg FLAGS_REG)
9604         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9605                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9606                  (const_int 0)))
9607    (set (strict_low_part (match_dup 0))
9608         (xor:QI (match_dup 0) (match_dup 1)))]
9609   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9610    && ix86_match_ccmode (insn, CCNOmode)
9611    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9612   "xor{b}\t{%1, %0|%0, %1}"
9613   [(set_attr "type" "alu1")
9614    (set_attr "mode" "QI")])
9615
9616 (define_insn "*xorqi_cc_2"
9617   [(set (reg FLAGS_REG)
9618         (compare
9619           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9620                   (match_operand:QI 2 "general_operand" "qmn"))
9621           (const_int 0)))
9622    (clobber (match_scratch:QI 0 "=q"))]
9623   "ix86_match_ccmode (insn, CCNOmode)
9624    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9625   "xor{b}\t{%2, %0|%0, %2}"
9626   [(set_attr "type" "alu")
9627    (set_attr "mode" "QI")])
9628
9629 (define_insn "*xorqi_cc_ext_1"
9630   [(set (reg FLAGS_REG)
9631         (compare
9632           (xor:SI
9633             (zero_extract:SI
9634               (match_operand 1 "ext_register_operand" "0")
9635               (const_int 8)
9636               (const_int 8))
9637             (match_operand:QI 2 "general_operand" "qmn"))
9638           (const_int 0)))
9639    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9640                          (const_int 8)
9641                          (const_int 8))
9642         (xor:SI
9643           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9644           (match_dup 2)))]
9645   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9646   "xor{b}\t{%2, %h0|%h0, %2}"
9647   [(set_attr "type" "alu")
9648    (set_attr "modrm" "1")
9649    (set_attr "mode" "QI")])
9650
9651 (define_insn "*xorqi_cc_ext_1_rex64"
9652   [(set (reg FLAGS_REG)
9653         (compare
9654           (xor:SI
9655             (zero_extract:SI
9656               (match_operand 1 "ext_register_operand" "0")
9657               (const_int 8)
9658               (const_int 8))
9659             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9660           (const_int 0)))
9661    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9662                          (const_int 8)
9663                          (const_int 8))
9664         (xor:SI
9665           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9666           (match_dup 2)))]
9667   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9668   "xor{b}\t{%2, %h0|%h0, %2}"
9669   [(set_attr "type" "alu")
9670    (set_attr "modrm" "1")
9671    (set_attr "mode" "QI")])
9672
9673 (define_expand "xorqi_cc_ext_1"
9674   [(parallel [
9675      (set (reg:CCNO FLAGS_REG)
9676           (compare:CCNO
9677             (xor:SI
9678               (zero_extract:SI
9679                 (match_operand 1 "ext_register_operand" "")
9680                 (const_int 8)
9681                 (const_int 8))
9682               (match_operand:QI 2 "general_operand" ""))
9683             (const_int 0)))
9684      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9685                            (const_int 8)
9686                            (const_int 8))
9687           (xor:SI
9688             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9689             (match_dup 2)))])]
9690   ""
9691   "")
9692
9693 (define_split
9694   [(set (match_operand 0 "register_operand" "")
9695         (xor (match_operand 1 "register_operand" "")
9696              (match_operand 2 "const_int_operand" "")))
9697    (clobber (reg:CC FLAGS_REG))]
9698    "reload_completed
9699     && QI_REG_P (operands[0])
9700     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9701     && !(INTVAL (operands[2]) & ~(255 << 8))
9702     && GET_MODE (operands[0]) != QImode"
9703   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9704                    (xor:SI (zero_extract:SI (match_dup 1)
9705                                             (const_int 8) (const_int 8))
9706                            (match_dup 2)))
9707               (clobber (reg:CC FLAGS_REG))])]
9708   "operands[0] = gen_lowpart (SImode, operands[0]);
9709    operands[1] = gen_lowpart (SImode, operands[1]);
9710    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9711
9712 ;; Since XOR can be encoded with sign extended immediate, this is only
9713 ;; profitable when 7th bit is set.
9714 (define_split
9715   [(set (match_operand 0 "register_operand" "")
9716         (xor (match_operand 1 "general_operand" "")
9717              (match_operand 2 "const_int_operand" "")))
9718    (clobber (reg:CC FLAGS_REG))]
9719    "reload_completed
9720     && ANY_QI_REG_P (operands[0])
9721     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9722     && !(INTVAL (operands[2]) & ~255)
9723     && (INTVAL (operands[2]) & 128)
9724     && GET_MODE (operands[0]) != QImode"
9725   [(parallel [(set (strict_low_part (match_dup 0))
9726                    (xor:QI (match_dup 1)
9727                            (match_dup 2)))
9728               (clobber (reg:CC FLAGS_REG))])]
9729   "operands[0] = gen_lowpart (QImode, operands[0]);
9730    operands[1] = gen_lowpart (QImode, operands[1]);
9731    operands[2] = gen_lowpart (QImode, operands[2]);")
9732 \f
9733 ;; Negation instructions
9734
9735 (define_expand "neg<mode>2"
9736   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9737         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9738   ""
9739   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9740
9741 (define_insn_and_split "*neg<dwi>2_doubleword"
9742   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9743         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9746   "#"
9747   "reload_completed"
9748   [(parallel
9749     [(set (reg:CCZ FLAGS_REG)
9750           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9751      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9752    (parallel
9753     [(set (match_dup 2)
9754           (plus:DWIH (match_dup 3)
9755                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9756                                 (const_int 0))))
9757      (clobber (reg:CC FLAGS_REG))])
9758    (parallel
9759     [(set (match_dup 2)
9760           (neg:DWIH (match_dup 2)))
9761      (clobber (reg:CC FLAGS_REG))])]
9762   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9763
9764 (define_insn "*neg<mode>2_1"
9765   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9766         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9767    (clobber (reg:CC FLAGS_REG))]
9768   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9769   "neg{<imodesuffix>}\t%0"
9770   [(set_attr "type" "negnot")
9771    (set_attr "mode" "<MODE>")])
9772
9773 ;; Combine is quite creative about this pattern.
9774 (define_insn "*negsi2_1_zext"
9775   [(set (match_operand:DI 0 "register_operand" "=r")
9776         (lshiftrt:DI
9777           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9778                              (const_int 32)))
9779         (const_int 32)))
9780    (clobber (reg:CC FLAGS_REG))]
9781   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9782   "neg{l}\t%k0"
9783   [(set_attr "type" "negnot")
9784    (set_attr "mode" "SI")])
9785
9786 ;; The problem with neg is that it does not perform (compare x 0),
9787 ;; it really performs (compare 0 x), which leaves us with the zero
9788 ;; flag being the only useful item.
9789
9790 (define_insn "*neg<mode>2_cmpz"
9791   [(set (reg:CCZ FLAGS_REG)
9792         (compare:CCZ
9793           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9794                    (const_int 0)))
9795    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9796         (neg:SWI (match_dup 1)))]
9797   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9798   "neg{<imodesuffix>}\t%0"
9799   [(set_attr "type" "negnot")
9800    (set_attr "mode" "<MODE>")])
9801
9802 (define_insn "*negsi2_cmpz_zext"
9803   [(set (reg:CCZ FLAGS_REG)
9804         (compare:CCZ
9805           (lshiftrt:DI
9806             (neg:DI (ashift:DI
9807                       (match_operand:DI 1 "register_operand" "0")
9808                       (const_int 32)))
9809             (const_int 32))
9810           (const_int 0)))
9811    (set (match_operand:DI 0 "register_operand" "=r")
9812         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9813                                         (const_int 32)))
9814                      (const_int 32)))]
9815   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9816   "neg{l}\t%k0"
9817   [(set_attr "type" "negnot")
9818    (set_attr "mode" "SI")])
9819
9820 ;; Changing of sign for FP values is doable using integer unit too.
9821
9822 (define_expand "<code><mode>2"
9823   [(set (match_operand:X87MODEF 0 "register_operand" "")
9824         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9825   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9826   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9827
9828 (define_insn "*absneg<mode>2_mixed"
9829   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9830         (match_operator:MODEF 3 "absneg_operator"
9831           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9832    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9833    (clobber (reg:CC FLAGS_REG))]
9834   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9835   "#")
9836
9837 (define_insn "*absneg<mode>2_sse"
9838   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9839         (match_operator:MODEF 3 "absneg_operator"
9840           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9841    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9844   "#")
9845
9846 (define_insn "*absneg<mode>2_i387"
9847   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9848         (match_operator:X87MODEF 3 "absneg_operator"
9849           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9850    (use (match_operand 2 "" ""))
9851    (clobber (reg:CC FLAGS_REG))]
9852   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9853   "#")
9854
9855 (define_expand "<code>tf2"
9856   [(set (match_operand:TF 0 "register_operand" "")
9857         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9858   "TARGET_SSE2"
9859   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9860
9861 (define_insn "*absnegtf2_sse"
9862   [(set (match_operand:TF 0 "register_operand" "=x,x")
9863         (match_operator:TF 3 "absneg_operator"
9864           [(match_operand:TF 1 "register_operand" "0,x")]))
9865    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9866    (clobber (reg:CC FLAGS_REG))]
9867   "TARGET_SSE2"
9868   "#")
9869
9870 ;; Splitters for fp abs and neg.
9871
9872 (define_split
9873   [(set (match_operand 0 "fp_register_operand" "")
9874         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9875    (use (match_operand 2 "" ""))
9876    (clobber (reg:CC FLAGS_REG))]
9877   "reload_completed"
9878   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9879
9880 (define_split
9881   [(set (match_operand 0 "register_operand" "")
9882         (match_operator 3 "absneg_operator"
9883           [(match_operand 1 "register_operand" "")]))
9884    (use (match_operand 2 "nonimmediate_operand" ""))
9885    (clobber (reg:CC FLAGS_REG))]
9886   "reload_completed && SSE_REG_P (operands[0])"
9887   [(set (match_dup 0) (match_dup 3))]
9888 {
9889   enum machine_mode mode = GET_MODE (operands[0]);
9890   enum machine_mode vmode = GET_MODE (operands[2]);
9891   rtx tmp;
9892
9893   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9894   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9895   if (operands_match_p (operands[0], operands[2]))
9896     {
9897       tmp = operands[1];
9898       operands[1] = operands[2];
9899       operands[2] = tmp;
9900     }
9901   if (GET_CODE (operands[3]) == ABS)
9902     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9903   else
9904     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9905   operands[3] = tmp;
9906 })
9907
9908 (define_split
9909   [(set (match_operand:SF 0 "register_operand" "")
9910         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9911    (use (match_operand:V4SF 2 "" ""))
9912    (clobber (reg:CC FLAGS_REG))]
9913   "reload_completed"
9914   [(parallel [(set (match_dup 0) (match_dup 1))
9915               (clobber (reg:CC FLAGS_REG))])]
9916 {
9917   rtx tmp;
9918   operands[0] = gen_lowpart (SImode, operands[0]);
9919   if (GET_CODE (operands[1]) == ABS)
9920     {
9921       tmp = gen_int_mode (0x7fffffff, SImode);
9922       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9923     }
9924   else
9925     {
9926       tmp = gen_int_mode (0x80000000, SImode);
9927       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9928     }
9929   operands[1] = tmp;
9930 })
9931
9932 (define_split
9933   [(set (match_operand:DF 0 "register_operand" "")
9934         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9935    (use (match_operand 2 "" ""))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "reload_completed"
9938   [(parallel [(set (match_dup 0) (match_dup 1))
9939               (clobber (reg:CC FLAGS_REG))])]
9940 {
9941   rtx tmp;
9942   if (TARGET_64BIT)
9943     {
9944       tmp = gen_lowpart (DImode, operands[0]);
9945       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9946       operands[0] = tmp;
9947
9948       if (GET_CODE (operands[1]) == ABS)
9949         tmp = const0_rtx;
9950       else
9951         tmp = gen_rtx_NOT (DImode, tmp);
9952     }
9953   else
9954     {
9955       operands[0] = gen_highpart (SImode, operands[0]);
9956       if (GET_CODE (operands[1]) == ABS)
9957         {
9958           tmp = gen_int_mode (0x7fffffff, SImode);
9959           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9960         }
9961       else
9962         {
9963           tmp = gen_int_mode (0x80000000, SImode);
9964           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9965         }
9966     }
9967   operands[1] = tmp;
9968 })
9969
9970 (define_split
9971   [(set (match_operand:XF 0 "register_operand" "")
9972         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9973    (use (match_operand 2 "" ""))
9974    (clobber (reg:CC FLAGS_REG))]
9975   "reload_completed"
9976   [(parallel [(set (match_dup 0) (match_dup 1))
9977               (clobber (reg:CC FLAGS_REG))])]
9978 {
9979   rtx tmp;
9980   operands[0] = gen_rtx_REG (SImode,
9981                              true_regnum (operands[0])
9982                              + (TARGET_64BIT ? 1 : 2));
9983   if (GET_CODE (operands[1]) == ABS)
9984     {
9985       tmp = GEN_INT (0x7fff);
9986       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9987     }
9988   else
9989     {
9990       tmp = GEN_INT (0x8000);
9991       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9992     }
9993   operands[1] = tmp;
9994 })
9995
9996 ;; Conditionalize these after reload. If they match before reload, we
9997 ;; lose the clobber and ability to use integer instructions.
9998
9999 (define_insn "*<code><mode>2_1"
10000   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10001         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10002   "TARGET_80387
10003    && (reload_completed
10004        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10005   "f<absnegprefix>"
10006   [(set_attr "type" "fsgn")
10007    (set_attr "mode" "<MODE>")])
10008
10009 (define_insn "*<code>extendsfdf2"
10010   [(set (match_operand:DF 0 "register_operand" "=f")
10011         (absneg:DF (float_extend:DF
10012                      (match_operand:SF 1 "register_operand" "0"))))]
10013   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10014   "f<absnegprefix>"
10015   [(set_attr "type" "fsgn")
10016    (set_attr "mode" "DF")])
10017
10018 (define_insn "*<code>extendsfxf2"
10019   [(set (match_operand:XF 0 "register_operand" "=f")
10020         (absneg:XF (float_extend:XF
10021                      (match_operand:SF 1 "register_operand" "0"))))]
10022   "TARGET_80387"
10023   "f<absnegprefix>"
10024   [(set_attr "type" "fsgn")
10025    (set_attr "mode" "XF")])
10026
10027 (define_insn "*<code>extenddfxf2"
10028   [(set (match_operand:XF 0 "register_operand" "=f")
10029         (absneg:XF (float_extend:XF
10030                       (match_operand:DF 1 "register_operand" "0"))))]
10031   "TARGET_80387"
10032   "f<absnegprefix>"
10033   [(set_attr "type" "fsgn")
10034    (set_attr "mode" "XF")])
10035
10036 ;; Copysign instructions
10037
10038 (define_mode_iterator CSGNMODE [SF DF TF])
10039 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10040
10041 (define_expand "copysign<mode>3"
10042   [(match_operand:CSGNMODE 0 "register_operand" "")
10043    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10044    (match_operand:CSGNMODE 2 "register_operand" "")]
10045   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10046    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10047 {
10048   ix86_expand_copysign (operands);
10049   DONE;
10050 })
10051
10052 (define_insn_and_split "copysign<mode>3_const"
10053   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10054         (unspec:CSGNMODE
10055           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10056            (match_operand:CSGNMODE 2 "register_operand" "0")
10057            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10058           UNSPEC_COPYSIGN))]
10059   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10060    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10061   "#"
10062   "&& reload_completed"
10063   [(const_int 0)]
10064 {
10065   ix86_split_copysign_const (operands);
10066   DONE;
10067 })
10068
10069 (define_insn "copysign<mode>3_var"
10070   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10071         (unspec:CSGNMODE
10072           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10073            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10074            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10075            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10076           UNSPEC_COPYSIGN))
10077    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10078   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10079    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10080   "#")
10081
10082 (define_split
10083   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10084         (unspec:CSGNMODE
10085           [(match_operand:CSGNMODE 2 "register_operand" "")
10086            (match_operand:CSGNMODE 3 "register_operand" "")
10087            (match_operand:<CSGNVMODE> 4 "" "")
10088            (match_operand:<CSGNVMODE> 5 "" "")]
10089           UNSPEC_COPYSIGN))
10090    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10091   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10092     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10093    && reload_completed"
10094   [(const_int 0)]
10095 {
10096   ix86_split_copysign_var (operands);
10097   DONE;
10098 })
10099 \f
10100 ;; One complement instructions
10101
10102 (define_expand "one_cmpl<mode>2"
10103   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
10104         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
10105   ""
10106   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10107
10108 (define_insn "*one_cmpl<mode>2_1"
10109   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10110         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10111   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10112   "not{<imodesuffix>}\t%0"
10113   [(set_attr "type" "negnot")
10114    (set_attr "mode" "<MODE>")])
10115
10116 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10117 (define_insn "*one_cmplqi2_1"
10118   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10119         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10120   "ix86_unary_operator_ok (NOT, QImode, operands)"
10121   "@
10122    not{b}\t%0
10123    not{l}\t%k0"
10124   [(set_attr "type" "negnot")
10125    (set_attr "mode" "QI,SI")])
10126
10127 ;; ??? Currently never generated - xor is used instead.
10128 (define_insn "*one_cmplsi2_1_zext"
10129   [(set (match_operand:DI 0 "register_operand" "=r")
10130         (zero_extend:DI
10131           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10132   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10133   "not{l}\t%k0"
10134   [(set_attr "type" "negnot")
10135    (set_attr "mode" "SI")])
10136
10137 (define_insn "*one_cmpl<mode>2_2"
10138   [(set (reg FLAGS_REG)
10139         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10140                  (const_int 0)))
10141    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10142         (not:SWI (match_dup 1)))]
10143   "ix86_match_ccmode (insn, CCNOmode)
10144    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10145   "#"
10146   [(set_attr "type" "alu1")
10147    (set_attr "mode" "<MODE>")])
10148
10149 (define_split
10150   [(set (match_operand 0 "flags_reg_operand" "")
10151         (match_operator 2 "compare_operator"
10152           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
10153            (const_int 0)]))
10154    (set (match_operand:SWI 1 "nonimmediate_operand" "")
10155         (not:SWI (match_dup 3)))]
10156   "ix86_match_ccmode (insn, CCNOmode)"
10157   [(parallel [(set (match_dup 0)
10158                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10159                                     (const_int 0)]))
10160               (set (match_dup 1)
10161                    (xor:SWI (match_dup 3) (const_int -1)))])]
10162   "")
10163
10164 ;; ??? Currently never generated - xor is used instead.
10165 (define_insn "*one_cmplsi2_2_zext"
10166   [(set (reg FLAGS_REG)
10167         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10168                  (const_int 0)))
10169    (set (match_operand:DI 0 "register_operand" "=r")
10170         (zero_extend:DI (not:SI (match_dup 1))))]
10171   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10172    && ix86_unary_operator_ok (NOT, SImode, operands)"
10173   "#"
10174   [(set_attr "type" "alu1")
10175    (set_attr "mode" "SI")])
10176
10177 (define_split
10178   [(set (match_operand 0 "flags_reg_operand" "")
10179         (match_operator 2 "compare_operator"
10180           [(not:SI (match_operand:SI 3 "register_operand" ""))
10181            (const_int 0)]))
10182    (set (match_operand:DI 1 "register_operand" "")
10183         (zero_extend:DI (not:SI (match_dup 3))))]
10184   "ix86_match_ccmode (insn, CCNOmode)"
10185   [(parallel [(set (match_dup 0)
10186                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10187                                     (const_int 0)]))
10188               (set (match_dup 1)
10189                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10190   "")
10191 \f
10192 ;; Arithmetic shift instructions
10193
10194 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10195 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10196 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10197 ;; from the assembler input.
10198 ;;
10199 ;; This instruction shifts the target reg/mem as usual, but instead of
10200 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10201 ;; is a left shift double, bits are taken from the high order bits of
10202 ;; reg, else if the insn is a shift right double, bits are taken from the
10203 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10204 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10205 ;;
10206 ;; Since sh[lr]d does not change the `reg' operand, that is done
10207 ;; separately, making all shifts emit pairs of shift double and normal
10208 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10209 ;; support a 63 bit shift, each shift where the count is in a reg expands
10210 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10211 ;;
10212 ;; If the shift count is a constant, we need never emit more than one
10213 ;; shift pair, instead using moves and sign extension for counts greater
10214 ;; than 31.
10215
10216 (define_expand "ashlti3"
10217   [(set (match_operand:TI 0 "register_operand" "")
10218         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10219                    (match_operand:QI 2 "nonmemory_operand" "")))]
10220   "TARGET_64BIT"
10221   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10222
10223 ;; This pattern must be defined before *ashlti3_1 to prevent
10224 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10225
10226 (define_insn "*avx_ashlti3"
10227   [(set (match_operand:TI 0 "register_operand" "=x")
10228         (ashift:TI (match_operand:TI 1 "register_operand" "x")
10229                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10230   "TARGET_AVX"
10231 {
10232   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10233   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10234 }
10235   [(set_attr "type" "sseishft")
10236    (set_attr "prefix" "vex")
10237    (set_attr "length_immediate" "1")
10238    (set_attr "mode" "TI")])
10239
10240 (define_insn "sse2_ashlti3"
10241   [(set (match_operand:TI 0 "register_operand" "=x")
10242         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10243                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10244   "TARGET_SSE2"
10245 {
10246   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10247   return "pslldq\t{%2, %0|%0, %2}";
10248 }
10249   [(set_attr "type" "sseishft")
10250    (set_attr "prefix_data16" "1")
10251    (set_attr "length_immediate" "1")
10252    (set_attr "mode" "TI")])
10253
10254 (define_insn "*ashlti3_1"
10255   [(set (match_operand:TI 0 "register_operand" "=&r,r")
10256         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10257                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10258    (clobber (reg:CC FLAGS_REG))]
10259   "TARGET_64BIT"
10260   "#"
10261   [(set_attr "type" "multi")])
10262
10263 (define_peephole2
10264   [(match_scratch:DI 3 "r")
10265    (parallel [(set (match_operand:TI 0 "register_operand" "")
10266                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10267                               (match_operand:QI 2 "nonmemory_operand" "")))
10268               (clobber (reg:CC FLAGS_REG))])
10269    (match_dup 3)]
10270   "TARGET_64BIT"
10271   [(const_int 0)]
10272   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10273
10274 (define_split
10275   [(set (match_operand:TI 0 "register_operand" "")
10276         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10277                    (match_operand:QI 2 "nonmemory_operand" "")))
10278    (clobber (reg:CC FLAGS_REG))]
10279   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10280                     ? epilogue_completed : reload_completed)"
10281   [(const_int 0)]
10282   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10283
10284 (define_insn "x86_64_shld"
10285   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10286         (ior:DI (ashift:DI (match_dup 0)
10287                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10288                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10289                   (minus:QI (const_int 64) (match_dup 2)))))
10290    (clobber (reg:CC FLAGS_REG))]
10291   "TARGET_64BIT"
10292   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10293   [(set_attr "type" "ishift")
10294    (set_attr "prefix_0f" "1")
10295    (set_attr "mode" "DI")
10296    (set_attr "athlon_decode" "vector")
10297    (set_attr "amdfam10_decode" "vector")])
10298
10299 (define_expand "x86_64_shift_adj_1"
10300   [(set (reg:CCZ FLAGS_REG)
10301         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10302                              (const_int 64))
10303                      (const_int 0)))
10304    (set (match_operand:DI 0 "register_operand" "")
10305         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10306                          (match_operand:DI 1 "register_operand" "")
10307                          (match_dup 0)))
10308    (set (match_dup 1)
10309         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10310                          (match_operand:DI 3 "register_operand" "r")
10311                          (match_dup 1)))]
10312   "TARGET_64BIT"
10313   "")
10314
10315 (define_expand "x86_64_shift_adj_2"
10316   [(use (match_operand:DI 0 "register_operand" ""))
10317    (use (match_operand:DI 1 "register_operand" ""))
10318    (use (match_operand:QI 2 "register_operand" ""))]
10319   "TARGET_64BIT"
10320 {
10321   rtx label = gen_label_rtx ();
10322   rtx tmp;
10323
10324   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10325
10326   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10327   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10328   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10329                               gen_rtx_LABEL_REF (VOIDmode, label),
10330                               pc_rtx);
10331   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10332   JUMP_LABEL (tmp) = label;
10333
10334   emit_move_insn (operands[0], operands[1]);
10335   ix86_expand_clear (operands[1]);
10336
10337   emit_label (label);
10338   LABEL_NUSES (label) = 1;
10339
10340   DONE;
10341 })
10342
10343 (define_expand "ashldi3"
10344   [(set (match_operand:DI 0 "shiftdi_operand" "")
10345         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10346                    (match_operand:QI 2 "nonmemory_operand" "")))]
10347   ""
10348   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10349
10350 (define_insn "*ashldi3_1_rex64"
10351   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10352         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10353                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10354    (clobber (reg:CC FLAGS_REG))]
10355   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10356 {
10357   switch (get_attr_type (insn))
10358     {
10359     case TYPE_ALU:
10360       gcc_assert (operands[2] == const1_rtx);
10361       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10362       return "add{q}\t%0, %0";
10363
10364     case TYPE_LEA:
10365       gcc_assert (CONST_INT_P (operands[2]));
10366       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10367       operands[1] = gen_rtx_MULT (DImode, operands[1],
10368                                   GEN_INT (1 << INTVAL (operands[2])));
10369       return "lea{q}\t{%a1, %0|%0, %a1}";
10370
10371     default:
10372       if (REG_P (operands[2]))
10373         return "sal{q}\t{%b2, %0|%0, %b2}";
10374       else if (operands[2] == const1_rtx
10375                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10376         return "sal{q}\t%0";
10377       else
10378         return "sal{q}\t{%2, %0|%0, %2}";
10379     }
10380 }
10381   [(set (attr "type")
10382      (cond [(eq_attr "alternative" "1")
10383               (const_string "lea")
10384             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10385                           (const_int 0))
10386                       (match_operand 0 "register_operand" ""))
10387                  (match_operand 2 "const1_operand" ""))
10388               (const_string "alu")
10389            ]
10390            (const_string "ishift")))
10391    (set (attr "length_immediate")
10392      (if_then_else
10393        (ior (eq_attr "type" "alu")
10394             (and (eq_attr "type" "ishift")
10395                  (and (match_operand 2 "const1_operand" "")
10396                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10397                           (const_int 0)))))
10398        (const_string "0")
10399        (const_string "*")))
10400    (set_attr "mode" "DI")])
10401
10402 ;; Convert lea to the lea pattern to avoid flags dependency.
10403 (define_split
10404   [(set (match_operand:DI 0 "register_operand" "")
10405         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10406                    (match_operand:QI 2 "immediate_operand" "")))
10407    (clobber (reg:CC FLAGS_REG))]
10408   "TARGET_64BIT && reload_completed
10409    && true_regnum (operands[0]) != true_regnum (operands[1])"
10410   [(set (match_dup 0)
10411         (mult:DI (match_dup 1)
10412                  (match_dup 2)))]
10413   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10414
10415 ;; This pattern can't accept a variable shift count, since shifts by
10416 ;; zero don't affect the flags.  We assume that shifts by constant
10417 ;; zero are optimized away.
10418 (define_insn "*ashldi3_cmp_rex64"
10419   [(set (reg FLAGS_REG)
10420         (compare
10421           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10422                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10423           (const_int 0)))
10424    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10425         (ashift:DI (match_dup 1) (match_dup 2)))]
10426   "TARGET_64BIT
10427    && (optimize_function_for_size_p (cfun)
10428        || !TARGET_PARTIAL_FLAG_REG_STALL
10429        || (operands[2] == const1_rtx
10430            && (TARGET_SHIFT1
10431                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10432    && ix86_match_ccmode (insn, CCGOCmode)
10433    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10434 {
10435   switch (get_attr_type (insn))
10436     {
10437     case TYPE_ALU:
10438       gcc_assert (operands[2] == const1_rtx);
10439       return "add{q}\t%0, %0";
10440
10441     default:
10442       if (REG_P (operands[2]))
10443         return "sal{q}\t{%b2, %0|%0, %b2}";
10444       else if (operands[2] == const1_rtx
10445                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10446         return "sal{q}\t%0";
10447       else
10448         return "sal{q}\t{%2, %0|%0, %2}";
10449     }
10450 }
10451   [(set (attr "type")
10452      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10453                           (const_int 0))
10454                       (match_operand 0 "register_operand" ""))
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" "DI")])
10469
10470 (define_insn "*ashldi3_cconly_rex64"
10471   [(set (reg FLAGS_REG)
10472         (compare
10473           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10474                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10475           (const_int 0)))
10476    (clobber (match_scratch:DI 0 "=r"))]
10477   "TARGET_64BIT
10478    && (optimize_function_for_size_p (cfun)
10479        || !TARGET_PARTIAL_FLAG_REG_STALL
10480        || (operands[2] == const1_rtx
10481            && (TARGET_SHIFT1
10482                || TARGET_DOUBLE_WITH_ADD)))
10483    && ix86_match_ccmode (insn, CCGOCmode)
10484    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10485 {
10486   switch (get_attr_type (insn))
10487     {
10488     case TYPE_ALU:
10489       gcc_assert (operands[2] == const1_rtx);
10490       return "add{q}\t%0, %0";
10491
10492     default:
10493       if (REG_P (operands[2]))
10494         return "sal{q}\t{%b2, %0|%0, %b2}";
10495       else if (operands[2] == const1_rtx
10496                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10497         return "sal{q}\t%0";
10498       else
10499         return "sal{q}\t{%2, %0|%0, %2}";
10500     }
10501 }
10502   [(set (attr "type")
10503      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10504                           (const_int 0))
10505                       (match_operand 0 "register_operand" ""))
10506                  (match_operand 2 "const1_operand" ""))
10507               (const_string "alu")
10508            ]
10509            (const_string "ishift")))
10510    (set (attr "length_immediate")
10511      (if_then_else
10512        (ior (eq_attr "type" "alu")
10513             (and (eq_attr "type" "ishift")
10514                  (and (match_operand 2 "const1_operand" "")
10515                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10516                           (const_int 0)))))
10517        (const_string "0")
10518        (const_string "*")))
10519    (set_attr "mode" "DI")])
10520
10521 (define_insn "*ashldi3_1"
10522   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10523         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10524                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10525    (clobber (reg:CC FLAGS_REG))]
10526   "!TARGET_64BIT"
10527   "#"
10528   [(set_attr "type" "multi")])
10529
10530 ;; By default we don't ask for a scratch register, because when DImode
10531 ;; values are manipulated, registers are already at a premium.  But if
10532 ;; we have one handy, we won't turn it away.
10533 (define_peephole2
10534   [(match_scratch:SI 3 "r")
10535    (parallel [(set (match_operand:DI 0 "register_operand" "")
10536                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10537                               (match_operand:QI 2 "nonmemory_operand" "")))
10538               (clobber (reg:CC FLAGS_REG))])
10539    (match_dup 3)]
10540   "!TARGET_64BIT && TARGET_CMOVE"
10541   [(const_int 0)]
10542   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10543
10544 (define_split
10545   [(set (match_operand:DI 0 "register_operand" "")
10546         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10547                    (match_operand:QI 2 "nonmemory_operand" "")))
10548    (clobber (reg:CC FLAGS_REG))]
10549   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10550                      ? epilogue_completed : reload_completed)"
10551   [(const_int 0)]
10552   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10553
10554 (define_insn "x86_shld"
10555   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10556         (ior:SI (ashift:SI (match_dup 0)
10557                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10558                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10559                   (minus:QI (const_int 32) (match_dup 2)))))
10560    (clobber (reg:CC FLAGS_REG))]
10561   ""
10562   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10563   [(set_attr "type" "ishift")
10564    (set_attr "prefix_0f" "1")
10565    (set_attr "mode" "SI")
10566    (set_attr "pent_pair" "np")
10567    (set_attr "athlon_decode" "vector")
10568    (set_attr "amdfam10_decode" "vector")])
10569
10570 (define_expand "x86_shift_adj_1"
10571   [(set (reg:CCZ FLAGS_REG)
10572         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10573                              (const_int 32))
10574                      (const_int 0)))
10575    (set (match_operand:SI 0 "register_operand" "")
10576         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10577                          (match_operand:SI 1 "register_operand" "")
10578                          (match_dup 0)))
10579    (set (match_dup 1)
10580         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10581                          (match_operand:SI 3 "register_operand" "r")
10582                          (match_dup 1)))]
10583   "TARGET_CMOVE"
10584   "")
10585
10586 (define_expand "x86_shift_adj_2"
10587   [(use (match_operand:SI 0 "register_operand" ""))
10588    (use (match_operand:SI 1 "register_operand" ""))
10589    (use (match_operand:QI 2 "register_operand" ""))]
10590   ""
10591 {
10592   rtx label = gen_label_rtx ();
10593   rtx tmp;
10594
10595   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10596
10597   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10598   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10599   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10600                               gen_rtx_LABEL_REF (VOIDmode, label),
10601                               pc_rtx);
10602   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10603   JUMP_LABEL (tmp) = label;
10604
10605   emit_move_insn (operands[0], operands[1]);
10606   ix86_expand_clear (operands[1]);
10607
10608   emit_label (label);
10609   LABEL_NUSES (label) = 1;
10610
10611   DONE;
10612 })
10613
10614 (define_expand "ashlsi3"
10615   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10616         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10617                    (match_operand:QI 2 "nonmemory_operand" "")))]
10618   ""
10619   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10620
10621 (define_insn "*ashlsi3_1"
10622   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10623         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10624                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10627 {
10628   switch (get_attr_type (insn))
10629     {
10630     case TYPE_ALU:
10631       gcc_assert (operands[2] == const1_rtx);
10632       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10633       return "add{l}\t%0, %0";
10634
10635     case TYPE_LEA:
10636       return "#";
10637
10638     default:
10639       if (REG_P (operands[2]))
10640         return "sal{l}\t{%b2, %0|%0, %b2}";
10641       else if (operands[2] == const1_rtx
10642                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10643         return "sal{l}\t%0";
10644       else
10645         return "sal{l}\t{%2, %0|%0, %2}";
10646     }
10647 }
10648   [(set (attr "type")
10649      (cond [(eq_attr "alternative" "1")
10650               (const_string "lea")
10651             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10652                           (const_int 0))
10653                       (match_operand 0 "register_operand" ""))
10654                  (match_operand 2 "const1_operand" ""))
10655               (const_string "alu")
10656            ]
10657            (const_string "ishift")))
10658    (set (attr "length_immediate")
10659      (if_then_else
10660        (ior (eq_attr "type" "alu")
10661             (and (eq_attr "type" "ishift")
10662                  (and (match_operand 2 "const1_operand" "")
10663                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10664                           (const_int 0)))))
10665        (const_string "0")
10666        (const_string "*")))
10667    (set_attr "mode" "SI")])
10668
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10670 (define_split
10671   [(set (match_operand 0 "register_operand" "")
10672         (ashift (match_operand 1 "index_register_operand" "")
10673                 (match_operand:QI 2 "const_int_operand" "")))
10674    (clobber (reg:CC FLAGS_REG))]
10675   "reload_completed
10676    && true_regnum (operands[0]) != true_regnum (operands[1])
10677    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10678   [(const_int 0)]
10679 {
10680   rtx pat;
10681   enum machine_mode mode = GET_MODE (operands[0]);
10682
10683   if (GET_MODE_SIZE (mode) < 4)
10684     operands[0] = gen_lowpart (SImode, operands[0]);
10685   if (mode != Pmode)
10686     operands[1] = gen_lowpart (Pmode, operands[1]);
10687   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10688
10689   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690   if (Pmode != SImode)
10691     pat = gen_rtx_SUBREG (SImode, pat, 0);
10692   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10693   DONE;
10694 })
10695
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10697 (define_split
10698   [(set (match_operand 0 "register_operand" "")
10699         (ashift (match_operand 1 "register_operand" "")
10700                 (match_operand:QI 2 "const_int_operand" "")))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "reload_completed
10703    && true_regnum (operands[0]) != true_regnum (operands[1])"
10704   [(const_int 0)]
10705 {
10706   rtx pat, clob;
10707   emit_move_insn (operands[0], operands[1]);
10708   pat = gen_rtx_SET (VOIDmode, operands[0],
10709                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710                                      operands[0], operands[2]));
10711   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10713   DONE;
10714 })
10715
10716 (define_insn "*ashlsi3_1_zext"
10717   [(set (match_operand:DI 0 "register_operand" "=r,r")
10718         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10722 {
10723   switch (get_attr_type (insn))
10724     {
10725     case TYPE_ALU:
10726       gcc_assert (operands[2] == const1_rtx);
10727       return "add{l}\t%k0, %k0";
10728
10729     case TYPE_LEA:
10730       return "#";
10731
10732     default:
10733       if (REG_P (operands[2]))
10734         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10737         return "sal{l}\t%k0";
10738       else
10739         return "sal{l}\t{%2, %k0|%k0, %2}";
10740     }
10741 }
10742   [(set (attr "type")
10743      (cond [(eq_attr "alternative" "1")
10744               (const_string "lea")
10745             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746                      (const_int 0))
10747                  (match_operand 2 "const1_operand" ""))
10748               (const_string "alu")
10749            ]
10750            (const_string "ishift")))
10751    (set (attr "length_immediate")
10752      (if_then_else
10753        (ior (eq_attr "type" "alu")
10754             (and (eq_attr "type" "ishift")
10755                  (and (match_operand 2 "const1_operand" "")
10756                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10757                           (const_int 0)))))
10758        (const_string "0")
10759        (const_string "*")))
10760    (set_attr "mode" "SI")])
10761
10762 ;; Convert lea to the lea pattern to avoid flags dependency.
10763 (define_split
10764   [(set (match_operand:DI 0 "register_operand" "")
10765         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10766                                 (match_operand:QI 2 "const_int_operand" ""))))
10767    (clobber (reg:CC FLAGS_REG))]
10768   "TARGET_64BIT && reload_completed
10769    && true_regnum (operands[0]) != true_regnum (operands[1])"
10770   [(set (match_dup 0) (zero_extend:DI
10771                         (subreg:SI (mult:SI (match_dup 1)
10772                                             (match_dup 2)) 0)))]
10773 {
10774   operands[1] = gen_lowpart (Pmode, operands[1]);
10775   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10776 })
10777
10778 ;; This pattern can't accept a variable shift count, since shifts by
10779 ;; zero don't affect the flags.  We assume that shifts by constant
10780 ;; zero are optimized away.
10781 (define_insn "*ashlsi3_cmp"
10782   [(set (reg FLAGS_REG)
10783         (compare
10784           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10785                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10786           (const_int 0)))
10787    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10788         (ashift:SI (match_dup 1) (match_dup 2)))]
10789    "(optimize_function_for_size_p (cfun)
10790      || !TARGET_PARTIAL_FLAG_REG_STALL
10791      || (operands[2] == const1_rtx
10792          && (TARGET_SHIFT1
10793              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10794    && ix86_match_ccmode (insn, CCGOCmode)
10795    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10796 {
10797   switch (get_attr_type (insn))
10798     {
10799     case TYPE_ALU:
10800       gcc_assert (operands[2] == const1_rtx);
10801       return "add{l}\t%0, %0";
10802
10803     default:
10804       if (REG_P (operands[2]))
10805         return "sal{l}\t{%b2, %0|%0, %b2}";
10806       else if (operands[2] == const1_rtx
10807                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10808         return "sal{l}\t%0";
10809       else
10810         return "sal{l}\t{%2, %0|%0, %2}";
10811     }
10812 }
10813   [(set (attr "type")
10814      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10815                           (const_int 0))
10816                       (match_operand 0 "register_operand" ""))
10817                  (match_operand 2 "const1_operand" ""))
10818               (const_string "alu")
10819            ]
10820            (const_string "ishift")))
10821    (set (attr "length_immediate")
10822      (if_then_else
10823        (ior (eq_attr "type" "alu")
10824             (and (eq_attr "type" "ishift")
10825                  (and (match_operand 2 "const1_operand" "")
10826                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10827                           (const_int 0)))))
10828        (const_string "0")
10829        (const_string "*")))
10830    (set_attr "mode" "SI")])
10831
10832 (define_insn "*ashlsi3_cconly"
10833   [(set (reg FLAGS_REG)
10834         (compare
10835           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10836                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10837           (const_int 0)))
10838    (clobber (match_scratch:SI 0 "=r"))]
10839   "(optimize_function_for_size_p (cfun)
10840     || !TARGET_PARTIAL_FLAG_REG_STALL
10841     || (operands[2] == const1_rtx
10842         && (TARGET_SHIFT1
10843             || TARGET_DOUBLE_WITH_ADD)))
10844    && ix86_match_ccmode (insn, CCGOCmode)
10845    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10846 {
10847   switch (get_attr_type (insn))
10848     {
10849     case TYPE_ALU:
10850       gcc_assert (operands[2] == const1_rtx);
10851       return "add{l}\t%0, %0";
10852
10853     default:
10854       if (REG_P (operands[2]))
10855         return "sal{l}\t{%b2, %0|%0, %b2}";
10856       else if (operands[2] == const1_rtx
10857                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10858         return "sal{l}\t%0";
10859       else
10860         return "sal{l}\t{%2, %0|%0, %2}";
10861     }
10862 }
10863   [(set (attr "type")
10864      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10865                           (const_int 0))
10866                       (match_operand 0 "register_operand" ""))
10867                  (match_operand 2 "const1_operand" ""))
10868               (const_string "alu")
10869            ]
10870            (const_string "ishift")))
10871    (set (attr "length_immediate")
10872      (if_then_else
10873        (ior (eq_attr "type" "alu")
10874             (and (eq_attr "type" "ishift")
10875                  (and (match_operand 2 "const1_operand" "")
10876                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10877                           (const_int 0)))))
10878        (const_string "0")
10879        (const_string "*")))
10880    (set_attr "mode" "SI")])
10881
10882 (define_insn "*ashlsi3_cmp_zext"
10883   [(set (reg FLAGS_REG)
10884         (compare
10885           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10886                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10887           (const_int 0)))
10888    (set (match_operand:DI 0 "register_operand" "=r")
10889         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10890   "TARGET_64BIT
10891    && (optimize_function_for_size_p (cfun)
10892        || !TARGET_PARTIAL_FLAG_REG_STALL
10893        || (operands[2] == const1_rtx
10894            && (TARGET_SHIFT1
10895                || TARGET_DOUBLE_WITH_ADD)))
10896    && ix86_match_ccmode (insn, CCGOCmode)
10897    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10898 {
10899   switch (get_attr_type (insn))
10900     {
10901     case TYPE_ALU:
10902       gcc_assert (operands[2] == const1_rtx);
10903       return "add{l}\t%k0, %k0";
10904
10905     default:
10906       if (REG_P (operands[2]))
10907         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10908       else if (operands[2] == const1_rtx
10909                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10910         return "sal{l}\t%k0";
10911       else
10912         return "sal{l}\t{%2, %k0|%k0, %2}";
10913     }
10914 }
10915   [(set (attr "type")
10916      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10917                      (const_int 0))
10918                  (match_operand 2 "const1_operand" ""))
10919               (const_string "alu")
10920            ]
10921            (const_string "ishift")))
10922    (set (attr "length_immediate")
10923      (if_then_else
10924        (ior (eq_attr "type" "alu")
10925             (and (eq_attr "type" "ishift")
10926                  (and (match_operand 2 "const1_operand" "")
10927                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10928                           (const_int 0)))))
10929        (const_string "0")
10930        (const_string "*")))
10931    (set_attr "mode" "SI")])
10932
10933 (define_expand "ashlhi3"
10934   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10935         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10936                    (match_operand:QI 2 "nonmemory_operand" "")))]
10937   "TARGET_HIMODE_MATH"
10938   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10939
10940 (define_insn "*ashlhi3_1_lea"
10941   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10942         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10943                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10944    (clobber (reg:CC FLAGS_REG))]
10945   "!TARGET_PARTIAL_REG_STALL
10946    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10947 {
10948   switch (get_attr_type (insn))
10949     {
10950     case TYPE_LEA:
10951       return "#";
10952     case TYPE_ALU:
10953       gcc_assert (operands[2] == const1_rtx);
10954       return "add{w}\t%0, %0";
10955
10956     default:
10957       if (REG_P (operands[2]))
10958         return "sal{w}\t{%b2, %0|%0, %b2}";
10959       else if (operands[2] == const1_rtx
10960                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10961         return "sal{w}\t%0";
10962       else
10963         return "sal{w}\t{%2, %0|%0, %2}";
10964     }
10965 }
10966   [(set (attr "type")
10967      (cond [(eq_attr "alternative" "1")
10968               (const_string "lea")
10969             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10970                           (const_int 0))
10971                       (match_operand 0 "register_operand" ""))
10972                  (match_operand 2 "const1_operand" ""))
10973               (const_string "alu")
10974            ]
10975            (const_string "ishift")))
10976    (set (attr "length_immediate")
10977      (if_then_else
10978        (ior (eq_attr "type" "alu")
10979             (and (eq_attr "type" "ishift")
10980                  (and (match_operand 2 "const1_operand" "")
10981                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10982                           (const_int 0)))))
10983        (const_string "0")
10984        (const_string "*")))
10985    (set_attr "mode" "HI,SI")])
10986
10987 (define_insn "*ashlhi3_1"
10988   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10990                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10991    (clobber (reg:CC FLAGS_REG))]
10992   "TARGET_PARTIAL_REG_STALL
10993    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10994 {
10995   switch (get_attr_type (insn))
10996     {
10997     case TYPE_ALU:
10998       gcc_assert (operands[2] == const1_rtx);
10999       return "add{w}\t%0, %0";
11000
11001     default:
11002       if (REG_P (operands[2]))
11003         return "sal{w}\t{%b2, %0|%0, %b2}";
11004       else if (operands[2] == const1_rtx
11005                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11006         return "sal{w}\t%0";
11007       else
11008         return "sal{w}\t{%2, %0|%0, %2}";
11009     }
11010 }
11011   [(set (attr "type")
11012      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013                           (const_int 0))
11014                       (match_operand 0 "register_operand" ""))
11015                  (match_operand 2 "const1_operand" ""))
11016               (const_string "alu")
11017            ]
11018            (const_string "ishift")))
11019    (set (attr "length_immediate")
11020      (if_then_else
11021        (ior (eq_attr "type" "alu")
11022             (and (eq_attr "type" "ishift")
11023                  (and (match_operand 2 "const1_operand" "")
11024                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11025                           (const_int 0)))))
11026        (const_string "0")
11027        (const_string "*")))
11028    (set_attr "mode" "HI")])
11029
11030 ;; This pattern can't accept a variable shift count, since shifts by
11031 ;; zero don't affect the flags.  We assume that shifts by constant
11032 ;; zero are optimized away.
11033 (define_insn "*ashlhi3_cmp"
11034   [(set (reg FLAGS_REG)
11035         (compare
11036           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11037                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11038           (const_int 0)))
11039    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11040         (ashift:HI (match_dup 1) (match_dup 2)))]
11041   "(optimize_function_for_size_p (cfun)
11042     || !TARGET_PARTIAL_FLAG_REG_STALL
11043     || (operands[2] == const1_rtx
11044         && (TARGET_SHIFT1
11045             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11046    && ix86_match_ccmode (insn, CCGOCmode)
11047    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11048 {
11049   switch (get_attr_type (insn))
11050     {
11051     case TYPE_ALU:
11052       gcc_assert (operands[2] == const1_rtx);
11053       return "add{w}\t%0, %0";
11054
11055     default:
11056       if (REG_P (operands[2]))
11057         return "sal{w}\t{%b2, %0|%0, %b2}";
11058       else if (operands[2] == const1_rtx
11059                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11060         return "sal{w}\t%0";
11061       else
11062         return "sal{w}\t{%2, %0|%0, %2}";
11063     }
11064 }
11065   [(set (attr "type")
11066      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11067                           (const_int 0))
11068                       (match_operand 0 "register_operand" ""))
11069                  (match_operand 2 "const1_operand" ""))
11070               (const_string "alu")
11071            ]
11072            (const_string "ishift")))
11073    (set (attr "length_immediate")
11074      (if_then_else
11075        (ior (eq_attr "type" "alu")
11076             (and (eq_attr "type" "ishift")
11077                  (and (match_operand 2 "const1_operand" "")
11078                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11079                           (const_int 0)))))
11080        (const_string "0")
11081        (const_string "*")))
11082    (set_attr "mode" "HI")])
11083
11084 (define_insn "*ashlhi3_cconly"
11085   [(set (reg FLAGS_REG)
11086         (compare
11087           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11088                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11089           (const_int 0)))
11090    (clobber (match_scratch:HI 0 "=r"))]
11091   "(optimize_function_for_size_p (cfun)
11092     || !TARGET_PARTIAL_FLAG_REG_STALL
11093     || (operands[2] == const1_rtx
11094         && (TARGET_SHIFT1
11095             || TARGET_DOUBLE_WITH_ADD)))
11096    && ix86_match_ccmode (insn, CCGOCmode)
11097    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11098 {
11099   switch (get_attr_type (insn))
11100     {
11101     case TYPE_ALU:
11102       gcc_assert (operands[2] == const1_rtx);
11103       return "add{w}\t%0, %0";
11104
11105     default:
11106       if (REG_P (operands[2]))
11107         return "sal{w}\t{%b2, %0|%0, %b2}";
11108       else if (operands[2] == const1_rtx
11109                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11110         return "sal{w}\t%0";
11111       else
11112         return "sal{w}\t{%2, %0|%0, %2}";
11113     }
11114 }
11115   [(set (attr "type")
11116      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11117                           (const_int 0))
11118                       (match_operand 0 "register_operand" ""))
11119                  (match_operand 2 "const1_operand" ""))
11120               (const_string "alu")
11121            ]
11122            (const_string "ishift")))
11123    (set (attr "length_immediate")
11124      (if_then_else
11125        (ior (eq_attr "type" "alu")
11126             (and (eq_attr "type" "ishift")
11127                  (and (match_operand 2 "const1_operand" "")
11128                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11129                           (const_int 0)))))
11130        (const_string "0")
11131        (const_string "*")))
11132    (set_attr "mode" "HI")])
11133
11134 (define_expand "ashlqi3"
11135   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11136         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11137                    (match_operand:QI 2 "nonmemory_operand" "")))]
11138   "TARGET_QIMODE_MATH"
11139   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11140
11141 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11142
11143 (define_insn "*ashlqi3_1_lea"
11144   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11145         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11146                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11147    (clobber (reg:CC FLAGS_REG))]
11148   "!TARGET_PARTIAL_REG_STALL
11149    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11150 {
11151   switch (get_attr_type (insn))
11152     {
11153     case TYPE_LEA:
11154       return "#";
11155     case TYPE_ALU:
11156       gcc_assert (operands[2] == const1_rtx);
11157       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11158         return "add{l}\t%k0, %k0";
11159       else
11160         return "add{b}\t%0, %0";
11161
11162     default:
11163       if (REG_P (operands[2]))
11164         {
11165           if (get_attr_mode (insn) == MODE_SI)
11166             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11167           else
11168             return "sal{b}\t{%b2, %0|%0, %b2}";
11169         }
11170       else if (operands[2] == const1_rtx
11171                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11172         {
11173           if (get_attr_mode (insn) == MODE_SI)
11174             return "sal{l}\t%0";
11175           else
11176             return "sal{b}\t%0";
11177         }
11178       else
11179         {
11180           if (get_attr_mode (insn) == MODE_SI)
11181             return "sal{l}\t{%2, %k0|%k0, %2}";
11182           else
11183             return "sal{b}\t{%2, %0|%0, %2}";
11184         }
11185     }
11186 }
11187   [(set (attr "type")
11188      (cond [(eq_attr "alternative" "2")
11189               (const_string "lea")
11190             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11191                           (const_int 0))
11192                       (match_operand 0 "register_operand" ""))
11193                  (match_operand 2 "const1_operand" ""))
11194               (const_string "alu")
11195            ]
11196            (const_string "ishift")))
11197    (set (attr "length_immediate")
11198      (if_then_else
11199        (ior (eq_attr "type" "alu")
11200             (and (eq_attr "type" "ishift")
11201                  (and (match_operand 2 "const1_operand" "")
11202                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11203                           (const_int 0)))))
11204        (const_string "0")
11205        (const_string "*")))
11206    (set_attr "mode" "QI,SI,SI")])
11207
11208 (define_insn "*ashlqi3_1"
11209   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11210         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11211                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11212    (clobber (reg:CC FLAGS_REG))]
11213   "TARGET_PARTIAL_REG_STALL
11214    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11215 {
11216   switch (get_attr_type (insn))
11217     {
11218     case TYPE_ALU:
11219       gcc_assert (operands[2] == const1_rtx);
11220       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11221         return "add{l}\t%k0, %k0";
11222       else
11223         return "add{b}\t%0, %0";
11224
11225     default:
11226       if (REG_P (operands[2]))
11227         {
11228           if (get_attr_mode (insn) == MODE_SI)
11229             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11230           else
11231             return "sal{b}\t{%b2, %0|%0, %b2}";
11232         }
11233       else if (operands[2] == const1_rtx
11234                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11235         {
11236           if (get_attr_mode (insn) == MODE_SI)
11237             return "sal{l}\t%0";
11238           else
11239             return "sal{b}\t%0";
11240         }
11241       else
11242         {
11243           if (get_attr_mode (insn) == MODE_SI)
11244             return "sal{l}\t{%2, %k0|%k0, %2}";
11245           else
11246             return "sal{b}\t{%2, %0|%0, %2}";
11247         }
11248     }
11249 }
11250   [(set (attr "type")
11251      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11252                           (const_int 0))
11253                       (match_operand 0 "register_operand" ""))
11254                  (match_operand 2 "const1_operand" ""))
11255               (const_string "alu")
11256            ]
11257            (const_string "ishift")))
11258    (set (attr "length_immediate")
11259      (if_then_else
11260        (ior (eq_attr "type" "alu")
11261             (and (eq_attr "type" "ishift")
11262                  (and (match_operand 2 "const1_operand" "")
11263                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11264                           (const_int 0)))))
11265        (const_string "0")
11266        (const_string "*")))
11267    (set_attr "mode" "QI,SI")])
11268
11269 ;; This pattern can't accept a variable shift count, since shifts by
11270 ;; zero don't affect the flags.  We assume that shifts by constant
11271 ;; zero are optimized away.
11272 (define_insn "*ashlqi3_cmp"
11273   [(set (reg FLAGS_REG)
11274         (compare
11275           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11276                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11277           (const_int 0)))
11278    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11279         (ashift:QI (match_dup 1) (match_dup 2)))]
11280   "(optimize_function_for_size_p (cfun)
11281     || !TARGET_PARTIAL_FLAG_REG_STALL
11282     || (operands[2] == const1_rtx
11283         && (TARGET_SHIFT1
11284             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11285    && ix86_match_ccmode (insn, CCGOCmode)
11286    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11287 {
11288   switch (get_attr_type (insn))
11289     {
11290     case TYPE_ALU:
11291       gcc_assert (operands[2] == const1_rtx);
11292       return "add{b}\t%0, %0";
11293
11294     default:
11295       if (REG_P (operands[2]))
11296         return "sal{b}\t{%b2, %0|%0, %b2}";
11297       else if (operands[2] == const1_rtx
11298                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11299         return "sal{b}\t%0";
11300       else
11301         return "sal{b}\t{%2, %0|%0, %2}";
11302     }
11303 }
11304   [(set (attr "type")
11305      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11306                           (const_int 0))
11307                       (match_operand 0 "register_operand" ""))
11308                  (match_operand 2 "const1_operand" ""))
11309               (const_string "alu")
11310            ]
11311            (const_string "ishift")))
11312    (set (attr "length_immediate")
11313      (if_then_else
11314        (ior (eq_attr "type" "alu")
11315             (and (eq_attr "type" "ishift")
11316                  (and (match_operand 2 "const1_operand" "")
11317                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11318                           (const_int 0)))))
11319        (const_string "0")
11320        (const_string "*")))
11321    (set_attr "mode" "QI")])
11322
11323 (define_insn "*ashlqi3_cconly"
11324   [(set (reg FLAGS_REG)
11325         (compare
11326           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11327                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11328           (const_int 0)))
11329    (clobber (match_scratch:QI 0 "=q"))]
11330   "(optimize_function_for_size_p (cfun)
11331     || !TARGET_PARTIAL_FLAG_REG_STALL
11332     || (operands[2] == const1_rtx
11333         && (TARGET_SHIFT1
11334             || TARGET_DOUBLE_WITH_ADD)))
11335    && ix86_match_ccmode (insn, CCGOCmode)
11336    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11337 {
11338   switch (get_attr_type (insn))
11339     {
11340     case TYPE_ALU:
11341       gcc_assert (operands[2] == const1_rtx);
11342       return "add{b}\t%0, %0";
11343
11344     default:
11345       if (REG_P (operands[2]))
11346         return "sal{b}\t{%b2, %0|%0, %b2}";
11347       else if (operands[2] == const1_rtx
11348                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11349         return "sal{b}\t%0";
11350       else
11351         return "sal{b}\t{%2, %0|%0, %2}";
11352     }
11353 }
11354   [(set (attr "type")
11355      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11356                           (const_int 0))
11357                       (match_operand 0 "register_operand" ""))
11358                  (match_operand 2 "const1_operand" ""))
11359               (const_string "alu")
11360            ]
11361            (const_string "ishift")))
11362    (set (attr "length_immediate")
11363      (if_then_else
11364        (ior (eq_attr "type" "alu")
11365             (and (eq_attr "type" "ishift")
11366                  (and (match_operand 2 "const1_operand" "")
11367                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11368                           (const_int 0)))))
11369        (const_string "0")
11370        (const_string "*")))
11371    (set_attr "mode" "QI")])
11372
11373 ;; See comment above `ashldi3' about how this works.
11374
11375 (define_expand "ashrti3"
11376   [(set (match_operand:TI 0 "register_operand" "")
11377         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))]
11379   "TARGET_64BIT"
11380   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11381
11382 (define_insn "*ashrti3_1"
11383   [(set (match_operand:TI 0 "register_operand" "=r")
11384         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11385                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11386    (clobber (reg:CC FLAGS_REG))]
11387   "TARGET_64BIT"
11388   "#"
11389   [(set_attr "type" "multi")])
11390
11391 (define_peephole2
11392   [(match_scratch:DI 3 "r")
11393    (parallel [(set (match_operand:TI 0 "register_operand" "")
11394                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11395                                 (match_operand:QI 2 "nonmemory_operand" "")))
11396               (clobber (reg:CC FLAGS_REG))])
11397    (match_dup 3)]
11398   "TARGET_64BIT"
11399   [(const_int 0)]
11400   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11401
11402 (define_split
11403   [(set (match_operand:TI 0 "register_operand" "")
11404         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11405                      (match_operand:QI 2 "nonmemory_operand" "")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11408                     ? epilogue_completed : reload_completed)"
11409   [(const_int 0)]
11410   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11411
11412 (define_insn "x86_64_shrd"
11413   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11414         (ior:DI (ashiftrt:DI (match_dup 0)
11415                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11416                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11417                   (minus:QI (const_int 64) (match_dup 2)))))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "TARGET_64BIT"
11420   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11421   [(set_attr "type" "ishift")
11422    (set_attr "prefix_0f" "1")
11423    (set_attr "mode" "DI")
11424    (set_attr "athlon_decode" "vector")
11425    (set_attr "amdfam10_decode" "vector")])
11426
11427 (define_expand "ashrdi3"
11428   [(set (match_operand:DI 0 "shiftdi_operand" "")
11429         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11430                      (match_operand:QI 2 "nonmemory_operand" "")))]
11431   ""
11432   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11433
11434 (define_expand "x86_64_shift_adj_3"
11435   [(use (match_operand:DI 0 "register_operand" ""))
11436    (use (match_operand:DI 1 "register_operand" ""))
11437    (use (match_operand:QI 2 "register_operand" ""))]
11438   ""
11439 {
11440   rtx label = gen_label_rtx ();
11441   rtx tmp;
11442
11443   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11444
11445   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11446   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11447   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11448                               gen_rtx_LABEL_REF (VOIDmode, label),
11449                               pc_rtx);
11450   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11451   JUMP_LABEL (tmp) = label;
11452
11453   emit_move_insn (operands[0], operands[1]);
11454   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11455
11456   emit_label (label);
11457   LABEL_NUSES (label) = 1;
11458
11459   DONE;
11460 })
11461
11462 (define_insn "ashrdi3_63_rex64"
11463   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11464         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11465                      (match_operand:DI 2 "const_int_operand" "i,i")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "TARGET_64BIT && INTVAL (operands[2]) == 63
11468    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11469    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11470   "@
11471    {cqto|cqo}
11472    sar{q}\t{%2, %0|%0, %2}"
11473   [(set_attr "type" "imovx,ishift")
11474    (set_attr "prefix_0f" "0,*")
11475    (set_attr "length_immediate" "0,*")
11476    (set_attr "modrm" "0,1")
11477    (set_attr "mode" "DI")])
11478
11479 (define_insn "*ashrdi3_1_one_bit_rex64"
11480   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11481         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11482                      (match_operand:QI 2 "const1_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "TARGET_64BIT
11485    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11486    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11487   "sar{q}\t%0"
11488   [(set_attr "type" "ishift")
11489    (set_attr "length_immediate" "0")
11490    (set_attr "mode" "DI")])
11491
11492 (define_insn "*ashrdi3_1_rex64"
11493   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11494         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11495                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11496    (clobber (reg:CC FLAGS_REG))]
11497   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11498   "@
11499    sar{q}\t{%2, %0|%0, %2}
11500    sar{q}\t{%b2, %0|%0, %b2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "mode" "DI")])
11503
11504 ;; This pattern can't accept a variable shift count, since shifts by
11505 ;; zero don't affect the flags.  We assume that shifts by constant
11506 ;; zero are optimized away.
11507 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11508   [(set (reg FLAGS_REG)
11509         (compare
11510           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11511                        (match_operand:QI 2 "const1_operand" ""))
11512           (const_int 0)))
11513    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11514         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11515   "TARGET_64BIT
11516    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11517    && ix86_match_ccmode (insn, CCGOCmode)
11518    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11519   "sar{q}\t%0"
11520   [(set_attr "type" "ishift")
11521    (set_attr "length_immediate" "0")
11522    (set_attr "mode" "DI")])
11523
11524 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11525   [(set (reg FLAGS_REG)
11526         (compare
11527           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11528                        (match_operand:QI 2 "const1_operand" ""))
11529           (const_int 0)))
11530    (clobber (match_scratch:DI 0 "=r"))]
11531   "TARGET_64BIT
11532    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11533    && ix86_match_ccmode (insn, CCGOCmode)
11534    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11535   "sar{q}\t%0"
11536   [(set_attr "type" "ishift")
11537    (set_attr "length_immediate" "0")
11538    (set_attr "mode" "DI")])
11539
11540 ;; This pattern can't accept a variable shift count, since shifts by
11541 ;; zero don't affect the flags.  We assume that shifts by constant
11542 ;; zero are optimized away.
11543 (define_insn "*ashrdi3_cmp_rex64"
11544   [(set (reg FLAGS_REG)
11545         (compare
11546           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11547                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11548           (const_int 0)))
11549    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11550         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11551   "TARGET_64BIT
11552    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11553    && ix86_match_ccmode (insn, CCGOCmode)
11554    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11555   "sar{q}\t{%2, %0|%0, %2}"
11556   [(set_attr "type" "ishift")
11557    (set_attr "mode" "DI")])
11558
11559 (define_insn "*ashrdi3_cconly_rex64"
11560   [(set (reg FLAGS_REG)
11561         (compare
11562           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11563                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11564           (const_int 0)))
11565    (clobber (match_scratch:DI 0 "=r"))]
11566   "TARGET_64BIT
11567    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11568    && ix86_match_ccmode (insn, CCGOCmode)
11569    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11570   "sar{q}\t{%2, %0|%0, %2}"
11571   [(set_attr "type" "ishift")
11572    (set_attr "mode" "DI")])
11573
11574 (define_insn "*ashrdi3_1"
11575   [(set (match_operand:DI 0 "register_operand" "=r")
11576         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11577                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11578    (clobber (reg:CC FLAGS_REG))]
11579   "!TARGET_64BIT"
11580   "#"
11581   [(set_attr "type" "multi")])
11582
11583 ;; By default we don't ask for a scratch register, because when DImode
11584 ;; values are manipulated, registers are already at a premium.  But if
11585 ;; we have one handy, we won't turn it away.
11586 (define_peephole2
11587   [(match_scratch:SI 3 "r")
11588    (parallel [(set (match_operand:DI 0 "register_operand" "")
11589                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11590                                 (match_operand:QI 2 "nonmemory_operand" "")))
11591               (clobber (reg:CC FLAGS_REG))])
11592    (match_dup 3)]
11593   "!TARGET_64BIT && TARGET_CMOVE"
11594   [(const_int 0)]
11595   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11596
11597 (define_split
11598   [(set (match_operand:DI 0 "register_operand" "")
11599         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11600                      (match_operand:QI 2 "nonmemory_operand" "")))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11603                      ? epilogue_completed : reload_completed)"
11604   [(const_int 0)]
11605   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11606
11607 (define_insn "x86_shrd"
11608   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11609         (ior:SI (ashiftrt:SI (match_dup 0)
11610                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11611                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11612                   (minus:QI (const_int 32) (match_dup 2)))))
11613    (clobber (reg:CC FLAGS_REG))]
11614   ""
11615   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11616   [(set_attr "type" "ishift")
11617    (set_attr "prefix_0f" "1")
11618    (set_attr "pent_pair" "np")
11619    (set_attr "mode" "SI")])
11620
11621 (define_expand "x86_shift_adj_3"
11622   [(use (match_operand:SI 0 "register_operand" ""))
11623    (use (match_operand:SI 1 "register_operand" ""))
11624    (use (match_operand:QI 2 "register_operand" ""))]
11625   ""
11626 {
11627   rtx label = gen_label_rtx ();
11628   rtx tmp;
11629
11630   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11631
11632   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11633   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11634   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11635                               gen_rtx_LABEL_REF (VOIDmode, label),
11636                               pc_rtx);
11637   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11638   JUMP_LABEL (tmp) = label;
11639
11640   emit_move_insn (operands[0], operands[1]);
11641   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11642
11643   emit_label (label);
11644   LABEL_NUSES (label) = 1;
11645
11646   DONE;
11647 })
11648
11649 (define_expand "ashrsi3_31"
11650   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11651                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11652                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11653               (clobber (reg:CC FLAGS_REG))])]
11654   "")
11655
11656 (define_insn "*ashrsi3_31"
11657   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11658         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11659                      (match_operand:SI 2 "const_int_operand" "i,i")))
11660    (clobber (reg:CC FLAGS_REG))]
11661   "INTVAL (operands[2]) == 31
11662    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11663    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11664   "@
11665    {cltd|cdq}
11666    sar{l}\t{%2, %0|%0, %2}"
11667   [(set_attr "type" "imovx,ishift")
11668    (set_attr "prefix_0f" "0,*")
11669    (set_attr "length_immediate" "0,*")
11670    (set_attr "modrm" "0,1")
11671    (set_attr "mode" "SI")])
11672
11673 (define_insn "*ashrsi3_31_zext"
11674   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11675         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11676                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11677    (clobber (reg:CC FLAGS_REG))]
11678   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11679    && INTVAL (operands[2]) == 31
11680    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11681   "@
11682    {cltd|cdq}
11683    sar{l}\t{%2, %k0|%k0, %2}"
11684   [(set_attr "type" "imovx,ishift")
11685    (set_attr "prefix_0f" "0,*")
11686    (set_attr "length_immediate" "0,*")
11687    (set_attr "modrm" "0,1")
11688    (set_attr "mode" "SI")])
11689
11690 (define_expand "ashrsi3"
11691   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11692         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11693                      (match_operand:QI 2 "nonmemory_operand" "")))]
11694   ""
11695   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11696
11697 (define_insn "*ashrsi3_1_one_bit"
11698   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11699         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11700                      (match_operand:QI 2 "const1_operand" "")))
11701    (clobber (reg:CC FLAGS_REG))]
11702   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11703    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11704   "sar{l}\t%0"
11705   [(set_attr "type" "ishift")
11706    (set_attr "length_immediate" "0")
11707    (set_attr "mode" "SI")])
11708
11709 (define_insn "*ashrsi3_1_one_bit_zext"
11710   [(set (match_operand:DI 0 "register_operand" "=r")
11711         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712                                      (match_operand:QI 2 "const1_operand" ""))))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "TARGET_64BIT
11715    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11716    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11717   "sar{l}\t%k0"
11718   [(set_attr "type" "ishift")
11719    (set_attr "length_immediate" "0")
11720    (set_attr "mode" "SI")])
11721
11722 (define_insn "*ashrsi3_1"
11723   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11724         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11725                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11726    (clobber (reg:CC FLAGS_REG))]
11727   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11728   "@
11729    sar{l}\t{%2, %0|%0, %2}
11730    sar{l}\t{%b2, %0|%0, %b2}"
11731   [(set_attr "type" "ishift")
11732    (set_attr "mode" "SI")])
11733
11734 (define_insn "*ashrsi3_1_zext"
11735   [(set (match_operand:DI 0 "register_operand" "=r,r")
11736         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11737                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11738    (clobber (reg:CC FLAGS_REG))]
11739   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11740   "@
11741    sar{l}\t{%2, %k0|%k0, %2}
11742    sar{l}\t{%b2, %k0|%k0, %b2}"
11743   [(set_attr "type" "ishift")
11744    (set_attr "mode" "SI")])
11745
11746 ;; This pattern can't accept a variable shift count, since shifts by
11747 ;; zero don't affect the flags.  We assume that shifts by constant
11748 ;; zero are optimized away.
11749 (define_insn "*ashrsi3_one_bit_cmp"
11750   [(set (reg FLAGS_REG)
11751         (compare
11752           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11753                        (match_operand:QI 2 "const1_operand" ""))
11754           (const_int 0)))
11755    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11756         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11757   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11758    && ix86_match_ccmode (insn, CCGOCmode)
11759    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11760   "sar{l}\t%0"
11761   [(set_attr "type" "ishift")
11762    (set_attr "length_immediate" "0")
11763    (set_attr "mode" "SI")])
11764
11765 (define_insn "*ashrsi3_one_bit_cconly"
11766   [(set (reg FLAGS_REG)
11767         (compare
11768           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11769                        (match_operand:QI 2 "const1_operand" ""))
11770           (const_int 0)))
11771    (clobber (match_scratch:SI 0 "=r"))]
11772   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11773    && ix86_match_ccmode (insn, CCGOCmode)
11774    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11775   "sar{l}\t%0"
11776   [(set_attr "type" "ishift")
11777    (set_attr "length_immediate" "0")
11778    (set_attr "mode" "SI")])
11779
11780 (define_insn "*ashrsi3_one_bit_cmp_zext"
11781   [(set (reg FLAGS_REG)
11782         (compare
11783           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11784                        (match_operand:QI 2 "const1_operand" ""))
11785           (const_int 0)))
11786    (set (match_operand:DI 0 "register_operand" "=r")
11787         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11788   "TARGET_64BIT
11789    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11790    && ix86_match_ccmode (insn, CCmode)
11791    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11792   "sar{l}\t%k0"
11793   [(set_attr "type" "ishift")
11794    (set_attr "length_immediate" "0")
11795    (set_attr "mode" "SI")])
11796
11797 ;; This pattern can't accept a variable shift count, since shifts by
11798 ;; zero don't affect the flags.  We assume that shifts by constant
11799 ;; zero are optimized away.
11800 (define_insn "*ashrsi3_cmp"
11801   [(set (reg FLAGS_REG)
11802         (compare
11803           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11804                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11805           (const_int 0)))
11806    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11807         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11808   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11809    && ix86_match_ccmode (insn, CCGOCmode)
11810    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11811   "sar{l}\t{%2, %0|%0, %2}"
11812   [(set_attr "type" "ishift")
11813    (set_attr "mode" "SI")])
11814
11815 (define_insn "*ashrsi3_cconly"
11816   [(set (reg FLAGS_REG)
11817         (compare
11818           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11819                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11820           (const_int 0)))
11821    (clobber (match_scratch:SI 0 "=r"))]
11822   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11823    && ix86_match_ccmode (insn, CCGOCmode)
11824    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11825   "sar{l}\t{%2, %0|%0, %2}"
11826   [(set_attr "type" "ishift")
11827    (set_attr "mode" "SI")])
11828
11829 (define_insn "*ashrsi3_cmp_zext"
11830   [(set (reg FLAGS_REG)
11831         (compare
11832           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11834           (const_int 0)))
11835    (set (match_operand:DI 0 "register_operand" "=r")
11836         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11837   "TARGET_64BIT
11838    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11839    && ix86_match_ccmode (insn, CCGOCmode)
11840    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11841   "sar{l}\t{%2, %k0|%k0, %2}"
11842   [(set_attr "type" "ishift")
11843    (set_attr "mode" "SI")])
11844
11845 (define_expand "ashrhi3"
11846   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11847         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11848                      (match_operand:QI 2 "nonmemory_operand" "")))]
11849   "TARGET_HIMODE_MATH"
11850   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11851
11852 (define_insn "*ashrhi3_1_one_bit"
11853   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11854         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11855                      (match_operand:QI 2 "const1_operand" "")))
11856    (clobber (reg:CC FLAGS_REG))]
11857   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11858    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11859   "sar{w}\t%0"
11860   [(set_attr "type" "ishift")
11861    (set_attr "length_immediate" "0")
11862    (set_attr "mode" "HI")])
11863
11864 (define_insn "*ashrhi3_1"
11865   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11866         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11867                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11870   "@
11871    sar{w}\t{%2, %0|%0, %2}
11872    sar{w}\t{%b2, %0|%0, %b2}"
11873   [(set_attr "type" "ishift")
11874    (set_attr "mode" "HI")])
11875
11876 ;; This pattern can't accept a variable shift count, since shifts by
11877 ;; zero don't affect the flags.  We assume that shifts by constant
11878 ;; zero are optimized away.
11879 (define_insn "*ashrhi3_one_bit_cmp"
11880   [(set (reg FLAGS_REG)
11881         (compare
11882           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11883                        (match_operand:QI 2 "const1_operand" ""))
11884           (const_int 0)))
11885    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11887   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11888    && ix86_match_ccmode (insn, CCGOCmode)
11889    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11890   "sar{w}\t%0"
11891   [(set_attr "type" "ishift")
11892    (set_attr "length_immediate" "0")
11893    (set_attr "mode" "HI")])
11894
11895 (define_insn "*ashrhi3_one_bit_cconly"
11896   [(set (reg FLAGS_REG)
11897         (compare
11898           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899                        (match_operand:QI 2 "const1_operand" ""))
11900           (const_int 0)))
11901    (clobber (match_scratch:HI 0 "=r"))]
11902   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11903    && ix86_match_ccmode (insn, CCGOCmode)
11904    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11905   "sar{w}\t%0"
11906   [(set_attr "type" "ishift")
11907    (set_attr "length_immediate" "0")
11908    (set_attr "mode" "HI")])
11909
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags.  We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrhi3_cmp"
11914   [(set (reg FLAGS_REG)
11915         (compare
11916           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11917                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11918           (const_int 0)))
11919    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11920         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11921   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11922    && ix86_match_ccmode (insn, CCGOCmode)
11923    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11924   "sar{w}\t{%2, %0|%0, %2}"
11925   [(set_attr "type" "ishift")
11926    (set_attr "mode" "HI")])
11927
11928 (define_insn "*ashrhi3_cconly"
11929   [(set (reg FLAGS_REG)
11930         (compare
11931           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11932                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11933           (const_int 0)))
11934    (clobber (match_scratch:HI 0 "=r"))]
11935   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11936    && ix86_match_ccmode (insn, CCGOCmode)
11937    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11938   "sar{w}\t{%2, %0|%0, %2}"
11939   [(set_attr "type" "ishift")
11940    (set_attr "mode" "HI")])
11941
11942 (define_expand "ashrqi3"
11943   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11944         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11945                      (match_operand:QI 2 "nonmemory_operand" "")))]
11946   "TARGET_QIMODE_MATH"
11947   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11948
11949 (define_insn "*ashrqi3_1_one_bit"
11950   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11951         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11952                      (match_operand:QI 2 "const1_operand" "")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11955    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11956   "sar{b}\t%0"
11957   [(set_attr "type" "ishift")
11958    (set_attr "length_immediate" "0")
11959    (set_attr "mode" "QI")])
11960
11961 (define_insn "*ashrqi3_1_one_bit_slp"
11962   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11963         (ashiftrt:QI (match_dup 0)
11964                      (match_operand:QI 1 "const1_operand" "")))
11965    (clobber (reg:CC FLAGS_REG))]
11966   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11967    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11968    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11969   "sar{b}\t%0"
11970   [(set_attr "type" "ishift1")
11971    (set_attr "length_immediate" "0")
11972    (set_attr "mode" "QI")])
11973
11974 (define_insn "*ashrqi3_1"
11975   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11976         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11977                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11978    (clobber (reg:CC FLAGS_REG))]
11979   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11980   "@
11981    sar{b}\t{%2, %0|%0, %2}
11982    sar{b}\t{%b2, %0|%0, %b2}"
11983   [(set_attr "type" "ishift")
11984    (set_attr "mode" "QI")])
11985
11986 (define_insn "*ashrqi3_1_slp"
11987   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11988         (ashiftrt:QI (match_dup 0)
11989                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11992    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11993   "@
11994    sar{b}\t{%1, %0|%0, %1}
11995    sar{b}\t{%b1, %0|%0, %b1}"
11996   [(set_attr "type" "ishift1")
11997    (set_attr "mode" "QI")])
11998
11999 ;; This pattern can't accept a variable shift count, since shifts by
12000 ;; zero don't affect the flags.  We assume that shifts by constant
12001 ;; zero are optimized away.
12002 (define_insn "*ashrqi3_one_bit_cmp"
12003   [(set (reg FLAGS_REG)
12004         (compare
12005           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12006                        (match_operand:QI 2 "const1_operand" "I"))
12007           (const_int 0)))
12008    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12009         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12010   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12011    && ix86_match_ccmode (insn, CCGOCmode)
12012    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12013   "sar{b}\t%0"
12014   [(set_attr "type" "ishift")
12015    (set_attr "length_immediate" "0")
12016    (set_attr "mode" "QI")])
12017
12018 (define_insn "*ashrqi3_one_bit_cconly"
12019   [(set (reg FLAGS_REG)
12020         (compare
12021           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12022                        (match_operand:QI 2 "const1_operand" ""))
12023           (const_int 0)))
12024    (clobber (match_scratch:QI 0 "=q"))]
12025   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12026    && ix86_match_ccmode (insn, CCGOCmode)
12027    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12028   "sar{b}\t%0"
12029   [(set_attr "type" "ishift")
12030    (set_attr "length_immediate" "0")
12031    (set_attr "mode" "QI")])
12032
12033 ;; This pattern can't accept a variable shift count, since shifts by
12034 ;; zero don't affect the flags.  We assume that shifts by constant
12035 ;; zero are optimized away.
12036 (define_insn "*ashrqi3_cmp"
12037   [(set (reg FLAGS_REG)
12038         (compare
12039           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12040                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12041           (const_int 0)))
12042    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12043         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12044   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12045    && ix86_match_ccmode (insn, CCGOCmode)
12046    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12047   "sar{b}\t{%2, %0|%0, %2}"
12048   [(set_attr "type" "ishift")
12049    (set_attr "mode" "QI")])
12050
12051 (define_insn "*ashrqi3_cconly"
12052   [(set (reg FLAGS_REG)
12053         (compare
12054           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12055                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12056           (const_int 0)))
12057    (clobber (match_scratch:QI 0 "=q"))]
12058   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12059    && ix86_match_ccmode (insn, CCGOCmode)
12060    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12061   "sar{b}\t{%2, %0|%0, %2}"
12062   [(set_attr "type" "ishift")
12063    (set_attr "mode" "QI")])
12064
12065 \f
12066 ;; Logical shift instructions
12067
12068 ;; See comment above `ashldi3' about how this works.
12069
12070 (define_expand "lshrti3"
12071   [(set (match_operand:TI 0 "register_operand" "")
12072         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12073                      (match_operand:QI 2 "nonmemory_operand" "")))]
12074   "TARGET_64BIT"
12075   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12076
12077 ;; This pattern must be defined before *lshrti3_1 to prevent
12078 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12079
12080 (define_insn "*avx_lshrti3"
12081   [(set (match_operand:TI 0 "register_operand" "=x")
12082         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12083                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12084   "TARGET_AVX"
12085 {
12086   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12087   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12088 }
12089   [(set_attr "type" "sseishft")
12090    (set_attr "prefix" "vex")
12091    (set_attr "length_immediate" "1")
12092    (set_attr "mode" "TI")])
12093
12094 (define_insn "sse2_lshrti3"
12095   [(set (match_operand:TI 0 "register_operand" "=x")
12096         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12097                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12098   "TARGET_SSE2"
12099 {
12100   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12101   return "psrldq\t{%2, %0|%0, %2}";
12102 }
12103   [(set_attr "type" "sseishft")
12104    (set_attr "prefix_data16" "1")
12105    (set_attr "length_immediate" "1")
12106    (set_attr "mode" "TI")])
12107
12108 (define_insn "*lshrti3_1"
12109   [(set (match_operand:TI 0 "register_operand" "=r")
12110         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12111                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12112    (clobber (reg:CC FLAGS_REG))]
12113   "TARGET_64BIT"
12114   "#"
12115   [(set_attr "type" "multi")])
12116
12117 (define_peephole2
12118   [(match_scratch:DI 3 "r")
12119    (parallel [(set (match_operand:TI 0 "register_operand" "")
12120                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12121                                 (match_operand:QI 2 "nonmemory_operand" "")))
12122               (clobber (reg:CC FLAGS_REG))])
12123    (match_dup 3)]
12124   "TARGET_64BIT"
12125   [(const_int 0)]
12126   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12127
12128 (define_split
12129   [(set (match_operand:TI 0 "register_operand" "")
12130         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12131                      (match_operand:QI 2 "nonmemory_operand" "")))
12132    (clobber (reg:CC FLAGS_REG))]
12133   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12134                     ? epilogue_completed : reload_completed)"
12135   [(const_int 0)]
12136   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12137
12138 (define_expand "lshrdi3"
12139   [(set (match_operand:DI 0 "shiftdi_operand" "")
12140         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12141                      (match_operand:QI 2 "nonmemory_operand" "")))]
12142   ""
12143   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12144
12145 (define_insn "*lshrdi3_1_one_bit_rex64"
12146   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12147         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12148                      (match_operand:QI 2 "const1_operand" "")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "TARGET_64BIT
12151    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12152    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12153   "shr{q}\t%0"
12154   [(set_attr "type" "ishift")
12155    (set_attr "length_immediate" "0")
12156    (set_attr "mode" "DI")])
12157
12158 (define_insn "*lshrdi3_1_rex64"
12159   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12160         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12161                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12164   "@
12165    shr{q}\t{%2, %0|%0, %2}
12166    shr{q}\t{%b2, %0|%0, %b2}"
12167   [(set_attr "type" "ishift")
12168    (set_attr "mode" "DI")])
12169
12170 ;; This pattern can't accept a variable shift count, since shifts by
12171 ;; zero don't affect the flags.  We assume that shifts by constant
12172 ;; zero are optimized away.
12173 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12174   [(set (reg FLAGS_REG)
12175         (compare
12176           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12177                        (match_operand:QI 2 "const1_operand" ""))
12178           (const_int 0)))
12179    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12180         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12181   "TARGET_64BIT
12182    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12183    && ix86_match_ccmode (insn, CCGOCmode)
12184    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12185   "shr{q}\t%0"
12186   [(set_attr "type" "ishift")
12187    (set_attr "length_immediate" "0")
12188    (set_attr "mode" "DI")])
12189
12190 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12191   [(set (reg FLAGS_REG)
12192         (compare
12193           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12194                        (match_operand:QI 2 "const1_operand" ""))
12195           (const_int 0)))
12196    (clobber (match_scratch:DI 0 "=r"))]
12197   "TARGET_64BIT
12198    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12199    && ix86_match_ccmode (insn, CCGOCmode)
12200    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12201   "shr{q}\t%0"
12202   [(set_attr "type" "ishift")
12203    (set_attr "length_immediate" "0")
12204    (set_attr "mode" "DI")])
12205
12206 ;; This pattern can't accept a variable shift count, since shifts by
12207 ;; zero don't affect the flags.  We assume that shifts by constant
12208 ;; zero are optimized away.
12209 (define_insn "*lshrdi3_cmp_rex64"
12210   [(set (reg FLAGS_REG)
12211         (compare
12212           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12213                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12214           (const_int 0)))
12215    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12216         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12217   "TARGET_64BIT
12218    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12219    && ix86_match_ccmode (insn, CCGOCmode)
12220    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12221   "shr{q}\t{%2, %0|%0, %2}"
12222   [(set_attr "type" "ishift")
12223    (set_attr "mode" "DI")])
12224
12225 (define_insn "*lshrdi3_cconly_rex64"
12226   [(set (reg FLAGS_REG)
12227         (compare
12228           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12229                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12230           (const_int 0)))
12231    (clobber (match_scratch:DI 0 "=r"))]
12232   "TARGET_64BIT
12233    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12234    && ix86_match_ccmode (insn, CCGOCmode)
12235    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12236   "shr{q}\t{%2, %0|%0, %2}"
12237   [(set_attr "type" "ishift")
12238    (set_attr "mode" "DI")])
12239
12240 (define_insn "*lshrdi3_1"
12241   [(set (match_operand:DI 0 "register_operand" "=r")
12242         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12243                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12244    (clobber (reg:CC FLAGS_REG))]
12245   "!TARGET_64BIT"
12246   "#"
12247   [(set_attr "type" "multi")])
12248
12249 ;; By default we don't ask for a scratch register, because when DImode
12250 ;; values are manipulated, registers are already at a premium.  But if
12251 ;; we have one handy, we won't turn it away.
12252 (define_peephole2
12253   [(match_scratch:SI 3 "r")
12254    (parallel [(set (match_operand:DI 0 "register_operand" "")
12255                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12256                                 (match_operand:QI 2 "nonmemory_operand" "")))
12257               (clobber (reg:CC FLAGS_REG))])
12258    (match_dup 3)]
12259   "!TARGET_64BIT && TARGET_CMOVE"
12260   [(const_int 0)]
12261   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12262
12263 (define_split
12264   [(set (match_operand:DI 0 "register_operand" "")
12265         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12266                      (match_operand:QI 2 "nonmemory_operand" "")))
12267    (clobber (reg:CC FLAGS_REG))]
12268   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12269                      ? epilogue_completed : reload_completed)"
12270   [(const_int 0)]
12271   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12272
12273 (define_expand "lshrsi3"
12274   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12275         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12276                      (match_operand:QI 2 "nonmemory_operand" "")))]
12277   ""
12278   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12279
12280 (define_insn "*lshrsi3_1_one_bit"
12281   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12282         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283                      (match_operand:QI 2 "const1_operand" "")))
12284    (clobber (reg:CC FLAGS_REG))]
12285   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12286    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12287   "shr{l}\t%0"
12288   [(set_attr "type" "ishift")
12289    (set_attr "length_immediate" "0")
12290    (set_attr "mode" "SI")])
12291
12292 (define_insn "*lshrsi3_1_one_bit_zext"
12293   [(set (match_operand:DI 0 "register_operand" "=r")
12294         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12295                      (match_operand:QI 2 "const1_operand" "")))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "TARGET_64BIT
12298    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12299    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12300   "shr{l}\t%k0"
12301   [(set_attr "type" "ishift")
12302    (set_attr "length_immediate" "0")
12303    (set_attr "mode" "SI")])
12304
12305 (define_insn "*lshrsi3_1"
12306   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12307         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12308                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12311   "@
12312    shr{l}\t{%2, %0|%0, %2}
12313    shr{l}\t{%b2, %0|%0, %b2}"
12314   [(set_attr "type" "ishift")
12315    (set_attr "mode" "SI")])
12316
12317 (define_insn "*lshrsi3_1_zext"
12318   [(set (match_operand:DI 0 "register_operand" "=r,r")
12319         (zero_extend:DI
12320           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12321                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12324   "@
12325    shr{l}\t{%2, %k0|%k0, %2}
12326    shr{l}\t{%b2, %k0|%k0, %b2}"
12327   [(set_attr "type" "ishift")
12328    (set_attr "mode" "SI")])
12329
12330 ;; This pattern can't accept a variable shift count, since shifts by
12331 ;; zero don't affect the flags.  We assume that shifts by constant
12332 ;; zero are optimized away.
12333 (define_insn "*lshrsi3_one_bit_cmp"
12334   [(set (reg FLAGS_REG)
12335         (compare
12336           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12337                        (match_operand:QI 2 "const1_operand" ""))
12338           (const_int 0)))
12339    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12340         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12341   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12342    && ix86_match_ccmode (insn, CCGOCmode)
12343    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12344   "shr{l}\t%0"
12345   [(set_attr "type" "ishift")
12346    (set_attr "length_immediate" "0")
12347    (set_attr "mode" "SI")])
12348
12349 (define_insn "*lshrsi3_one_bit_cconly"
12350   [(set (reg FLAGS_REG)
12351         (compare
12352           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353                        (match_operand:QI 2 "const1_operand" ""))
12354           (const_int 0)))
12355    (clobber (match_scratch:SI 0 "=r"))]
12356   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12357    && ix86_match_ccmode (insn, CCGOCmode)
12358    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12359   "shr{l}\t%0"
12360   [(set_attr "type" "ishift")
12361    (set_attr "length_immediate" "0")
12362    (set_attr "mode" "SI")])
12363
12364 (define_insn "*lshrsi3_cmp_one_bit_zext"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))
12369           (const_int 0)))
12370    (set (match_operand:DI 0 "register_operand" "=r")
12371         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12372   "TARGET_64BIT
12373    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12374    && ix86_match_ccmode (insn, CCGOCmode)
12375    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12376   "shr{l}\t%k0"
12377   [(set_attr "type" "ishift")
12378    (set_attr "length_immediate" "0")
12379    (set_attr "mode" "SI")])
12380
12381 ;; This pattern can't accept a variable shift count, since shifts by
12382 ;; zero don't affect the flags.  We assume that shifts by constant
12383 ;; zero are optimized away.
12384 (define_insn "*lshrsi3_cmp"
12385   [(set (reg FLAGS_REG)
12386         (compare
12387           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12388                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12389           (const_int 0)))
12390    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12391         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12392   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12393    && ix86_match_ccmode (insn, CCGOCmode)
12394    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12395   "shr{l}\t{%2, %0|%0, %2}"
12396   [(set_attr "type" "ishift")
12397    (set_attr "mode" "SI")])
12398
12399 (define_insn "*lshrsi3_cconly"
12400   [(set (reg FLAGS_REG)
12401       (compare
12402         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12403                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12404         (const_int 0)))
12405    (clobber (match_scratch:SI 0 "=r"))]
12406   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12407    && ix86_match_ccmode (insn, CCGOCmode)
12408    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12409   "shr{l}\t{%2, %0|%0, %2}"
12410   [(set_attr "type" "ishift")
12411    (set_attr "mode" "SI")])
12412
12413 (define_insn "*lshrsi3_cmp_zext"
12414   [(set (reg FLAGS_REG)
12415         (compare
12416           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12417                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12418           (const_int 0)))
12419    (set (match_operand:DI 0 "register_operand" "=r")
12420         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12421   "TARGET_64BIT
12422    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12423    && ix86_match_ccmode (insn, CCGOCmode)
12424    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12425   "shr{l}\t{%2, %k0|%k0, %2}"
12426   [(set_attr "type" "ishift")
12427    (set_attr "mode" "SI")])
12428
12429 (define_expand "lshrhi3"
12430   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12431         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12432                      (match_operand:QI 2 "nonmemory_operand" "")))]
12433   "TARGET_HIMODE_MATH"
12434   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12435
12436 (define_insn "*lshrhi3_1_one_bit"
12437   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12438         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12439                      (match_operand:QI 2 "const1_operand" "")))
12440    (clobber (reg:CC FLAGS_REG))]
12441   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12442    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12443   "shr{w}\t%0"
12444   [(set_attr "type" "ishift")
12445    (set_attr "length_immediate" "0")
12446    (set_attr "mode" "HI")])
12447
12448 (define_insn "*lshrhi3_1"
12449   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12450         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12451                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12452    (clobber (reg:CC FLAGS_REG))]
12453   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12454   "@
12455    shr{w}\t{%2, %0|%0, %2}
12456    shr{w}\t{%b2, %0|%0, %b2}"
12457   [(set_attr "type" "ishift")
12458    (set_attr "mode" "HI")])
12459
12460 ;; This pattern can't accept a variable shift count, since shifts by
12461 ;; zero don't affect the flags.  We assume that shifts by constant
12462 ;; zero are optimized away.
12463 (define_insn "*lshrhi3_one_bit_cmp"
12464   [(set (reg FLAGS_REG)
12465         (compare
12466           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12467                        (match_operand:QI 2 "const1_operand" ""))
12468           (const_int 0)))
12469    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12470         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12471   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12472    && ix86_match_ccmode (insn, CCGOCmode)
12473    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12474   "shr{w}\t%0"
12475   [(set_attr "type" "ishift")
12476    (set_attr "length_immediate" "0")
12477    (set_attr "mode" "HI")])
12478
12479 (define_insn "*lshrhi3_one_bit_cconly"
12480   [(set (reg FLAGS_REG)
12481         (compare
12482           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12483                        (match_operand:QI 2 "const1_operand" ""))
12484           (const_int 0)))
12485    (clobber (match_scratch:HI 0 "=r"))]
12486   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12487    && ix86_match_ccmode (insn, CCGOCmode)
12488    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12489   "shr{w}\t%0"
12490   [(set_attr "type" "ishift")
12491    (set_attr "length_immediate" "0")
12492    (set_attr "mode" "HI")])
12493
12494 ;; This pattern can't accept a variable shift count, since shifts by
12495 ;; zero don't affect the flags.  We assume that shifts by constant
12496 ;; zero are optimized away.
12497 (define_insn "*lshrhi3_cmp"
12498   [(set (reg FLAGS_REG)
12499         (compare
12500           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12501                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12502           (const_int 0)))
12503    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12504         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12505   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12506    && ix86_match_ccmode (insn, CCGOCmode)
12507    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12508   "shr{w}\t{%2, %0|%0, %2}"
12509   [(set_attr "type" "ishift")
12510    (set_attr "mode" "HI")])
12511
12512 (define_insn "*lshrhi3_cconly"
12513   [(set (reg FLAGS_REG)
12514         (compare
12515           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12516                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12517           (const_int 0)))
12518    (clobber (match_scratch:HI 0 "=r"))]
12519   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12520    && ix86_match_ccmode (insn, CCGOCmode)
12521    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12522   "shr{w}\t{%2, %0|%0, %2}"
12523   [(set_attr "type" "ishift")
12524    (set_attr "mode" "HI")])
12525
12526 (define_expand "lshrqi3"
12527   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12528         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12529                      (match_operand:QI 2 "nonmemory_operand" "")))]
12530   "TARGET_QIMODE_MATH"
12531   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12532
12533 (define_insn "*lshrqi3_1_one_bit"
12534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12535         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12536                      (match_operand:QI 2 "const1_operand" "")))
12537    (clobber (reg:CC FLAGS_REG))]
12538   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12539    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12540   "shr{b}\t%0"
12541   [(set_attr "type" "ishift")
12542    (set_attr "length_immediate" "0")
12543    (set_attr "mode" "QI")])
12544
12545 (define_insn "*lshrqi3_1_one_bit_slp"
12546   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12547         (lshiftrt:QI (match_dup 0)
12548                      (match_operand:QI 1 "const1_operand" "")))
12549    (clobber (reg:CC FLAGS_REG))]
12550   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12551    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12552   "shr{b}\t%0"
12553   [(set_attr "type" "ishift1")
12554    (set_attr "length_immediate" "0")
12555    (set_attr "mode" "QI")])
12556
12557 (define_insn "*lshrqi3_1"
12558   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12559         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12560                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561    (clobber (reg:CC FLAGS_REG))]
12562   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12563   "@
12564    shr{b}\t{%2, %0|%0, %2}
12565    shr{b}\t{%b2, %0|%0, %b2}"
12566   [(set_attr "type" "ishift")
12567    (set_attr "mode" "QI")])
12568
12569 (define_insn "*lshrqi3_1_slp"
12570   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12571         (lshiftrt:QI (match_dup 0)
12572                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12573    (clobber (reg:CC FLAGS_REG))]
12574   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12575    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12576   "@
12577    shr{b}\t{%1, %0|%0, %1}
12578    shr{b}\t{%b1, %0|%0, %b1}"
12579   [(set_attr "type" "ishift1")
12580    (set_attr "mode" "QI")])
12581
12582 ;; This pattern can't accept a variable shift count, since shifts by
12583 ;; zero don't affect the flags.  We assume that shifts by constant
12584 ;; zero are optimized away.
12585 (define_insn "*lshrqi2_one_bit_cmp"
12586   [(set (reg FLAGS_REG)
12587         (compare
12588           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12589                        (match_operand:QI 2 "const1_operand" ""))
12590           (const_int 0)))
12591    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12592         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12593   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12594    && ix86_match_ccmode (insn, CCGOCmode)
12595    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12596   "shr{b}\t%0"
12597   [(set_attr "type" "ishift")
12598    (set_attr "length_immediate" "0")
12599    (set_attr "mode" "QI")])
12600
12601 (define_insn "*lshrqi2_one_bit_cconly"
12602   [(set (reg FLAGS_REG)
12603         (compare
12604           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12605                        (match_operand:QI 2 "const1_operand" ""))
12606           (const_int 0)))
12607    (clobber (match_scratch:QI 0 "=q"))]
12608   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12609    && ix86_match_ccmode (insn, CCGOCmode)
12610    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12611   "shr{b}\t%0"
12612   [(set_attr "type" "ishift")
12613    (set_attr "length_immediate" "0")
12614    (set_attr "mode" "QI")])
12615
12616 ;; This pattern can't accept a variable shift count, since shifts by
12617 ;; zero don't affect the flags.  We assume that shifts by constant
12618 ;; zero are optimized away.
12619 (define_insn "*lshrqi2_cmp"
12620   [(set (reg FLAGS_REG)
12621         (compare
12622           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12623                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12624           (const_int 0)))
12625    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12626         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12627   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12628    && ix86_match_ccmode (insn, CCGOCmode)
12629    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12630   "shr{b}\t{%2, %0|%0, %2}"
12631   [(set_attr "type" "ishift")
12632    (set_attr "mode" "QI")])
12633
12634 (define_insn "*lshrqi2_cconly"
12635   [(set (reg FLAGS_REG)
12636         (compare
12637           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12638                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12639           (const_int 0)))
12640    (clobber (match_scratch:QI 0 "=q"))]
12641   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12642    && ix86_match_ccmode (insn, CCGOCmode)
12643    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12644   "shr{b}\t{%2, %0|%0, %2}"
12645   [(set_attr "type" "ishift")
12646    (set_attr "mode" "QI")])
12647 \f
12648 ;; Rotate instructions
12649
12650 (define_expand "rotldi3"
12651   [(set (match_operand:DI 0 "shiftdi_operand" "")
12652         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12653                    (match_operand:QI 2 "nonmemory_operand" "")))]
12654  ""
12655 {
12656   if (TARGET_64BIT)
12657     {
12658       ix86_expand_binary_operator (ROTATE, DImode, operands);
12659       DONE;
12660     }
12661   if (!const_1_to_31_operand (operands[2], VOIDmode))
12662     FAIL;
12663   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12664   DONE;
12665 })
12666
12667 ;; Implement rotation using two double-precision shift instructions
12668 ;; and a scratch register.
12669 (define_insn_and_split "ix86_rotldi3"
12670  [(set (match_operand:DI 0 "register_operand" "=r")
12671        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12672                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12673   (clobber (reg:CC FLAGS_REG))
12674   (clobber (match_scratch:SI 3 "=&r"))]
12675  "!TARGET_64BIT"
12676  ""
12677  "&& reload_completed"
12678  [(set (match_dup 3) (match_dup 4))
12679   (parallel
12680    [(set (match_dup 4)
12681          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12682                  (lshiftrt:SI (match_dup 5)
12683                               (minus:QI (const_int 32) (match_dup 2)))))
12684     (clobber (reg:CC FLAGS_REG))])
12685   (parallel
12686    [(set (match_dup 5)
12687          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12688                  (lshiftrt:SI (match_dup 3)
12689                               (minus:QI (const_int 32) (match_dup 2)))))
12690     (clobber (reg:CC FLAGS_REG))])]
12691  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12692
12693 (define_insn "*rotlsi3_1_one_bit_rex64"
12694   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12695         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12696                    (match_operand:QI 2 "const1_operand" "")))
12697    (clobber (reg:CC FLAGS_REG))]
12698   "TARGET_64BIT
12699    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12700    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12701   "rol{q}\t%0"
12702   [(set_attr "type" "rotate")
12703    (set_attr "length_immediate" "0")
12704    (set_attr "mode" "DI")])
12705
12706 (define_insn "*rotldi3_1_rex64"
12707   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12708         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12709                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12710    (clobber (reg:CC FLAGS_REG))]
12711   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12712   "@
12713    rol{q}\t{%2, %0|%0, %2}
12714    rol{q}\t{%b2, %0|%0, %b2}"
12715   [(set_attr "type" "rotate")
12716    (set_attr "mode" "DI")])
12717
12718 (define_expand "rotlsi3"
12719   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12720         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12721                    (match_operand:QI 2 "nonmemory_operand" "")))]
12722   ""
12723   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12724
12725 (define_insn "*rotlsi3_1_one_bit"
12726   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12727         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12728                    (match_operand:QI 2 "const1_operand" "")))
12729    (clobber (reg:CC FLAGS_REG))]
12730   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12731    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12732   "rol{l}\t%0"
12733   [(set_attr "type" "rotate")
12734    (set_attr "length_immediate" "0")
12735    (set_attr "mode" "SI")])
12736
12737 (define_insn "*rotlsi3_1_one_bit_zext"
12738   [(set (match_operand:DI 0 "register_operand" "=r")
12739         (zero_extend:DI
12740           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12741                      (match_operand:QI 2 "const1_operand" ""))))
12742    (clobber (reg:CC FLAGS_REG))]
12743   "TARGET_64BIT
12744    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12745    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12746   "rol{l}\t%k0"
12747   [(set_attr "type" "rotate")
12748    (set_attr "length_immediate" "0")
12749    (set_attr "mode" "SI")])
12750
12751 (define_insn "*rotlsi3_1"
12752   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12753         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12754                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12755    (clobber (reg:CC FLAGS_REG))]
12756   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12757   "@
12758    rol{l}\t{%2, %0|%0, %2}
12759    rol{l}\t{%b2, %0|%0, %b2}"
12760   [(set_attr "type" "rotate")
12761    (set_attr "mode" "SI")])
12762
12763 (define_insn "*rotlsi3_1_zext"
12764   [(set (match_operand:DI 0 "register_operand" "=r,r")
12765         (zero_extend:DI
12766           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12767                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12768    (clobber (reg:CC FLAGS_REG))]
12769   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12770   "@
12771    rol{l}\t{%2, %k0|%k0, %2}
12772    rol{l}\t{%b2, %k0|%k0, %b2}"
12773   [(set_attr "type" "rotate")
12774    (set_attr "mode" "SI")])
12775
12776 (define_expand "rotlhi3"
12777   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12778         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12779                    (match_operand:QI 2 "nonmemory_operand" "")))]
12780   "TARGET_HIMODE_MATH"
12781   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12782
12783 (define_insn "*rotlhi3_1_one_bit"
12784   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12785         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12786                    (match_operand:QI 2 "const1_operand" "")))
12787    (clobber (reg:CC FLAGS_REG))]
12788   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12789    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12790   "rol{w}\t%0"
12791   [(set_attr "type" "rotate")
12792    (set_attr "length_immediate" "0")
12793    (set_attr "mode" "HI")])
12794
12795 (define_insn "*rotlhi3_1"
12796   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12797         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12798                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12799    (clobber (reg:CC FLAGS_REG))]
12800   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12801   "@
12802    rol{w}\t{%2, %0|%0, %2}
12803    rol{w}\t{%b2, %0|%0, %b2}"
12804   [(set_attr "type" "rotate")
12805    (set_attr "mode" "HI")])
12806
12807 (define_split
12808  [(set (match_operand:HI 0 "register_operand" "")
12809        (rotate:HI (match_dup 0) (const_int 8)))
12810   (clobber (reg:CC FLAGS_REG))]
12811  "reload_completed"
12812  [(parallel [(set (strict_low_part (match_dup 0))
12813                   (bswap:HI (match_dup 0)))
12814              (clobber (reg:CC FLAGS_REG))])]
12815  "")
12816
12817 (define_expand "rotlqi3"
12818   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12819         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12820                    (match_operand:QI 2 "nonmemory_operand" "")))]
12821   "TARGET_QIMODE_MATH"
12822   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12823
12824 (define_insn "*rotlqi3_1_one_bit_slp"
12825   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12826         (rotate:QI (match_dup 0)
12827                    (match_operand:QI 1 "const1_operand" "")))
12828    (clobber (reg:CC FLAGS_REG))]
12829   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12830    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12831   "rol{b}\t%0"
12832   [(set_attr "type" "rotate1")
12833    (set_attr "length_immediate" "0")
12834    (set_attr "mode" "QI")])
12835
12836 (define_insn "*rotlqi3_1_one_bit"
12837   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12838         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12839                    (match_operand:QI 2 "const1_operand" "")))
12840    (clobber (reg:CC FLAGS_REG))]
12841   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12842    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12843   "rol{b}\t%0"
12844   [(set_attr "type" "rotate")
12845    (set_attr "length_immediate" "0")
12846    (set_attr "mode" "QI")])
12847
12848 (define_insn "*rotlqi3_1_slp"
12849   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12850         (rotate:QI (match_dup 0)
12851                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12852    (clobber (reg:CC FLAGS_REG))]
12853   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12854    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12855   "@
12856    rol{b}\t{%1, %0|%0, %1}
12857    rol{b}\t{%b1, %0|%0, %b1}"
12858   [(set_attr "type" "rotate1")
12859    (set_attr "mode" "QI")])
12860
12861 (define_insn "*rotlqi3_1"
12862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12863         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12864                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12867   "@
12868    rol{b}\t{%2, %0|%0, %2}
12869    rol{b}\t{%b2, %0|%0, %b2}"
12870   [(set_attr "type" "rotate")
12871    (set_attr "mode" "QI")])
12872
12873 (define_expand "rotrdi3"
12874   [(set (match_operand:DI 0 "shiftdi_operand" "")
12875         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12876                    (match_operand:QI 2 "nonmemory_operand" "")))]
12877  ""
12878 {
12879   if (TARGET_64BIT)
12880     {
12881       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12882       DONE;
12883     }
12884   if (!const_1_to_31_operand (operands[2], VOIDmode))
12885     FAIL;
12886   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12887   DONE;
12888 })
12889
12890 ;; Implement rotation using two double-precision shift instructions
12891 ;; and a scratch register.
12892 (define_insn_and_split "ix86_rotrdi3"
12893  [(set (match_operand:DI 0 "register_operand" "=r")
12894        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12895                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12896   (clobber (reg:CC FLAGS_REG))
12897   (clobber (match_scratch:SI 3 "=&r"))]
12898  "!TARGET_64BIT"
12899  ""
12900  "&& reload_completed"
12901  [(set (match_dup 3) (match_dup 4))
12902   (parallel
12903    [(set (match_dup 4)
12904          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12905                  (ashift:SI (match_dup 5)
12906                             (minus:QI (const_int 32) (match_dup 2)))))
12907     (clobber (reg:CC FLAGS_REG))])
12908   (parallel
12909    [(set (match_dup 5)
12910          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12911                  (ashift:SI (match_dup 3)
12912                             (minus:QI (const_int 32) (match_dup 2)))))
12913     (clobber (reg:CC FLAGS_REG))])]
12914  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12915
12916 (define_insn "*rotrdi3_1_one_bit_rex64"
12917   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12918         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12919                      (match_operand:QI 2 "const1_operand" "")))
12920    (clobber (reg:CC FLAGS_REG))]
12921   "TARGET_64BIT
12922    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12923    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12924   "ror{q}\t%0"
12925   [(set_attr "type" "rotate")
12926    (set_attr "length_immediate" "0")
12927    (set_attr "mode" "DI")])
12928
12929 (define_insn "*rotrdi3_1_rex64"
12930   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12931         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12932                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12933    (clobber (reg:CC FLAGS_REG))]
12934   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12935   "@
12936    ror{q}\t{%2, %0|%0, %2}
12937    ror{q}\t{%b2, %0|%0, %b2}"
12938   [(set_attr "type" "rotate")
12939    (set_attr "mode" "DI")])
12940
12941 (define_expand "rotrsi3"
12942   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12943         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12944                      (match_operand:QI 2 "nonmemory_operand" "")))]
12945   ""
12946   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12947
12948 (define_insn "*rotrsi3_1_one_bit"
12949   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12950         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12951                      (match_operand:QI 2 "const1_operand" "")))
12952    (clobber (reg:CC FLAGS_REG))]
12953   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12954    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12955   "ror{l}\t%0"
12956   [(set_attr "type" "rotate")
12957    (set_attr "length_immediate" "0")
12958    (set_attr "mode" "SI")])
12959
12960 (define_insn "*rotrsi3_1_one_bit_zext"
12961   [(set (match_operand:DI 0 "register_operand" "=r")
12962         (zero_extend:DI
12963           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12964                        (match_operand:QI 2 "const1_operand" ""))))
12965    (clobber (reg:CC FLAGS_REG))]
12966   "TARGET_64BIT
12967    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12968    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12969   "ror{l}\t%k0"
12970   [(set_attr "type" "rotate")
12971    (set_attr "length_immediate" "0")
12972    (set_attr "mode" "SI")])
12973
12974 (define_insn "*rotrsi3_1"
12975   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12976         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12977                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12978    (clobber (reg:CC FLAGS_REG))]
12979   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12980   "@
12981    ror{l}\t{%2, %0|%0, %2}
12982    ror{l}\t{%b2, %0|%0, %b2}"
12983   [(set_attr "type" "rotate")
12984    (set_attr "mode" "SI")])
12985
12986 (define_insn "*rotrsi3_1_zext"
12987   [(set (match_operand:DI 0 "register_operand" "=r,r")
12988         (zero_extend:DI
12989           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12990                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12991    (clobber (reg:CC FLAGS_REG))]
12992   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12993   "@
12994    ror{l}\t{%2, %k0|%k0, %2}
12995    ror{l}\t{%b2, %k0|%k0, %b2}"
12996   [(set_attr "type" "rotate")
12997    (set_attr "mode" "SI")])
12998
12999 (define_expand "rotrhi3"
13000   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13001         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13002                      (match_operand:QI 2 "nonmemory_operand" "")))]
13003   "TARGET_HIMODE_MATH"
13004   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13005
13006 (define_insn "*rotrhi3_one_bit"
13007   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13008         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13009                      (match_operand:QI 2 "const1_operand" "")))
13010    (clobber (reg:CC FLAGS_REG))]
13011   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13012    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13013   "ror{w}\t%0"
13014   [(set_attr "type" "rotate")
13015    (set_attr "length_immediate" "0")
13016    (set_attr "mode" "HI")])
13017
13018 (define_insn "*rotrhi3_1"
13019   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13020         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13021                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13024   "@
13025    ror{w}\t{%2, %0|%0, %2}
13026    ror{w}\t{%b2, %0|%0, %b2}"
13027   [(set_attr "type" "rotate")
13028    (set_attr "mode" "HI")])
13029
13030 (define_split
13031  [(set (match_operand:HI 0 "register_operand" "")
13032        (rotatert:HI (match_dup 0) (const_int 8)))
13033   (clobber (reg:CC FLAGS_REG))]
13034  "reload_completed"
13035  [(parallel [(set (strict_low_part (match_dup 0))
13036                   (bswap:HI (match_dup 0)))
13037              (clobber (reg:CC FLAGS_REG))])]
13038  "")
13039
13040 (define_expand "rotrqi3"
13041   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13042         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13043                      (match_operand:QI 2 "nonmemory_operand" "")))]
13044   "TARGET_QIMODE_MATH"
13045   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13046
13047 (define_insn "*rotrqi3_1_one_bit"
13048   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13049         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13050                      (match_operand:QI 2 "const1_operand" "")))
13051    (clobber (reg:CC FLAGS_REG))]
13052   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13053    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13054   "ror{b}\t%0"
13055   [(set_attr "type" "rotate")
13056    (set_attr "length_immediate" "0")
13057    (set_attr "mode" "QI")])
13058
13059 (define_insn "*rotrqi3_1_one_bit_slp"
13060   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13061         (rotatert:QI (match_dup 0)
13062                      (match_operand:QI 1 "const1_operand" "")))
13063    (clobber (reg:CC FLAGS_REG))]
13064   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13065    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13066   "ror{b}\t%0"
13067   [(set_attr "type" "rotate1")
13068    (set_attr "length_immediate" "0")
13069    (set_attr "mode" "QI")])
13070
13071 (define_insn "*rotrqi3_1"
13072   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13073         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13074                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13075    (clobber (reg:CC FLAGS_REG))]
13076   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13077   "@
13078    ror{b}\t{%2, %0|%0, %2}
13079    ror{b}\t{%b2, %0|%0, %b2}"
13080   [(set_attr "type" "rotate")
13081    (set_attr "mode" "QI")])
13082
13083 (define_insn "*rotrqi3_1_slp"
13084   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13085         (rotatert:QI (match_dup 0)
13086                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13087    (clobber (reg:CC FLAGS_REG))]
13088   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13089    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13090   "@
13091    ror{b}\t{%1, %0|%0, %1}
13092    ror{b}\t{%b1, %0|%0, %b1}"
13093   [(set_attr "type" "rotate1")
13094    (set_attr "mode" "QI")])
13095 \f
13096 ;; Bit set / bit test instructions
13097
13098 (define_expand "extv"
13099   [(set (match_operand:SI 0 "register_operand" "")
13100         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13101                          (match_operand:SI 2 "const8_operand" "")
13102                          (match_operand:SI 3 "const8_operand" "")))]
13103   ""
13104 {
13105   /* Handle extractions from %ah et al.  */
13106   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13107     FAIL;
13108
13109   /* From mips.md: extract_bit_field doesn't verify that our source
13110      matches the predicate, so check it again here.  */
13111   if (! ext_register_operand (operands[1], VOIDmode))
13112     FAIL;
13113 })
13114
13115 (define_expand "extzv"
13116   [(set (match_operand:SI 0 "register_operand" "")
13117         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13118                          (match_operand:SI 2 "const8_operand" "")
13119                          (match_operand:SI 3 "const8_operand" "")))]
13120   ""
13121 {
13122   /* Handle extractions from %ah et al.  */
13123   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13124     FAIL;
13125
13126   /* From mips.md: extract_bit_field doesn't verify that our source
13127      matches the predicate, so check it again here.  */
13128   if (! ext_register_operand (operands[1], VOIDmode))
13129     FAIL;
13130 })
13131
13132 (define_expand "insv"
13133   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13134                       (match_operand 1 "const8_operand" "")
13135                       (match_operand 2 "const8_operand" ""))
13136         (match_operand 3 "register_operand" ""))]
13137   ""
13138 {
13139   /* Handle insertions to %ah et al.  */
13140   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13141     FAIL;
13142
13143   /* From mips.md: insert_bit_field doesn't verify that our source
13144      matches the predicate, so check it again here.  */
13145   if (! ext_register_operand (operands[0], VOIDmode))
13146     FAIL;
13147
13148   if (TARGET_64BIT)
13149     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13150   else
13151     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13152
13153   DONE;
13154 })
13155
13156 ;; %%% bts, btr, btc, bt.
13157 ;; In general these instructions are *slow* when applied to memory,
13158 ;; since they enforce atomic operation.  When applied to registers,
13159 ;; it depends on the cpu implementation.  They're never faster than
13160 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13161 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13162 ;; within the instruction itself, so operating on bits in the high
13163 ;; 32-bits of a register becomes easier.
13164 ;;
13165 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13166 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13167 ;; negdf respectively, so they can never be disabled entirely.
13168
13169 (define_insn "*btsq"
13170   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13171                          (const_int 1)
13172                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13173         (const_int 1))
13174    (clobber (reg:CC FLAGS_REG))]
13175   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13176   "bts{q}\t{%1, %0|%0, %1}"
13177   [(set_attr "type" "alu1")
13178    (set_attr "prefix_0f" "1")
13179    (set_attr "mode" "DI")])
13180
13181 (define_insn "*btrq"
13182   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13183                          (const_int 1)
13184                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13185         (const_int 0))
13186    (clobber (reg:CC FLAGS_REG))]
13187   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13188   "btr{q}\t{%1, %0|%0, %1}"
13189   [(set_attr "type" "alu1")
13190    (set_attr "prefix_0f" "1")
13191    (set_attr "mode" "DI")])
13192
13193 (define_insn "*btcq"
13194   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13195                          (const_int 1)
13196                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13197         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13198    (clobber (reg:CC FLAGS_REG))]
13199   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13200   "btc{q}\t{%1, %0|%0, %1}"
13201   [(set_attr "type" "alu1")
13202    (set_attr "prefix_0f" "1")
13203    (set_attr "mode" "DI")])
13204
13205 ;; Allow Nocona to avoid these instructions if a register is available.
13206
13207 (define_peephole2
13208   [(match_scratch:DI 2 "r")
13209    (parallel [(set (zero_extract:DI
13210                      (match_operand:DI 0 "register_operand" "")
13211                      (const_int 1)
13212                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13213                    (const_int 1))
13214               (clobber (reg:CC FLAGS_REG))])]
13215   "TARGET_64BIT && !TARGET_USE_BT"
13216   [(const_int 0)]
13217 {
13218   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13219   rtx op1;
13220
13221   if (HOST_BITS_PER_WIDE_INT >= 64)
13222     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13223   else if (i < HOST_BITS_PER_WIDE_INT)
13224     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13225   else
13226     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13227
13228   op1 = immed_double_const (lo, hi, DImode);
13229   if (i >= 31)
13230     {
13231       emit_move_insn (operands[2], op1);
13232       op1 = operands[2];
13233     }
13234
13235   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13236   DONE;
13237 })
13238
13239 (define_peephole2
13240   [(match_scratch:DI 2 "r")
13241    (parallel [(set (zero_extract:DI
13242                      (match_operand:DI 0 "register_operand" "")
13243                      (const_int 1)
13244                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13245                    (const_int 0))
13246               (clobber (reg:CC FLAGS_REG))])]
13247   "TARGET_64BIT && !TARGET_USE_BT"
13248   [(const_int 0)]
13249 {
13250   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13251   rtx op1;
13252
13253   if (HOST_BITS_PER_WIDE_INT >= 64)
13254     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13255   else if (i < HOST_BITS_PER_WIDE_INT)
13256     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13257   else
13258     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13259
13260   op1 = immed_double_const (~lo, ~hi, DImode);
13261   if (i >= 32)
13262     {
13263       emit_move_insn (operands[2], op1);
13264       op1 = operands[2];
13265     }
13266
13267   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13268   DONE;
13269 })
13270
13271 (define_peephole2
13272   [(match_scratch:DI 2 "r")
13273    (parallel [(set (zero_extract:DI
13274                      (match_operand:DI 0 "register_operand" "")
13275                      (const_int 1)
13276                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13277               (not:DI (zero_extract:DI
13278                         (match_dup 0) (const_int 1) (match_dup 1))))
13279               (clobber (reg:CC FLAGS_REG))])]
13280   "TARGET_64BIT && !TARGET_USE_BT"
13281   [(const_int 0)]
13282 {
13283   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13284   rtx op1;
13285
13286   if (HOST_BITS_PER_WIDE_INT >= 64)
13287     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13288   else if (i < HOST_BITS_PER_WIDE_INT)
13289     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13290   else
13291     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13292
13293   op1 = immed_double_const (lo, hi, DImode);
13294   if (i >= 31)
13295     {
13296       emit_move_insn (operands[2], op1);
13297       op1 = operands[2];
13298     }
13299
13300   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13301   DONE;
13302 })
13303
13304 (define_insn "*btdi_rex64"
13305   [(set (reg:CCC FLAGS_REG)
13306         (compare:CCC
13307           (zero_extract:DI
13308             (match_operand:DI 0 "register_operand" "r")
13309             (const_int 1)
13310             (match_operand:DI 1 "nonmemory_operand" "rN"))
13311           (const_int 0)))]
13312   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13313   "bt{q}\t{%1, %0|%0, %1}"
13314   [(set_attr "type" "alu1")
13315    (set_attr "prefix_0f" "1")
13316    (set_attr "mode" "DI")])
13317
13318 (define_insn "*btsi"
13319   [(set (reg:CCC FLAGS_REG)
13320         (compare:CCC
13321           (zero_extract:SI
13322             (match_operand:SI 0 "register_operand" "r")
13323             (const_int 1)
13324             (match_operand:SI 1 "nonmemory_operand" "rN"))
13325           (const_int 0)))]
13326   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13327   "bt{l}\t{%1, %0|%0, %1}"
13328   [(set_attr "type" "alu1")
13329    (set_attr "prefix_0f" "1")
13330    (set_attr "mode" "SI")])
13331 \f
13332 ;; Store-flag instructions.
13333
13334 ;; For all sCOND expanders, also expand the compare or test insn that
13335 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13336
13337 (define_insn_and_split "*setcc_di_1"
13338   [(set (match_operand:DI 0 "register_operand" "=q")
13339         (match_operator:DI 1 "ix86_comparison_operator"
13340           [(reg FLAGS_REG) (const_int 0)]))]
13341   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13342   "#"
13343   "&& reload_completed"
13344   [(set (match_dup 2) (match_dup 1))
13345    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13346 {
13347   PUT_MODE (operands[1], QImode);
13348   operands[2] = gen_lowpart (QImode, operands[0]);
13349 })
13350
13351 (define_insn_and_split "*setcc_si_1_and"
13352   [(set (match_operand:SI 0 "register_operand" "=q")
13353         (match_operator:SI 1 "ix86_comparison_operator"
13354           [(reg FLAGS_REG) (const_int 0)]))
13355    (clobber (reg:CC FLAGS_REG))]
13356   "!TARGET_PARTIAL_REG_STALL
13357    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13358   "#"
13359   "&& reload_completed"
13360   [(set (match_dup 2) (match_dup 1))
13361    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13362               (clobber (reg:CC FLAGS_REG))])]
13363 {
13364   PUT_MODE (operands[1], QImode);
13365   operands[2] = gen_lowpart (QImode, operands[0]);
13366 })
13367
13368 (define_insn_and_split "*setcc_si_1_movzbl"
13369   [(set (match_operand:SI 0 "register_operand" "=q")
13370         (match_operator:SI 1 "ix86_comparison_operator"
13371           [(reg FLAGS_REG) (const_int 0)]))]
13372   "!TARGET_PARTIAL_REG_STALL
13373    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13374   "#"
13375   "&& reload_completed"
13376   [(set (match_dup 2) (match_dup 1))
13377    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13378 {
13379   PUT_MODE (operands[1], QImode);
13380   operands[2] = gen_lowpart (QImode, operands[0]);
13381 })
13382
13383 (define_insn "*setcc_qi"
13384   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13385         (match_operator:QI 1 "ix86_comparison_operator"
13386           [(reg FLAGS_REG) (const_int 0)]))]
13387   ""
13388   "set%C1\t%0"
13389   [(set_attr "type" "setcc")
13390    (set_attr "mode" "QI")])
13391
13392 (define_insn "*setcc_qi_slp"
13393   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13394         (match_operator:QI 1 "ix86_comparison_operator"
13395           [(reg FLAGS_REG) (const_int 0)]))]
13396   ""
13397   "set%C1\t%0"
13398   [(set_attr "type" "setcc")
13399    (set_attr "mode" "QI")])
13400
13401 ;; In general it is not safe to assume too much about CCmode registers,
13402 ;; so simplify-rtx stops when it sees a second one.  Under certain
13403 ;; conditions this is safe on x86, so help combine not create
13404 ;;
13405 ;;      seta    %al
13406 ;;      testb   %al, %al
13407 ;;      sete    %al
13408
13409 (define_split
13410   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13411         (ne:QI (match_operator 1 "ix86_comparison_operator"
13412                  [(reg FLAGS_REG) (const_int 0)])
13413             (const_int 0)))]
13414   ""
13415   [(set (match_dup 0) (match_dup 1))]
13416 {
13417   PUT_MODE (operands[1], QImode);
13418 })
13419
13420 (define_split
13421   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13422         (ne:QI (match_operator 1 "ix86_comparison_operator"
13423                  [(reg FLAGS_REG) (const_int 0)])
13424             (const_int 0)))]
13425   ""
13426   [(set (match_dup 0) (match_dup 1))]
13427 {
13428   PUT_MODE (operands[1], QImode);
13429 })
13430
13431 (define_split
13432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13433         (eq:QI (match_operator 1 "ix86_comparison_operator"
13434                  [(reg FLAGS_REG) (const_int 0)])
13435             (const_int 0)))]
13436   ""
13437   [(set (match_dup 0) (match_dup 1))]
13438 {
13439   rtx new_op1 = copy_rtx (operands[1]);
13440   operands[1] = new_op1;
13441   PUT_MODE (new_op1, QImode);
13442   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13443                                              GET_MODE (XEXP (new_op1, 0))));
13444
13445   /* Make sure that (a) the CCmode we have for the flags is strong
13446      enough for the reversed compare or (b) we have a valid FP compare.  */
13447   if (! ix86_comparison_operator (new_op1, VOIDmode))
13448     FAIL;
13449 })
13450
13451 (define_split
13452   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13453         (eq:QI (match_operator 1 "ix86_comparison_operator"
13454                  [(reg FLAGS_REG) (const_int 0)])
13455             (const_int 0)))]
13456   ""
13457   [(set (match_dup 0) (match_dup 1))]
13458 {
13459   rtx new_op1 = copy_rtx (operands[1]);
13460   operands[1] = new_op1;
13461   PUT_MODE (new_op1, QImode);
13462   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13463                                              GET_MODE (XEXP (new_op1, 0))));
13464
13465   /* Make sure that (a) the CCmode we have for the flags is strong
13466      enough for the reversed compare or (b) we have a valid FP compare.  */
13467   if (! ix86_comparison_operator (new_op1, VOIDmode))
13468     FAIL;
13469 })
13470
13471 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13472 ;; subsequent logical operations are used to imitate conditional moves.
13473 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13474 ;; it directly.
13475
13476 (define_insn "*avx_setcc<mode>"
13477   [(set (match_operand:MODEF 0 "register_operand" "=x")
13478         (match_operator:MODEF 1 "avx_comparison_float_operator"
13479           [(match_operand:MODEF 2 "register_operand" "x")
13480            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13481   "TARGET_AVX"
13482   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13483   [(set_attr "type" "ssecmp")
13484    (set_attr "prefix" "vex")
13485    (set_attr "length_immediate" "1")
13486    (set_attr "mode" "<MODE>")])
13487
13488 (define_insn "*sse_setcc<mode>"
13489   [(set (match_operand:MODEF 0 "register_operand" "=x")
13490         (match_operator:MODEF 1 "sse_comparison_operator"
13491           [(match_operand:MODEF 2 "register_operand" "0")
13492            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13493   "SSE_FLOAT_MODE_P (<MODE>mode)"
13494   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13495   [(set_attr "type" "ssecmp")
13496    (set_attr "length_immediate" "1")
13497    (set_attr "mode" "<MODE>")])
13498 \f
13499 ;; Basic conditional jump instructions.
13500 ;; We ignore the overflow flag for signed branch instructions.
13501
13502 (define_insn "*jcc_1"
13503   [(set (pc)
13504         (if_then_else (match_operator 1 "ix86_comparison_operator"
13505                                       [(reg FLAGS_REG) (const_int 0)])
13506                       (label_ref (match_operand 0 "" ""))
13507                       (pc)))]
13508   ""
13509   "%+j%C1\t%l0"
13510   [(set_attr "type" "ibr")
13511    (set_attr "modrm" "0")
13512    (set (attr "length")
13513            (if_then_else (and (ge (minus (match_dup 0) (pc))
13514                                   (const_int -126))
13515                               (lt (minus (match_dup 0) (pc))
13516                                   (const_int 128)))
13517              (const_int 2)
13518              (const_int 6)))])
13519
13520 (define_insn "*jcc_2"
13521   [(set (pc)
13522         (if_then_else (match_operator 1 "ix86_comparison_operator"
13523                                       [(reg FLAGS_REG) (const_int 0)])
13524                       (pc)
13525                       (label_ref (match_operand 0 "" ""))))]
13526   ""
13527   "%+j%c1\t%l0"
13528   [(set_attr "type" "ibr")
13529    (set_attr "modrm" "0")
13530    (set (attr "length")
13531            (if_then_else (and (ge (minus (match_dup 0) (pc))
13532                                   (const_int -126))
13533                               (lt (minus (match_dup 0) (pc))
13534                                   (const_int 128)))
13535              (const_int 2)
13536              (const_int 6)))])
13537
13538 ;; In general it is not safe to assume too much about CCmode registers,
13539 ;; so simplify-rtx stops when it sees a second one.  Under certain
13540 ;; conditions this is safe on x86, so help combine not create
13541 ;;
13542 ;;      seta    %al
13543 ;;      testb   %al, %al
13544 ;;      je      Lfoo
13545
13546 (define_split
13547   [(set (pc)
13548         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13549                                       [(reg FLAGS_REG) (const_int 0)])
13550                           (const_int 0))
13551                       (label_ref (match_operand 1 "" ""))
13552                       (pc)))]
13553   ""
13554   [(set (pc)
13555         (if_then_else (match_dup 0)
13556                       (label_ref (match_dup 1))
13557                       (pc)))]
13558 {
13559   PUT_MODE (operands[0], VOIDmode);
13560 })
13561
13562 (define_split
13563   [(set (pc)
13564         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13565                                       [(reg FLAGS_REG) (const_int 0)])
13566                           (const_int 0))
13567                       (label_ref (match_operand 1 "" ""))
13568                       (pc)))]
13569   ""
13570   [(set (pc)
13571         (if_then_else (match_dup 0)
13572                       (label_ref (match_dup 1))
13573                       (pc)))]
13574 {
13575   rtx new_op0 = copy_rtx (operands[0]);
13576   operands[0] = new_op0;
13577   PUT_MODE (new_op0, VOIDmode);
13578   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13579                                              GET_MODE (XEXP (new_op0, 0))));
13580
13581   /* Make sure that (a) the CCmode we have for the flags is strong
13582      enough for the reversed compare or (b) we have a valid FP compare.  */
13583   if (! ix86_comparison_operator (new_op0, VOIDmode))
13584     FAIL;
13585 })
13586
13587 ;; zero_extend in SImode is correct, since this is what combine pass
13588 ;; generates from shift insn with QImode operand.  Actually, the mode of
13589 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13590 ;; appropriate modulo of the bit offset value.
13591
13592 (define_insn_and_split "*jcc_btdi_rex64"
13593   [(set (pc)
13594         (if_then_else (match_operator 0 "bt_comparison_operator"
13595                         [(zero_extract:DI
13596                            (match_operand:DI 1 "register_operand" "r")
13597                            (const_int 1)
13598                            (zero_extend:SI
13599                              (match_operand:QI 2 "register_operand" "r")))
13600                          (const_int 0)])
13601                       (label_ref (match_operand 3 "" ""))
13602                       (pc)))
13603    (clobber (reg:CC FLAGS_REG))]
13604   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13605   "#"
13606   "&& 1"
13607   [(set (reg:CCC FLAGS_REG)
13608         (compare:CCC
13609           (zero_extract:DI
13610             (match_dup 1)
13611             (const_int 1)
13612             (match_dup 2))
13613           (const_int 0)))
13614    (set (pc)
13615         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13616                       (label_ref (match_dup 3))
13617                       (pc)))]
13618 {
13619   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13620
13621   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13622 })
13623
13624 ;; avoid useless masking of bit offset operand
13625 (define_insn_and_split "*jcc_btdi_mask_rex64"
13626   [(set (pc)
13627         (if_then_else (match_operator 0 "bt_comparison_operator"
13628                         [(zero_extract:DI
13629                            (match_operand:DI 1 "register_operand" "r")
13630                            (const_int 1)
13631                            (and:SI
13632                              (match_operand:SI 2 "register_operand" "r")
13633                              (match_operand:SI 3 "const_int_operand" "n")))])
13634                       (label_ref (match_operand 4 "" ""))
13635                       (pc)))
13636    (clobber (reg:CC FLAGS_REG))]
13637   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13638    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13639   "#"
13640   "&& 1"
13641   [(set (reg:CCC FLAGS_REG)
13642         (compare:CCC
13643           (zero_extract:DI
13644             (match_dup 1)
13645             (const_int 1)
13646             (match_dup 2))
13647           (const_int 0)))
13648    (set (pc)
13649         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13650                       (label_ref (match_dup 4))
13651                       (pc)))]
13652 {
13653   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13654
13655   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13656 })
13657
13658 (define_insn_and_split "*jcc_btsi"
13659   [(set (pc)
13660         (if_then_else (match_operator 0 "bt_comparison_operator"
13661                         [(zero_extract:SI
13662                            (match_operand:SI 1 "register_operand" "r")
13663                            (const_int 1)
13664                            (zero_extend:SI
13665                              (match_operand:QI 2 "register_operand" "r")))
13666                          (const_int 0)])
13667                       (label_ref (match_operand 3 "" ""))
13668                       (pc)))
13669    (clobber (reg:CC FLAGS_REG))]
13670   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13671   "#"
13672   "&& 1"
13673   [(set (reg:CCC FLAGS_REG)
13674         (compare:CCC
13675           (zero_extract:SI
13676             (match_dup 1)
13677             (const_int 1)
13678             (match_dup 2))
13679           (const_int 0)))
13680    (set (pc)
13681         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13682                       (label_ref (match_dup 3))
13683                       (pc)))]
13684 {
13685   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13686
13687   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13688 })
13689
13690 ;; avoid useless masking of bit offset operand
13691 (define_insn_and_split "*jcc_btsi_mask"
13692   [(set (pc)
13693         (if_then_else (match_operator 0 "bt_comparison_operator"
13694                         [(zero_extract:SI
13695                            (match_operand:SI 1 "register_operand" "r")
13696                            (const_int 1)
13697                            (and:SI
13698                              (match_operand:SI 2 "register_operand" "r")
13699                              (match_operand:SI 3 "const_int_operand" "n")))])
13700                       (label_ref (match_operand 4 "" ""))
13701                       (pc)))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13704    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13705   "#"
13706   "&& 1"
13707   [(set (reg:CCC FLAGS_REG)
13708         (compare:CCC
13709           (zero_extract:SI
13710             (match_dup 1)
13711             (const_int 1)
13712             (match_dup 2))
13713           (const_int 0)))
13714    (set (pc)
13715         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13716                       (label_ref (match_dup 4))
13717                       (pc)))]
13718   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13719
13720 (define_insn_and_split "*jcc_btsi_1"
13721   [(set (pc)
13722         (if_then_else (match_operator 0 "bt_comparison_operator"
13723                         [(and:SI
13724                            (lshiftrt:SI
13725                              (match_operand:SI 1 "register_operand" "r")
13726                              (match_operand:QI 2 "register_operand" "r"))
13727                            (const_int 1))
13728                          (const_int 0)])
13729                       (label_ref (match_operand 3 "" ""))
13730                       (pc)))
13731    (clobber (reg:CC FLAGS_REG))]
13732   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13733   "#"
13734   "&& 1"
13735   [(set (reg:CCC FLAGS_REG)
13736         (compare:CCC
13737           (zero_extract:SI
13738             (match_dup 1)
13739             (const_int 1)
13740             (match_dup 2))
13741           (const_int 0)))
13742    (set (pc)
13743         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13744                       (label_ref (match_dup 3))
13745                       (pc)))]
13746 {
13747   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13748
13749   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13750 })
13751
13752 ;; avoid useless masking of bit offset operand
13753 (define_insn_and_split "*jcc_btsi_mask_1"
13754   [(set (pc)
13755         (if_then_else
13756           (match_operator 0 "bt_comparison_operator"
13757             [(and:SI
13758                (lshiftrt:SI
13759                  (match_operand:SI 1 "register_operand" "r")
13760                  (subreg:QI
13761                    (and:SI
13762                      (match_operand:SI 2 "register_operand" "r")
13763                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13764                (const_int 1))
13765              (const_int 0)])
13766           (label_ref (match_operand 4 "" ""))
13767           (pc)))
13768    (clobber (reg:CC FLAGS_REG))]
13769   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13770    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13771   "#"
13772   "&& 1"
13773   [(set (reg:CCC FLAGS_REG)
13774         (compare:CCC
13775           (zero_extract:SI
13776             (match_dup 1)
13777             (const_int 1)
13778             (match_dup 2))
13779           (const_int 0)))
13780    (set (pc)
13781         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13782                       (label_ref (match_dup 4))
13783                       (pc)))]
13784   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13785
13786 ;; Define combination compare-and-branch fp compare instructions to help
13787 ;; combine.
13788
13789 (define_insn "*fp_jcc_3_387"
13790   [(set (pc)
13791         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13792                         [(match_operand 1 "register_operand" "f")
13793                          (match_operand 2 "nonimmediate_operand" "fm")])
13794           (label_ref (match_operand 3 "" ""))
13795           (pc)))
13796    (clobber (reg:CCFP FPSR_REG))
13797    (clobber (reg:CCFP FLAGS_REG))
13798    (clobber (match_scratch:HI 4 "=a"))]
13799   "TARGET_80387
13800    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13801    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13802    && SELECT_CC_MODE (GET_CODE (operands[0]),
13803                       operands[1], operands[2]) == CCFPmode
13804    && !TARGET_CMOVE"
13805   "#")
13806
13807 (define_insn "*fp_jcc_4_387"
13808   [(set (pc)
13809         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13810                         [(match_operand 1 "register_operand" "f")
13811                          (match_operand 2 "nonimmediate_operand" "fm")])
13812           (pc)
13813           (label_ref (match_operand 3 "" ""))))
13814    (clobber (reg:CCFP FPSR_REG))
13815    (clobber (reg:CCFP FLAGS_REG))
13816    (clobber (match_scratch:HI 4 "=a"))]
13817   "TARGET_80387
13818    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13819    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13820    && SELECT_CC_MODE (GET_CODE (operands[0]),
13821                       operands[1], operands[2]) == CCFPmode
13822    && !TARGET_CMOVE"
13823   "#")
13824
13825 (define_insn "*fp_jcc_5_387"
13826   [(set (pc)
13827         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13828                         [(match_operand 1 "register_operand" "f")
13829                          (match_operand 2 "register_operand" "f")])
13830           (label_ref (match_operand 3 "" ""))
13831           (pc)))
13832    (clobber (reg:CCFP FPSR_REG))
13833    (clobber (reg:CCFP FLAGS_REG))
13834    (clobber (match_scratch:HI 4 "=a"))]
13835   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13836    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13837    && !TARGET_CMOVE"
13838   "#")
13839
13840 (define_insn "*fp_jcc_6_387"
13841   [(set (pc)
13842         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13843                         [(match_operand 1 "register_operand" "f")
13844                          (match_operand 2 "register_operand" "f")])
13845           (pc)
13846           (label_ref (match_operand 3 "" ""))))
13847    (clobber (reg:CCFP FPSR_REG))
13848    (clobber (reg:CCFP FLAGS_REG))
13849    (clobber (match_scratch:HI 4 "=a"))]
13850   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13851    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13852    && !TARGET_CMOVE"
13853   "#")
13854
13855 (define_insn "*fp_jcc_7_387"
13856   [(set (pc)
13857         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13858                         [(match_operand 1 "register_operand" "f")
13859                          (match_operand 2 "const0_operand" "")])
13860           (label_ref (match_operand 3 "" ""))
13861           (pc)))
13862    (clobber (reg:CCFP FPSR_REG))
13863    (clobber (reg:CCFP FLAGS_REG))
13864    (clobber (match_scratch:HI 4 "=a"))]
13865   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13866    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13867    && SELECT_CC_MODE (GET_CODE (operands[0]),
13868                       operands[1], operands[2]) == CCFPmode
13869    && !TARGET_CMOVE"
13870   "#")
13871
13872 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13873 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13874 ;; with a precedence over other operators and is always put in the first
13875 ;; place. Swap condition and operands to match ficom instruction.
13876
13877 (define_insn "*fp_jcc_8<mode>_387"
13878   [(set (pc)
13879         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13880                         [(match_operator 1 "float_operator"
13881                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13882                            (match_operand 3 "register_operand" "f,f")])
13883           (label_ref (match_operand 4 "" ""))
13884           (pc)))
13885    (clobber (reg:CCFP FPSR_REG))
13886    (clobber (reg:CCFP FLAGS_REG))
13887    (clobber (match_scratch:HI 5 "=a,a"))]
13888   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13889    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13890    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13891    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13892    && !TARGET_CMOVE"
13893   "#")
13894
13895 (define_split
13896   [(set (pc)
13897         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13898                         [(match_operand 1 "register_operand" "")
13899                          (match_operand 2 "nonimmediate_operand" "")])
13900           (match_operand 3 "" "")
13901           (match_operand 4 "" "")))
13902    (clobber (reg:CCFP FPSR_REG))
13903    (clobber (reg:CCFP FLAGS_REG))]
13904   "reload_completed"
13905   [(const_int 0)]
13906 {
13907   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13908                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13909   DONE;
13910 })
13911
13912 (define_split
13913   [(set (pc)
13914         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13915                         [(match_operand 1 "register_operand" "")
13916                          (match_operand 2 "general_operand" "")])
13917           (match_operand 3 "" "")
13918           (match_operand 4 "" "")))
13919    (clobber (reg:CCFP FPSR_REG))
13920    (clobber (reg:CCFP FLAGS_REG))
13921    (clobber (match_scratch:HI 5 "=a"))]
13922   "reload_completed"
13923   [(const_int 0)]
13924 {
13925   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13926                         operands[3], operands[4], operands[5], NULL_RTX);
13927   DONE;
13928 })
13929
13930 (define_split
13931   [(set (pc)
13932         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13933                         [(match_operator 1 "float_operator"
13934                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13935                            (match_operand 3 "register_operand" "")])
13936           (match_operand 4 "" "")
13937           (match_operand 5 "" "")))
13938    (clobber (reg:CCFP FPSR_REG))
13939    (clobber (reg:CCFP FLAGS_REG))
13940    (clobber (match_scratch:HI 6 "=a"))]
13941   "reload_completed"
13942   [(const_int 0)]
13943 {
13944   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13945   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13946                         operands[3], operands[7],
13947                         operands[4], operands[5], operands[6], NULL_RTX);
13948   DONE;
13949 })
13950
13951 ;; %%% Kill this when reload knows how to do it.
13952 (define_split
13953   [(set (pc)
13954         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13955                         [(match_operator 1 "float_operator"
13956                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13957                            (match_operand 3 "register_operand" "")])
13958           (match_operand 4 "" "")
13959           (match_operand 5 "" "")))
13960    (clobber (reg:CCFP FPSR_REG))
13961    (clobber (reg:CCFP FLAGS_REG))
13962    (clobber (match_scratch:HI 6 "=a"))]
13963   "reload_completed"
13964   [(const_int 0)]
13965 {
13966   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13967   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13968   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13969                         operands[3], operands[7],
13970                         operands[4], operands[5], operands[6], operands[2]);
13971   DONE;
13972 })
13973 \f
13974 ;; Unconditional and other jump instructions
13975
13976 (define_insn "jump"
13977   [(set (pc)
13978         (label_ref (match_operand 0 "" "")))]
13979   ""
13980   "jmp\t%l0"
13981   [(set_attr "type" "ibr")
13982    (set (attr "length")
13983            (if_then_else (and (ge (minus (match_dup 0) (pc))
13984                                   (const_int -126))
13985                               (lt (minus (match_dup 0) (pc))
13986                                   (const_int 128)))
13987              (const_int 2)
13988              (const_int 5)))
13989    (set_attr "modrm" "0")])
13990
13991 (define_expand "indirect_jump"
13992   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13993   ""
13994   "")
13995
13996 (define_insn "*indirect_jump"
13997   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13998   ""
13999   "jmp\t%A0"
14000   [(set_attr "type" "ibr")
14001    (set_attr "length_immediate" "0")])
14002
14003 (define_expand "tablejump"
14004   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14005               (use (label_ref (match_operand 1 "" "")))])]
14006   ""
14007 {
14008   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14009      relative.  Convert the relative address to an absolute address.  */
14010   if (flag_pic)
14011     {
14012       rtx op0, op1;
14013       enum rtx_code code;
14014
14015       /* We can't use @GOTOFF for text labels on VxWorks;
14016          see gotoff_operand.  */
14017       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14018         {
14019           code = PLUS;
14020           op0 = operands[0];
14021           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14022         }
14023       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14024         {
14025           code = PLUS;
14026           op0 = operands[0];
14027           op1 = pic_offset_table_rtx;
14028         }
14029       else
14030         {
14031           code = MINUS;
14032           op0 = pic_offset_table_rtx;
14033           op1 = operands[0];
14034         }
14035
14036       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14037                                          OPTAB_DIRECT);
14038     }
14039 })
14040
14041 (define_insn "*tablejump_1"
14042   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14043    (use (label_ref (match_operand 1 "" "")))]
14044   ""
14045   "jmp\t%A0"
14046   [(set_attr "type" "ibr")
14047    (set_attr "length_immediate" "0")])
14048 \f
14049 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14050
14051 (define_peephole2
14052   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14053    (set (match_operand:QI 1 "register_operand" "")
14054         (match_operator:QI 2 "ix86_comparison_operator"
14055           [(reg FLAGS_REG) (const_int 0)]))
14056    (set (match_operand 3 "q_regs_operand" "")
14057         (zero_extend (match_dup 1)))]
14058   "(peep2_reg_dead_p (3, operands[1])
14059     || operands_match_p (operands[1], operands[3]))
14060    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14061   [(set (match_dup 4) (match_dup 0))
14062    (set (strict_low_part (match_dup 5))
14063         (match_dup 2))]
14064 {
14065   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14066   operands[5] = gen_lowpart (QImode, operands[3]);
14067   ix86_expand_clear (operands[3]);
14068 })
14069
14070 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14071
14072 (define_peephole2
14073   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14074    (set (match_operand:QI 1 "register_operand" "")
14075         (match_operator:QI 2 "ix86_comparison_operator"
14076           [(reg FLAGS_REG) (const_int 0)]))
14077    (parallel [(set (match_operand 3 "q_regs_operand" "")
14078                    (zero_extend (match_dup 1)))
14079               (clobber (reg:CC FLAGS_REG))])]
14080   "(peep2_reg_dead_p (3, operands[1])
14081     || operands_match_p (operands[1], operands[3]))
14082    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14083   [(set (match_dup 4) (match_dup 0))
14084    (set (strict_low_part (match_dup 5))
14085         (match_dup 2))]
14086 {
14087   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14088   operands[5] = gen_lowpart (QImode, operands[3]);
14089   ix86_expand_clear (operands[3]);
14090 })
14091 \f
14092 ;; Call instructions.
14093
14094 ;; The predicates normally associated with named expanders are not properly
14095 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14096 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14097
14098 ;; P6 processors will jump to the address after the decrement when %esp
14099 ;; is used as a call operand, so they will execute return address as a code.
14100 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14101  
14102 ;; Call subroutine returning no value.
14103
14104 (define_expand "call_pop"
14105   [(parallel [(call (match_operand:QI 0 "" "")
14106                     (match_operand:SI 1 "" ""))
14107               (set (reg:SI SP_REG)
14108                    (plus:SI (reg:SI SP_REG)
14109                             (match_operand:SI 3 "" "")))])]
14110   "!TARGET_64BIT"
14111 {
14112   ix86_expand_call (NULL, operands[0], operands[1],
14113                     operands[2], operands[3], 0);
14114   DONE;
14115 })
14116
14117 (define_insn "*call_pop_0"
14118   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14119          (match_operand:SI 1 "" ""))
14120    (set (reg:SI SP_REG)
14121         (plus:SI (reg:SI SP_REG)
14122                  (match_operand:SI 2 "immediate_operand" "")))]
14123   "!TARGET_64BIT"
14124 {
14125   if (SIBLING_CALL_P (insn))
14126     return "jmp\t%P0";
14127   else
14128     return "call\t%P0";
14129 }
14130   [(set_attr "type" "call")])
14131
14132 (define_insn "*call_pop_1"
14133   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14134          (match_operand:SI 1 "" ""))
14135    (set (reg:SI SP_REG)
14136         (plus:SI (reg:SI SP_REG)
14137                  (match_operand:SI 2 "immediate_operand" "i")))]
14138   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14139 {
14140   if (constant_call_address_operand (operands[0], Pmode))
14141     return "call\t%P0";
14142   return "call\t%A0";
14143 }
14144   [(set_attr "type" "call")])
14145
14146 (define_insn "*sibcall_pop_1"
14147   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14148          (match_operand:SI 1 "" ""))
14149    (set (reg:SI SP_REG)
14150         (plus:SI (reg:SI SP_REG)
14151                  (match_operand:SI 2 "immediate_operand" "i,i")))]
14152   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14153   "@
14154    jmp\t%P0
14155    jmp\t%A0"
14156   [(set_attr "type" "call")])
14157
14158 (define_expand "call"
14159   [(call (match_operand:QI 0 "" "")
14160          (match_operand 1 "" ""))
14161    (use (match_operand 2 "" ""))]
14162   ""
14163 {
14164   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14165   DONE;
14166 })
14167
14168 (define_expand "sibcall"
14169   [(call (match_operand:QI 0 "" "")
14170          (match_operand 1 "" ""))
14171    (use (match_operand 2 "" ""))]
14172   ""
14173 {
14174   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14175   DONE;
14176 })
14177
14178 (define_insn "*call_0"
14179   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14180          (match_operand 1 "" ""))]
14181   ""
14182 {
14183   if (SIBLING_CALL_P (insn))
14184     return "jmp\t%P0";
14185   else
14186     return "call\t%P0";
14187 }
14188   [(set_attr "type" "call")])
14189
14190 (define_insn "*call_1"
14191   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14192          (match_operand 1 "" ""))]
14193   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14194 {
14195   if (constant_call_address_operand (operands[0], Pmode))
14196     return "call\t%P0";
14197   return "call\t%A0";
14198 }
14199   [(set_attr "type" "call")])
14200
14201 (define_insn "*sibcall_1"
14202   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14203          (match_operand 1 "" ""))]
14204   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14205   "@
14206    jmp\t%P0
14207    jmp\t%A0"
14208   [(set_attr "type" "call")])
14209
14210 (define_insn "*call_1_rex64"
14211   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14212          (match_operand 1 "" ""))]
14213   "TARGET_64BIT && !SIBLING_CALL_P (insn)
14214    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14215 {
14216   if (constant_call_address_operand (operands[0], Pmode))
14217     return "call\t%P0";
14218   return "call\t%A0";
14219 }
14220   [(set_attr "type" "call")])
14221
14222 (define_insn "*call_1_rex64_ms_sysv"
14223   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14224          (match_operand 1 "" ""))
14225    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14226    (clobber (reg:TI XMM6_REG))
14227    (clobber (reg:TI XMM7_REG))
14228    (clobber (reg:TI XMM8_REG))
14229    (clobber (reg:TI XMM9_REG))
14230    (clobber (reg:TI XMM10_REG))
14231    (clobber (reg:TI XMM11_REG))
14232    (clobber (reg:TI XMM12_REG))
14233    (clobber (reg:TI XMM13_REG))
14234    (clobber (reg:TI XMM14_REG))
14235    (clobber (reg:TI XMM15_REG))
14236    (clobber (reg:DI SI_REG))
14237    (clobber (reg:DI DI_REG))]
14238   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14239 {
14240   if (constant_call_address_operand (operands[0], Pmode))
14241     return "call\t%P0";
14242   return "call\t%A0";
14243 }
14244   [(set_attr "type" "call")])
14245
14246 (define_insn "*call_1_rex64_large"
14247   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14248          (match_operand 1 "" ""))]
14249   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14250   "call\t%A0"
14251   [(set_attr "type" "call")])
14252
14253 (define_insn "*sibcall_1_rex64"
14254   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14255          (match_operand 1 "" ""))]
14256   "TARGET_64BIT && SIBLING_CALL_P (insn)"
14257   "@
14258    jmp\t%P0
14259    jmp\t%A0"
14260   [(set_attr "type" "call")])
14261
14262 ;; Call subroutine, returning value in operand 0
14263 (define_expand "call_value_pop"
14264   [(parallel [(set (match_operand 0 "" "")
14265                    (call (match_operand:QI 1 "" "")
14266                          (match_operand:SI 2 "" "")))
14267               (set (reg:SI SP_REG)
14268                    (plus:SI (reg:SI SP_REG)
14269                             (match_operand:SI 4 "" "")))])]
14270   "!TARGET_64BIT"
14271 {
14272   ix86_expand_call (operands[0], operands[1], operands[2],
14273                     operands[3], operands[4], 0);
14274   DONE;
14275 })
14276
14277 (define_expand "call_value"
14278   [(set (match_operand 0 "" "")
14279         (call (match_operand:QI 1 "" "")
14280               (match_operand:SI 2 "" "")))
14281    (use (match_operand:SI 3 "" ""))]
14282   ;; Operand 3 is not used on the i386.
14283   ""
14284 {
14285   ix86_expand_call (operands[0], operands[1], operands[2],
14286                     operands[3], NULL, 0);
14287   DONE;
14288 })
14289
14290 (define_expand "sibcall_value"
14291   [(set (match_operand 0 "" "")
14292         (call (match_operand:QI 1 "" "")
14293               (match_operand:SI 2 "" "")))
14294    (use (match_operand:SI 3 "" ""))]
14295   ;; Operand 3 is not used on the i386.
14296   ""
14297 {
14298   ix86_expand_call (operands[0], operands[1], operands[2],
14299                     operands[3], NULL, 1);
14300   DONE;
14301 })
14302
14303 ;; Call subroutine returning any type.
14304
14305 (define_expand "untyped_call"
14306   [(parallel [(call (match_operand 0 "" "")
14307                     (const_int 0))
14308               (match_operand 1 "" "")
14309               (match_operand 2 "" "")])]
14310   ""
14311 {
14312   int i;
14313
14314   /* In order to give reg-stack an easier job in validating two
14315      coprocessor registers as containing a possible return value,
14316      simply pretend the untyped call returns a complex long double
14317      value. 
14318
14319      We can't use SSE_REGPARM_MAX here since callee is unprototyped
14320      and should have the default ABI.  */
14321
14322   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14323                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14324                     operands[0], const0_rtx,
14325                     GEN_INT ((TARGET_64BIT
14326                               ? (ix86_abi == SYSV_ABI
14327                                  ? X86_64_SSE_REGPARM_MAX
14328                                  : X86_64_MS_SSE_REGPARM_MAX)
14329                               : X86_32_SSE_REGPARM_MAX)
14330                              - 1),
14331                     NULL, 0);
14332
14333   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14334     {
14335       rtx set = XVECEXP (operands[2], 0, i);
14336       emit_move_insn (SET_DEST (set), SET_SRC (set));
14337     }
14338
14339   /* The optimizer does not know that the call sets the function value
14340      registers we stored in the result block.  We avoid problems by
14341      claiming that all hard registers are used and clobbered at this
14342      point.  */
14343   emit_insn (gen_blockage ());
14344
14345   DONE;
14346 })
14347 \f
14348 ;; Prologue and epilogue instructions
14349
14350 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14351 ;; all of memory.  This blocks insns from being moved across this point.
14352
14353 (define_insn "blockage"
14354   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14355   ""
14356   ""
14357   [(set_attr "length" "0")])
14358
14359 ;; Do not schedule instructions accessing memory across this point.
14360
14361 (define_expand "memory_blockage"
14362   [(set (match_dup 0)
14363         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14364   ""
14365 {
14366   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14367   MEM_VOLATILE_P (operands[0]) = 1;
14368 })
14369
14370 (define_insn "*memory_blockage"
14371   [(set (match_operand:BLK 0 "" "")
14372         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14373   ""
14374   ""
14375   [(set_attr "length" "0")])
14376
14377 ;; As USE insns aren't meaningful after reload, this is used instead
14378 ;; to prevent deleting instructions setting registers for PIC code
14379 (define_insn "prologue_use"
14380   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14381   ""
14382   ""
14383   [(set_attr "length" "0")])
14384
14385 ;; Insn emitted into the body of a function to return from a function.
14386 ;; This is only done if the function's epilogue is known to be simple.
14387 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14388
14389 (define_expand "return"
14390   [(return)]
14391   "ix86_can_use_return_insn_p ()"
14392 {
14393   if (crtl->args.pops_args)
14394     {
14395       rtx popc = GEN_INT (crtl->args.pops_args);
14396       emit_jump_insn (gen_return_pop_internal (popc));
14397       DONE;
14398     }
14399 })
14400
14401 (define_insn "return_internal"
14402   [(return)]
14403   "reload_completed"
14404   "ret"
14405   [(set_attr "length" "1")
14406    (set_attr "atom_unit" "jeu")
14407    (set_attr "length_immediate" "0")
14408    (set_attr "modrm" "0")])
14409
14410 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14411 ;; instruction Athlon and K8 have.
14412
14413 (define_insn "return_internal_long"
14414   [(return)
14415    (unspec [(const_int 0)] UNSPEC_REP)]
14416   "reload_completed"
14417   "rep\;ret"
14418   [(set_attr "length" "2")
14419    (set_attr "atom_unit" "jeu")
14420    (set_attr "length_immediate" "0")
14421    (set_attr "prefix_rep" "1")
14422    (set_attr "modrm" "0")])
14423
14424 (define_insn "return_pop_internal"
14425   [(return)
14426    (use (match_operand:SI 0 "const_int_operand" ""))]
14427   "reload_completed"
14428   "ret\t%0"
14429   [(set_attr "length" "3")
14430    (set_attr "atom_unit" "jeu")
14431    (set_attr "length_immediate" "2")
14432    (set_attr "modrm" "0")])
14433
14434 (define_insn "return_indirect_internal"
14435   [(return)
14436    (use (match_operand:SI 0 "register_operand" "r"))]
14437   "reload_completed"
14438   "jmp\t%A0"
14439   [(set_attr "type" "ibr")
14440    (set_attr "length_immediate" "0")])
14441
14442 (define_insn "nop"
14443   [(const_int 0)]
14444   ""
14445   "nop"
14446   [(set_attr "length" "1")
14447    (set_attr "length_immediate" "0")
14448    (set_attr "modrm" "0")])
14449
14450 (define_insn "vswapmov"
14451   [(set (match_operand:SI 0 "register_operand" "=r")
14452         (match_operand:SI 1 "register_operand" "r"))
14453    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14454   ""
14455   "movl.s\t{%1, %0|%0, %1}"
14456   [(set_attr "length" "2")
14457    (set_attr "length_immediate" "0")
14458    (set_attr "modrm" "0")])
14459
14460 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
14461 ;; branch prediction penalty for the third jump in a 16-byte
14462 ;; block on K8.
14463
14464 (define_insn "pad"
14465   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14466   ""
14467 {
14468 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14469   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14470 #else
14471   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14472      The align insn is used to avoid 3 jump instructions in the row to improve
14473      branch prediction and the benefits hardly outweigh the cost of extra 8
14474      nops on the average inserted by full alignment pseudo operation.  */
14475 #endif
14476   return "";
14477 }
14478   [(set_attr "length" "16")])
14479
14480 (define_expand "prologue"
14481   [(const_int 0)]
14482   ""
14483   "ix86_expand_prologue (); DONE;")
14484
14485 (define_insn "set_got"
14486   [(set (match_operand:SI 0 "register_operand" "=r")
14487         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14488    (clobber (reg:CC FLAGS_REG))]
14489   "!TARGET_64BIT"
14490   { return output_set_got (operands[0], NULL_RTX); }
14491   [(set_attr "type" "multi")
14492    (set_attr "length" "12")])
14493
14494 (define_insn "set_got_labelled"
14495   [(set (match_operand:SI 0 "register_operand" "=r")
14496         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14497          UNSPEC_SET_GOT))
14498    (clobber (reg:CC FLAGS_REG))]
14499   "!TARGET_64BIT"
14500   { return output_set_got (operands[0], operands[1]); }
14501   [(set_attr "type" "multi")
14502    (set_attr "length" "12")])
14503
14504 (define_insn "set_got_rex64"
14505   [(set (match_operand:DI 0 "register_operand" "=r")
14506         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14507   "TARGET_64BIT"
14508   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14509   [(set_attr "type" "lea")
14510    (set_attr "length_address" "4")
14511    (set_attr "mode" "DI")])
14512
14513 (define_insn "set_rip_rex64"
14514   [(set (match_operand:DI 0 "register_operand" "=r")
14515         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14516   "TARGET_64BIT"
14517   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14518   [(set_attr "type" "lea")
14519    (set_attr "length_address" "4")
14520    (set_attr "mode" "DI")])
14521
14522 (define_insn "set_got_offset_rex64"
14523   [(set (match_operand:DI 0 "register_operand" "=r")
14524         (unspec:DI
14525           [(label_ref (match_operand 1 "" ""))]
14526           UNSPEC_SET_GOT_OFFSET))]
14527   "TARGET_64BIT"
14528   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14529   [(set_attr "type" "imov")
14530    (set_attr "length_immediate" "0")
14531    (set_attr "length_address" "8")
14532    (set_attr "mode" "DI")])
14533
14534 (define_expand "epilogue"
14535   [(const_int 0)]
14536   ""
14537   "ix86_expand_epilogue (1); DONE;")
14538
14539 (define_expand "sibcall_epilogue"
14540   [(const_int 0)]
14541   ""
14542   "ix86_expand_epilogue (0); DONE;")
14543
14544 (define_expand "eh_return"
14545   [(use (match_operand 0 "register_operand" ""))]
14546   ""
14547 {
14548   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14549
14550   /* Tricky bit: we write the address of the handler to which we will
14551      be returning into someone else's stack frame, one word below the
14552      stack address we wish to restore.  */
14553   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14554   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14555   tmp = gen_rtx_MEM (Pmode, tmp);
14556   emit_move_insn (tmp, ra);
14557
14558   emit_jump_insn (gen_eh_return_internal ());
14559   emit_barrier ();
14560   DONE;
14561 })
14562
14563 (define_insn_and_split "eh_return_internal"
14564   [(eh_return)]
14565   ""
14566   "#"
14567   "epilogue_completed"
14568   [(const_int 0)]
14569   "ix86_expand_epilogue (2); DONE;")
14570
14571 (define_insn "leave"
14572   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14573    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14574    (clobber (mem:BLK (scratch)))]
14575   "!TARGET_64BIT"
14576   "leave"
14577   [(set_attr "type" "leave")])
14578
14579 (define_insn "leave_rex64"
14580   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14581    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14582    (clobber (mem:BLK (scratch)))]
14583   "TARGET_64BIT"
14584   "leave"
14585   [(set_attr "type" "leave")])
14586 \f
14587 (define_expand "ffssi2"
14588   [(parallel
14589      [(set (match_operand:SI 0 "register_operand" "")
14590            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14591       (clobber (match_scratch:SI 2 ""))
14592       (clobber (reg:CC FLAGS_REG))])]
14593   ""
14594 {
14595   if (TARGET_CMOVE)
14596     {
14597       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14598       DONE;
14599     }
14600 })
14601
14602 (define_expand "ffs_cmove"
14603   [(set (match_dup 2) (const_int -1))
14604    (parallel [(set (reg:CCZ FLAGS_REG)
14605                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14606                                 (const_int 0)))
14607               (set (match_operand:SI 0 "register_operand" "")
14608                    (ctz:SI (match_dup 1)))])
14609    (set (match_dup 0) (if_then_else:SI
14610                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14611                         (match_dup 2)
14612                         (match_dup 0)))
14613    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14614               (clobber (reg:CC FLAGS_REG))])]
14615   "TARGET_CMOVE"
14616   "operands[2] = gen_reg_rtx (SImode);")
14617
14618 (define_insn_and_split "*ffs_no_cmove"
14619   [(set (match_operand:SI 0 "register_operand" "=r")
14620         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14621    (clobber (match_scratch:SI 2 "=&q"))
14622    (clobber (reg:CC FLAGS_REG))]
14623   "!TARGET_CMOVE"
14624   "#"
14625   "&& reload_completed"
14626   [(parallel [(set (reg:CCZ FLAGS_REG)
14627                    (compare:CCZ (match_dup 1) (const_int 0)))
14628               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14629    (set (strict_low_part (match_dup 3))
14630         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14631    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14632               (clobber (reg:CC FLAGS_REG))])
14633    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14634               (clobber (reg:CC FLAGS_REG))])
14635    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14636               (clobber (reg:CC FLAGS_REG))])]
14637 {
14638   operands[3] = gen_lowpart (QImode, operands[2]);
14639   ix86_expand_clear (operands[2]);
14640 })
14641
14642 (define_insn "*ffssi_1"
14643   [(set (reg:CCZ FLAGS_REG)
14644         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14645                      (const_int 0)))
14646    (set (match_operand:SI 0 "register_operand" "=r")
14647         (ctz:SI (match_dup 1)))]
14648   ""
14649   "bsf{l}\t{%1, %0|%0, %1}"
14650   [(set_attr "type" "alu1")
14651    (set_attr "prefix_0f" "1")
14652    (set_attr "mode" "SI")])
14653
14654 (define_expand "ffsdi2"
14655   [(set (match_dup 2) (const_int -1))
14656    (parallel [(set (reg:CCZ FLAGS_REG)
14657                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14658                                 (const_int 0)))
14659               (set (match_operand:DI 0 "register_operand" "")
14660                    (ctz:DI (match_dup 1)))])
14661    (set (match_dup 0) (if_then_else:DI
14662                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14663                         (match_dup 2)
14664                         (match_dup 0)))
14665    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14666               (clobber (reg:CC FLAGS_REG))])]
14667   "TARGET_64BIT"
14668   "operands[2] = gen_reg_rtx (DImode);")
14669
14670 (define_insn "*ffsdi_1"
14671   [(set (reg:CCZ FLAGS_REG)
14672         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14673                      (const_int 0)))
14674    (set (match_operand:DI 0 "register_operand" "=r")
14675         (ctz:DI (match_dup 1)))]
14676   "TARGET_64BIT"
14677   "bsf{q}\t{%1, %0|%0, %1}"
14678   [(set_attr "type" "alu1")
14679    (set_attr "prefix_0f" "1")
14680    (set_attr "mode" "DI")])
14681
14682 (define_insn "ctzsi2"
14683   [(set (match_operand:SI 0 "register_operand" "=r")
14684         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14685    (clobber (reg:CC FLAGS_REG))]
14686   ""
14687   "bsf{l}\t{%1, %0|%0, %1}"
14688   [(set_attr "type" "alu1")
14689    (set_attr "prefix_0f" "1")
14690    (set_attr "mode" "SI")])
14691
14692 (define_insn "ctzdi2"
14693   [(set (match_operand:DI 0 "register_operand" "=r")
14694         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14695    (clobber (reg:CC FLAGS_REG))]
14696   "TARGET_64BIT"
14697   "bsf{q}\t{%1, %0|%0, %1}"
14698   [(set_attr "type" "alu1")
14699    (set_attr "prefix_0f" "1")
14700    (set_attr "mode" "DI")])
14701
14702 (define_expand "clzsi2"
14703   [(parallel
14704      [(set (match_operand:SI 0 "register_operand" "")
14705            (minus:SI (const_int 31)
14706                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14707       (clobber (reg:CC FLAGS_REG))])
14708    (parallel
14709      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14710       (clobber (reg:CC FLAGS_REG))])]
14711   ""
14712 {
14713   if (TARGET_ABM)
14714     {
14715       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14716       DONE;
14717     }
14718 })
14719
14720 (define_insn "clzsi2_abm"
14721   [(set (match_operand:SI 0 "register_operand" "=r")
14722         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14723    (clobber (reg:CC FLAGS_REG))]
14724   "TARGET_ABM"
14725   "lzcnt{l}\t{%1, %0|%0, %1}"
14726   [(set_attr "prefix_rep" "1")
14727    (set_attr "type" "bitmanip")
14728    (set_attr "mode" "SI")])
14729
14730 (define_insn "bsr"
14731   [(set (match_operand:SI 0 "register_operand" "=r")
14732         (minus:SI (const_int 31)
14733                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14734    (clobber (reg:CC FLAGS_REG))]
14735   ""
14736   "bsr{l}\t{%1, %0|%0, %1}"
14737   [(set_attr "type" "alu1")
14738    (set_attr "prefix_0f" "1")
14739    (set_attr "mode" "SI")])
14740
14741 (define_insn "popcount<mode>2"
14742   [(set (match_operand:SWI248 0 "register_operand" "=r")
14743         (popcount:SWI248
14744           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14745    (clobber (reg:CC FLAGS_REG))]
14746   "TARGET_POPCNT"
14747 {
14748 #if TARGET_MACHO
14749   return "popcnt\t{%1, %0|%0, %1}";
14750 #else
14751   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14752 #endif
14753 }
14754   [(set_attr "prefix_rep" "1")
14755    (set_attr "type" "bitmanip")
14756    (set_attr "mode" "<MODE>")])
14757
14758 (define_insn "*popcount<mode>2_cmp"
14759   [(set (reg FLAGS_REG)
14760         (compare
14761           (popcount:SWI248
14762             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14763           (const_int 0)))
14764    (set (match_operand:SWI248 0 "register_operand" "=r")
14765         (popcount:SWI248 (match_dup 1)))]
14766   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14767 {
14768 #if TARGET_MACHO
14769   return "popcnt\t{%1, %0|%0, %1}";
14770 #else
14771   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14772 #endif
14773 }
14774   [(set_attr "prefix_rep" "1")
14775    (set_attr "type" "bitmanip")
14776    (set_attr "mode" "<MODE>")])
14777
14778 (define_insn "*popcountsi2_cmp_zext"
14779   [(set (reg FLAGS_REG)
14780         (compare
14781           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14782           (const_int 0)))
14783    (set (match_operand:DI 0 "register_operand" "=r")
14784         (zero_extend:DI(popcount:SI (match_dup 1))))]
14785   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14786 {
14787 #if TARGET_MACHO
14788   return "popcnt\t{%1, %0|%0, %1}";
14789 #else
14790   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14791 #endif
14792 }
14793   [(set_attr "prefix_rep" "1")
14794    (set_attr "type" "bitmanip")
14795    (set_attr "mode" "SI")])
14796
14797 (define_expand "bswapsi2"
14798   [(set (match_operand:SI 0 "register_operand" "")
14799         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14800   ""
14801 {
14802   if (!(TARGET_BSWAP || TARGET_MOVBE))
14803     {
14804       rtx x = operands[0];
14805
14806       emit_move_insn (x, operands[1]);
14807       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14808       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14809       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14810       DONE;
14811     }
14812 })
14813
14814 (define_insn "*bswapsi_movbe"
14815   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14816         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14817   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14818   "@
14819     bswap\t%0
14820     movbe\t{%1, %0|%0, %1}
14821     movbe\t{%1, %0|%0, %1}"
14822   [(set_attr "type" "*,imov,imov")
14823    (set_attr "modrm" "*,1,1")
14824    (set_attr "prefix_0f" "1")
14825    (set_attr "prefix_extra" "*,1,1")
14826    (set_attr "length" "2,*,*")
14827    (set_attr "mode" "SI")])
14828
14829 (define_insn "*bswapsi_1"
14830   [(set (match_operand:SI 0 "register_operand" "=r")
14831         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14832   "TARGET_BSWAP"
14833   "bswap\t%0"
14834   [(set_attr "prefix_0f" "1")
14835    (set_attr "length" "2")])
14836
14837 (define_insn "*bswaphi_lowpart_1"
14838   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14839         (bswap:HI (match_dup 0)))
14840    (clobber (reg:CC FLAGS_REG))]
14841   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14842   "@
14843     xchg{b}\t{%h0, %b0|%b0, %h0}
14844     rol{w}\t{$8, %0|%0, 8}"
14845   [(set_attr "length" "2,4")
14846    (set_attr "mode" "QI,HI")])
14847
14848 (define_insn "bswaphi_lowpart"
14849   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14850         (bswap:HI (match_dup 0)))
14851    (clobber (reg:CC FLAGS_REG))]
14852   ""
14853   "rol{w}\t{$8, %0|%0, 8}"
14854   [(set_attr "length" "4")
14855    (set_attr "mode" "HI")])
14856
14857 (define_expand "bswapdi2"
14858   [(set (match_operand:DI 0 "register_operand" "")
14859         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14860   "TARGET_64BIT"
14861   "")
14862
14863 (define_insn "*bswapdi_movbe"
14864   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14865         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14866   "TARGET_64BIT && TARGET_MOVBE
14867    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14868   "@
14869     bswap\t%0
14870     movbe\t{%1, %0|%0, %1}
14871     movbe\t{%1, %0|%0, %1}"
14872   [(set_attr "type" "*,imov,imov")
14873    (set_attr "modrm" "*,1,1")
14874    (set_attr "prefix_0f" "1")
14875    (set_attr "prefix_extra" "*,1,1")
14876    (set_attr "length" "3,*,*")
14877    (set_attr "mode" "DI")])
14878
14879 (define_insn "*bswapdi_1"
14880   [(set (match_operand:DI 0 "register_operand" "=r")
14881         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14882   "TARGET_64BIT"
14883   "bswap\t%0"
14884   [(set_attr "prefix_0f" "1")
14885    (set_attr "length" "3")])
14886
14887 (define_expand "clzdi2"
14888   [(parallel
14889      [(set (match_operand:DI 0 "register_operand" "")
14890            (minus:DI (const_int 63)
14891                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14892       (clobber (reg:CC FLAGS_REG))])
14893    (parallel
14894      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14895       (clobber (reg:CC FLAGS_REG))])]
14896   "TARGET_64BIT"
14897 {
14898   if (TARGET_ABM)
14899     {
14900       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14901       DONE;
14902     }
14903 })
14904
14905 (define_insn "clzdi2_abm"
14906   [(set (match_operand:DI 0 "register_operand" "=r")
14907         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14908    (clobber (reg:CC FLAGS_REG))]
14909   "TARGET_64BIT && TARGET_ABM"
14910   "lzcnt{q}\t{%1, %0|%0, %1}"
14911   [(set_attr "prefix_rep" "1")
14912    (set_attr "type" "bitmanip")
14913    (set_attr "mode" "DI")])
14914
14915 (define_insn "bsr_rex64"
14916   [(set (match_operand:DI 0 "register_operand" "=r")
14917         (minus:DI (const_int 63)
14918                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14919    (clobber (reg:CC FLAGS_REG))]
14920   "TARGET_64BIT"
14921   "bsr{q}\t{%1, %0|%0, %1}"
14922   [(set_attr "type" "alu1")
14923    (set_attr "prefix_0f" "1")
14924    (set_attr "mode" "DI")])
14925
14926 (define_expand "clzhi2"
14927   [(parallel
14928      [(set (match_operand:HI 0 "register_operand" "")
14929            (minus:HI (const_int 15)
14930                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14931       (clobber (reg:CC FLAGS_REG))])
14932    (parallel
14933      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14934       (clobber (reg:CC FLAGS_REG))])]
14935   ""
14936 {
14937   if (TARGET_ABM)
14938     {
14939       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14940       DONE;
14941     }
14942 })
14943
14944 (define_insn "clzhi2_abm"
14945   [(set (match_operand:HI 0 "register_operand" "=r")
14946         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14947    (clobber (reg:CC FLAGS_REG))]
14948   "TARGET_ABM"
14949   "lzcnt{w}\t{%1, %0|%0, %1}"
14950   [(set_attr "prefix_rep" "1")
14951    (set_attr "type" "bitmanip")
14952    (set_attr "mode" "HI")])
14953
14954 (define_insn "*bsrhi"
14955   [(set (match_operand:HI 0 "register_operand" "=r")
14956         (minus:HI (const_int 15)
14957                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14958    (clobber (reg:CC FLAGS_REG))]
14959   ""
14960   "bsr{w}\t{%1, %0|%0, %1}"
14961   [(set_attr "type" "alu1")
14962    (set_attr "prefix_0f" "1")
14963    (set_attr "mode" "HI")])
14964
14965 (define_expand "paritydi2"
14966   [(set (match_operand:DI 0 "register_operand" "")
14967         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14968   "! TARGET_POPCNT"
14969 {
14970   rtx scratch = gen_reg_rtx (QImode);
14971   rtx cond;
14972
14973   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14974                                 NULL_RTX, operands[1]));
14975
14976   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14977                          gen_rtx_REG (CCmode, FLAGS_REG),
14978                          const0_rtx);
14979   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14980
14981   if (TARGET_64BIT)
14982     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14983   else
14984     {
14985       rtx tmp = gen_reg_rtx (SImode);
14986
14987       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14988       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14989     }
14990   DONE;
14991 })
14992
14993 (define_insn_and_split "paritydi2_cmp"
14994   [(set (reg:CC FLAGS_REG)
14995         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14996    (clobber (match_scratch:DI 0 "=r"))
14997    (clobber (match_scratch:SI 1 "=&r"))
14998    (clobber (match_scratch:HI 2 "=Q"))]
14999   "! TARGET_POPCNT"
15000   "#"
15001   "&& reload_completed"
15002   [(parallel
15003      [(set (match_dup 1)
15004            (xor:SI (match_dup 1) (match_dup 4)))
15005       (clobber (reg:CC FLAGS_REG))])
15006    (parallel
15007      [(set (reg:CC FLAGS_REG)
15008            (parity:CC (match_dup 1)))
15009       (clobber (match_dup 1))
15010       (clobber (match_dup 2))])]
15011 {
15012   operands[4] = gen_lowpart (SImode, operands[3]);
15013
15014   if (TARGET_64BIT)
15015     {
15016       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15017       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15018     }
15019   else
15020     operands[1] = gen_highpart (SImode, operands[3]);
15021 })
15022
15023 (define_expand "paritysi2"
15024   [(set (match_operand:SI 0 "register_operand" "")
15025         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15026   "! TARGET_POPCNT"
15027 {
15028   rtx scratch = gen_reg_rtx (QImode);
15029   rtx cond;
15030
15031   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15032
15033   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15034                          gen_rtx_REG (CCmode, FLAGS_REG),
15035                          const0_rtx);
15036   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15037
15038   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15039   DONE;
15040 })
15041
15042 (define_insn_and_split "paritysi2_cmp"
15043   [(set (reg:CC FLAGS_REG)
15044         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15045    (clobber (match_scratch:SI 0 "=r"))
15046    (clobber (match_scratch:HI 1 "=&Q"))]
15047   "! TARGET_POPCNT"
15048   "#"
15049   "&& reload_completed"
15050   [(parallel
15051      [(set (match_dup 1)
15052            (xor:HI (match_dup 1) (match_dup 3)))
15053       (clobber (reg:CC FLAGS_REG))])
15054    (parallel
15055      [(set (reg:CC FLAGS_REG)
15056            (parity:CC (match_dup 1)))
15057       (clobber (match_dup 1))])]
15058 {
15059   operands[3] = gen_lowpart (HImode, operands[2]);
15060
15061   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15062   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15063 })
15064
15065 (define_insn "*parityhi2_cmp"
15066   [(set (reg:CC FLAGS_REG)
15067         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15068    (clobber (match_scratch:HI 0 "=Q"))]
15069   "! TARGET_POPCNT"
15070   "xor{b}\t{%h0, %b0|%b0, %h0}"
15071   [(set_attr "length" "2")
15072    (set_attr "mode" "HI")])
15073
15074 (define_insn "*parityqi2_cmp"
15075   [(set (reg:CC FLAGS_REG)
15076         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15077   "! TARGET_POPCNT"
15078   "test{b}\t%0, %0"
15079   [(set_attr "length" "2")
15080    (set_attr "mode" "QI")])
15081 \f
15082 ;; Thread-local storage patterns for ELF.
15083 ;;
15084 ;; Note that these code sequences must appear exactly as shown
15085 ;; in order to allow linker relaxation.
15086
15087 (define_insn "*tls_global_dynamic_32_gnu"
15088   [(set (match_operand:SI 0 "register_operand" "=a")
15089         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15090                     (match_operand:SI 2 "tls_symbolic_operand" "")
15091                     (match_operand:SI 3 "call_insn_operand" "")]
15092                     UNSPEC_TLS_GD))
15093    (clobber (match_scratch:SI 4 "=d"))
15094    (clobber (match_scratch:SI 5 "=c"))
15095    (clobber (reg:CC FLAGS_REG))]
15096   "!TARGET_64BIT && TARGET_GNU_TLS"
15097   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15098   [(set_attr "type" "multi")
15099    (set_attr "length" "12")])
15100
15101 (define_insn "*tls_global_dynamic_32_sun"
15102   [(set (match_operand:SI 0 "register_operand" "=a")
15103         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15104                     (match_operand:SI 2 "tls_symbolic_operand" "")
15105                     (match_operand:SI 3 "call_insn_operand" "")]
15106                     UNSPEC_TLS_GD))
15107    (clobber (match_scratch:SI 4 "=d"))
15108    (clobber (match_scratch:SI 5 "=c"))
15109    (clobber (reg:CC FLAGS_REG))]
15110   "!TARGET_64BIT && TARGET_SUN_TLS"
15111   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15112         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15113   [(set_attr "type" "multi")
15114    (set_attr "length" "14")])
15115
15116 (define_expand "tls_global_dynamic_32"
15117   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15118                    (unspec:SI
15119                     [(match_dup 2)
15120                      (match_operand:SI 1 "tls_symbolic_operand" "")
15121                      (match_dup 3)]
15122                     UNSPEC_TLS_GD))
15123               (clobber (match_scratch:SI 4 ""))
15124               (clobber (match_scratch:SI 5 ""))
15125               (clobber (reg:CC FLAGS_REG))])]
15126   ""
15127 {
15128   if (flag_pic)
15129     operands[2] = pic_offset_table_rtx;
15130   else
15131     {
15132       operands[2] = gen_reg_rtx (Pmode);
15133       emit_insn (gen_set_got (operands[2]));
15134     }
15135   if (TARGET_GNU2_TLS)
15136     {
15137        emit_insn (gen_tls_dynamic_gnu2_32
15138                   (operands[0], operands[1], operands[2]));
15139        DONE;
15140     }
15141   operands[3] = ix86_tls_get_addr ();
15142 })
15143
15144 (define_insn "*tls_global_dynamic_64"
15145   [(set (match_operand:DI 0 "register_operand" "=a")
15146         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15147                  (match_operand:DI 3 "" "")))
15148    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15149               UNSPEC_TLS_GD)]
15150   "TARGET_64BIT"
15151   { 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"; }
15152   [(set_attr "type" "multi")
15153    (set_attr "length" "16")])
15154
15155 (define_expand "tls_global_dynamic_64"
15156   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15157                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15158               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15159                          UNSPEC_TLS_GD)])]
15160   ""
15161 {
15162   if (TARGET_GNU2_TLS)
15163     {
15164        emit_insn (gen_tls_dynamic_gnu2_64
15165                   (operands[0], operands[1]));
15166        DONE;
15167     }
15168   operands[2] = ix86_tls_get_addr ();
15169 })
15170
15171 (define_insn "*tls_local_dynamic_base_32_gnu"
15172   [(set (match_operand:SI 0 "register_operand" "=a")
15173         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15174                     (match_operand:SI 2 "call_insn_operand" "")]
15175                    UNSPEC_TLS_LD_BASE))
15176    (clobber (match_scratch:SI 3 "=d"))
15177    (clobber (match_scratch:SI 4 "=c"))
15178    (clobber (reg:CC FLAGS_REG))]
15179   "!TARGET_64BIT && TARGET_GNU_TLS"
15180   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15181   [(set_attr "type" "multi")
15182    (set_attr "length" "11")])
15183
15184 (define_insn "*tls_local_dynamic_base_32_sun"
15185   [(set (match_operand:SI 0 "register_operand" "=a")
15186         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15187                     (match_operand:SI 2 "call_insn_operand" "")]
15188                    UNSPEC_TLS_LD_BASE))
15189    (clobber (match_scratch:SI 3 "=d"))
15190    (clobber (match_scratch:SI 4 "=c"))
15191    (clobber (reg:CC FLAGS_REG))]
15192   "!TARGET_64BIT && TARGET_SUN_TLS"
15193   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15194         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15195   [(set_attr "type" "multi")
15196    (set_attr "length" "13")])
15197
15198 (define_expand "tls_local_dynamic_base_32"
15199   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15200                    (unspec:SI [(match_dup 1) (match_dup 2)]
15201                               UNSPEC_TLS_LD_BASE))
15202               (clobber (match_scratch:SI 3 ""))
15203               (clobber (match_scratch:SI 4 ""))
15204               (clobber (reg:CC FLAGS_REG))])]
15205   ""
15206 {
15207   if (flag_pic)
15208     operands[1] = pic_offset_table_rtx;
15209   else
15210     {
15211       operands[1] = gen_reg_rtx (Pmode);
15212       emit_insn (gen_set_got (operands[1]));
15213     }
15214   if (TARGET_GNU2_TLS)
15215     {
15216        emit_insn (gen_tls_dynamic_gnu2_32
15217                   (operands[0], ix86_tls_module_base (), operands[1]));
15218        DONE;
15219     }
15220   operands[2] = ix86_tls_get_addr ();
15221 })
15222
15223 (define_insn "*tls_local_dynamic_base_64"
15224   [(set (match_operand:DI 0 "register_operand" "=a")
15225         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15226                  (match_operand:DI 2 "" "")))
15227    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15228   "TARGET_64BIT"
15229   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15230   [(set_attr "type" "multi")
15231    (set_attr "length" "12")])
15232
15233 (define_expand "tls_local_dynamic_base_64"
15234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15235                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15236               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15237   ""
15238 {
15239   if (TARGET_GNU2_TLS)
15240     {
15241        emit_insn (gen_tls_dynamic_gnu2_64
15242                   (operands[0], ix86_tls_module_base ()));
15243        DONE;
15244     }
15245   operands[1] = ix86_tls_get_addr ();
15246 })
15247
15248 ;; Local dynamic of a single variable is a lose.  Show combine how
15249 ;; to convert that back to global dynamic.
15250
15251 (define_insn_and_split "*tls_local_dynamic_32_once"
15252   [(set (match_operand:SI 0 "register_operand" "=a")
15253         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15254                              (match_operand:SI 2 "call_insn_operand" "")]
15255                             UNSPEC_TLS_LD_BASE)
15256                  (const:SI (unspec:SI
15257                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15258                             UNSPEC_DTPOFF))))
15259    (clobber (match_scratch:SI 4 "=d"))
15260    (clobber (match_scratch:SI 5 "=c"))
15261    (clobber (reg:CC FLAGS_REG))]
15262   ""
15263   "#"
15264   ""
15265   [(parallel [(set (match_dup 0)
15266                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15267                               UNSPEC_TLS_GD))
15268               (clobber (match_dup 4))
15269               (clobber (match_dup 5))
15270               (clobber (reg:CC FLAGS_REG))])]
15271   "")
15272
15273 ;; Load and add the thread base pointer from %gs:0.
15274
15275 (define_insn "*load_tp_si"
15276   [(set (match_operand:SI 0 "register_operand" "=r")
15277         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15278   "!TARGET_64BIT"
15279   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15280   [(set_attr "type" "imov")
15281    (set_attr "modrm" "0")
15282    (set_attr "length" "7")
15283    (set_attr "memory" "load")
15284    (set_attr "imm_disp" "false")])
15285
15286 (define_insn "*add_tp_si"
15287   [(set (match_operand:SI 0 "register_operand" "=r")
15288         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15289                  (match_operand:SI 1 "register_operand" "0")))
15290    (clobber (reg:CC FLAGS_REG))]
15291   "!TARGET_64BIT"
15292   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15293   [(set_attr "type" "alu")
15294    (set_attr "modrm" "0")
15295    (set_attr "length" "7")
15296    (set_attr "memory" "load")
15297    (set_attr "imm_disp" "false")])
15298
15299 (define_insn "*load_tp_di"
15300   [(set (match_operand:DI 0 "register_operand" "=r")
15301         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15302   "TARGET_64BIT"
15303   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15304   [(set_attr "type" "imov")
15305    (set_attr "modrm" "0")
15306    (set_attr "length" "7")
15307    (set_attr "memory" "load")
15308    (set_attr "imm_disp" "false")])
15309
15310 (define_insn "*add_tp_di"
15311   [(set (match_operand:DI 0 "register_operand" "=r")
15312         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15313                  (match_operand:DI 1 "register_operand" "0")))
15314    (clobber (reg:CC FLAGS_REG))]
15315   "TARGET_64BIT"
15316   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15317   [(set_attr "type" "alu")
15318    (set_attr "modrm" "0")
15319    (set_attr "length" "7")
15320    (set_attr "memory" "load")
15321    (set_attr "imm_disp" "false")])
15322
15323 ;; GNU2 TLS patterns can be split.
15324
15325 (define_expand "tls_dynamic_gnu2_32"
15326   [(set (match_dup 3)
15327         (plus:SI (match_operand:SI 2 "register_operand" "")
15328                  (const:SI
15329                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15330                              UNSPEC_TLSDESC))))
15331    (parallel
15332     [(set (match_operand:SI 0 "register_operand" "")
15333           (unspec:SI [(match_dup 1) (match_dup 3)
15334                       (match_dup 2) (reg:SI SP_REG)]
15335                       UNSPEC_TLSDESC))
15336      (clobber (reg:CC FLAGS_REG))])]
15337   "!TARGET_64BIT && TARGET_GNU2_TLS"
15338 {
15339   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15340   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15341 })
15342
15343 (define_insn "*tls_dynamic_lea_32"
15344   [(set (match_operand:SI 0 "register_operand" "=r")
15345         (plus:SI (match_operand:SI 1 "register_operand" "b")
15346                  (const:SI
15347                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15348                               UNSPEC_TLSDESC))))]
15349   "!TARGET_64BIT && TARGET_GNU2_TLS"
15350   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15351   [(set_attr "type" "lea")
15352    (set_attr "mode" "SI")
15353    (set_attr "length" "6")
15354    (set_attr "length_address" "4")])
15355
15356 (define_insn "*tls_dynamic_call_32"
15357   [(set (match_operand:SI 0 "register_operand" "=a")
15358         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15359                     (match_operand:SI 2 "register_operand" "0")
15360                     ;; we have to make sure %ebx still points to the GOT
15361                     (match_operand:SI 3 "register_operand" "b")
15362                     (reg:SI SP_REG)]
15363                    UNSPEC_TLSDESC))
15364    (clobber (reg:CC FLAGS_REG))]
15365   "!TARGET_64BIT && TARGET_GNU2_TLS"
15366   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15367   [(set_attr "type" "call")
15368    (set_attr "length" "2")
15369    (set_attr "length_address" "0")])
15370
15371 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15372   [(set (match_operand:SI 0 "register_operand" "=&a")
15373         (plus:SI
15374          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15375                      (match_operand:SI 4 "" "")
15376                      (match_operand:SI 2 "register_operand" "b")
15377                      (reg:SI SP_REG)]
15378                     UNSPEC_TLSDESC)
15379          (const:SI (unspec:SI
15380                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15381                     UNSPEC_DTPOFF))))
15382    (clobber (reg:CC FLAGS_REG))]
15383   "!TARGET_64BIT && TARGET_GNU2_TLS"
15384   "#"
15385   ""
15386   [(set (match_dup 0) (match_dup 5))]
15387 {
15388   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15389   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15390 })
15391
15392 (define_expand "tls_dynamic_gnu2_64"
15393   [(set (match_dup 2)
15394         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15395                    UNSPEC_TLSDESC))
15396    (parallel
15397     [(set (match_operand:DI 0 "register_operand" "")
15398           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15399                      UNSPEC_TLSDESC))
15400      (clobber (reg:CC FLAGS_REG))])]
15401   "TARGET_64BIT && TARGET_GNU2_TLS"
15402 {
15403   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15404   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15405 })
15406
15407 (define_insn "*tls_dynamic_lea_64"
15408   [(set (match_operand:DI 0 "register_operand" "=r")
15409         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15410                    UNSPEC_TLSDESC))]
15411   "TARGET_64BIT && TARGET_GNU2_TLS"
15412   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15413   [(set_attr "type" "lea")
15414    (set_attr "mode" "DI")
15415    (set_attr "length" "7")
15416    (set_attr "length_address" "4")])
15417
15418 (define_insn "*tls_dynamic_call_64"
15419   [(set (match_operand:DI 0 "register_operand" "=a")
15420         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15421                     (match_operand:DI 2 "register_operand" "0")
15422                     (reg:DI SP_REG)]
15423                    UNSPEC_TLSDESC))
15424    (clobber (reg:CC FLAGS_REG))]
15425   "TARGET_64BIT && TARGET_GNU2_TLS"
15426   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15427   [(set_attr "type" "call")
15428    (set_attr "length" "2")
15429    (set_attr "length_address" "0")])
15430
15431 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15432   [(set (match_operand:DI 0 "register_operand" "=&a")
15433         (plus:DI
15434          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15435                      (match_operand:DI 3 "" "")
15436                      (reg:DI SP_REG)]
15437                     UNSPEC_TLSDESC)
15438          (const:DI (unspec:DI
15439                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15440                     UNSPEC_DTPOFF))))
15441    (clobber (reg:CC FLAGS_REG))]
15442   "TARGET_64BIT && TARGET_GNU2_TLS"
15443   "#"
15444   ""
15445   [(set (match_dup 0) (match_dup 4))]
15446 {
15447   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15448   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15449 })
15450
15451 ;;
15452 \f
15453 ;; These patterns match the binary 387 instructions for addM3, subM3,
15454 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15455 ;; SFmode.  The first is the normal insn, the second the same insn but
15456 ;; with one operand a conversion, and the third the same insn but with
15457 ;; the other operand a conversion.  The conversion may be SFmode or
15458 ;; SImode if the target mode DFmode, but only SImode if the target mode
15459 ;; is SFmode.
15460
15461 ;; Gcc is slightly more smart about handling normal two address instructions
15462 ;; so use special patterns for add and mull.
15463
15464 (define_insn "*fop_<mode>_comm_mixed_avx"
15465   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15466         (match_operator:MODEF 3 "binary_fp_operator"
15467           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15468            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15469   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15470    && COMMUTATIVE_ARITH_P (operands[3])
15471    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15472   "* return output_387_binary_op (insn, operands);"
15473   [(set (attr "type")
15474         (if_then_else (eq_attr "alternative" "1")
15475            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15476               (const_string "ssemul")
15477               (const_string "sseadd"))
15478            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15479               (const_string "fmul")
15480               (const_string "fop"))))
15481    (set_attr "prefix" "orig,maybe_vex")
15482    (set_attr "mode" "<MODE>")])
15483
15484 (define_insn "*fop_<mode>_comm_mixed"
15485   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15486         (match_operator:MODEF 3 "binary_fp_operator"
15487           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15488            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15489   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15490    && COMMUTATIVE_ARITH_P (operands[3])
15491    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15492   "* return output_387_binary_op (insn, operands);"
15493   [(set (attr "type")
15494         (if_then_else (eq_attr "alternative" "1")
15495            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15496               (const_string "ssemul")
15497               (const_string "sseadd"))
15498            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15499               (const_string "fmul")
15500               (const_string "fop"))))
15501    (set_attr "mode" "<MODE>")])
15502
15503 (define_insn "*fop_<mode>_comm_avx"
15504   [(set (match_operand:MODEF 0 "register_operand" "=x")
15505         (match_operator:MODEF 3 "binary_fp_operator"
15506           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15507            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15508   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15509    && COMMUTATIVE_ARITH_P (operands[3])
15510    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15511   "* return output_387_binary_op (insn, operands);"
15512   [(set (attr "type")
15513         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15514            (const_string "ssemul")
15515            (const_string "sseadd")))
15516    (set_attr "prefix" "vex")
15517    (set_attr "mode" "<MODE>")])
15518
15519 (define_insn "*fop_<mode>_comm_sse"
15520   [(set (match_operand:MODEF 0 "register_operand" "=x")
15521         (match_operator:MODEF 3 "binary_fp_operator"
15522           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15523            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15524   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15525    && COMMUTATIVE_ARITH_P (operands[3])
15526    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15527   "* return output_387_binary_op (insn, operands);"
15528   [(set (attr "type")
15529         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15530            (const_string "ssemul")
15531            (const_string "sseadd")))
15532    (set_attr "mode" "<MODE>")])
15533
15534 (define_insn "*fop_<mode>_comm_i387"
15535   [(set (match_operand:MODEF 0 "register_operand" "=f")
15536         (match_operator:MODEF 3 "binary_fp_operator"
15537           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15538            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15539   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15540    && COMMUTATIVE_ARITH_P (operands[3])
15541    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15542   "* return output_387_binary_op (insn, operands);"
15543   [(set (attr "type")
15544         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15545            (const_string "fmul")
15546            (const_string "fop")))
15547    (set_attr "mode" "<MODE>")])
15548
15549 (define_insn "*fop_<mode>_1_mixed_avx"
15550   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15551         (match_operator:MODEF 3 "binary_fp_operator"
15552           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15553            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15554   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15555    && !COMMUTATIVE_ARITH_P (operands[3])
15556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15557   "* return output_387_binary_op (insn, operands);"
15558   [(set (attr "type")
15559         (cond [(and (eq_attr "alternative" "2")
15560                     (match_operand:MODEF 3 "mult_operator" ""))
15561                  (const_string "ssemul")
15562                (and (eq_attr "alternative" "2")
15563                     (match_operand:MODEF 3 "div_operator" ""))
15564                  (const_string "ssediv")
15565                (eq_attr "alternative" "2")
15566                  (const_string "sseadd")
15567                (match_operand:MODEF 3 "mult_operator" "")
15568                  (const_string "fmul")
15569                (match_operand:MODEF 3 "div_operator" "")
15570                  (const_string "fdiv")
15571               ]
15572               (const_string "fop")))
15573    (set_attr "prefix" "orig,orig,maybe_vex")
15574    (set_attr "mode" "<MODE>")])
15575
15576 (define_insn "*fop_<mode>_1_mixed"
15577   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15578         (match_operator:MODEF 3 "binary_fp_operator"
15579           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15580            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15581   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15582    && !COMMUTATIVE_ARITH_P (operands[3])
15583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15584   "* return output_387_binary_op (insn, operands);"
15585   [(set (attr "type")
15586         (cond [(and (eq_attr "alternative" "2")
15587                     (match_operand:MODEF 3 "mult_operator" ""))
15588                  (const_string "ssemul")
15589                (and (eq_attr "alternative" "2")
15590                     (match_operand:MODEF 3 "div_operator" ""))
15591                  (const_string "ssediv")
15592                (eq_attr "alternative" "2")
15593                  (const_string "sseadd")
15594                (match_operand:MODEF 3 "mult_operator" "")
15595                  (const_string "fmul")
15596                (match_operand:MODEF 3 "div_operator" "")
15597                  (const_string "fdiv")
15598               ]
15599               (const_string "fop")))
15600    (set_attr "mode" "<MODE>")])
15601
15602 (define_insn "*rcpsf2_sse"
15603   [(set (match_operand:SF 0 "register_operand" "=x")
15604         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15605                    UNSPEC_RCP))]
15606   "TARGET_SSE_MATH"
15607   "%vrcpss\t{%1, %d0|%d0, %1}"
15608   [(set_attr "type" "sse")
15609    (set_attr "atom_sse_attr" "rcp")
15610    (set_attr "prefix" "maybe_vex")
15611    (set_attr "mode" "SF")])
15612
15613 (define_insn "*fop_<mode>_1_avx"
15614   [(set (match_operand:MODEF 0 "register_operand" "=x")
15615         (match_operator:MODEF 3 "binary_fp_operator"
15616           [(match_operand:MODEF 1 "register_operand" "x")
15617            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15618   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15619    && !COMMUTATIVE_ARITH_P (operands[3])"
15620   "* return output_387_binary_op (insn, operands);"
15621   [(set (attr "type")
15622         (cond [(match_operand:MODEF 3 "mult_operator" "")
15623                  (const_string "ssemul")
15624                (match_operand:MODEF 3 "div_operator" "")
15625                  (const_string "ssediv")
15626               ]
15627               (const_string "sseadd")))
15628    (set_attr "prefix" "vex")
15629    (set_attr "mode" "<MODE>")])
15630
15631 (define_insn "*fop_<mode>_1_sse"
15632   [(set (match_operand:MODEF 0 "register_operand" "=x")
15633         (match_operator:MODEF 3 "binary_fp_operator"
15634           [(match_operand:MODEF 1 "register_operand" "0")
15635            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15636   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15637    && !COMMUTATIVE_ARITH_P (operands[3])"
15638   "* return output_387_binary_op (insn, operands);"
15639   [(set (attr "type")
15640         (cond [(match_operand:MODEF 3 "mult_operator" "")
15641                  (const_string "ssemul")
15642                (match_operand:MODEF 3 "div_operator" "")
15643                  (const_string "ssediv")
15644               ]
15645               (const_string "sseadd")))
15646    (set_attr "mode" "<MODE>")])
15647
15648 ;; This pattern is not fully shadowed by the pattern above.
15649 (define_insn "*fop_<mode>_1_i387"
15650   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15651         (match_operator:MODEF 3 "binary_fp_operator"
15652           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15653            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15654   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15655    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15656    && !COMMUTATIVE_ARITH_P (operands[3])
15657    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15658   "* return output_387_binary_op (insn, operands);"
15659   [(set (attr "type")
15660         (cond [(match_operand:MODEF 3 "mult_operator" "")
15661                  (const_string "fmul")
15662                (match_operand:MODEF 3 "div_operator" "")
15663                  (const_string "fdiv")
15664               ]
15665               (const_string "fop")))
15666    (set_attr "mode" "<MODE>")])
15667
15668 ;; ??? Add SSE splitters for these!
15669 (define_insn "*fop_<MODEF:mode>_2_i387"
15670   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15671         (match_operator:MODEF 3 "binary_fp_operator"
15672           [(float:MODEF
15673              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15674            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15675   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15676    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15677    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15678   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15679   [(set (attr "type")
15680         (cond [(match_operand:MODEF 3 "mult_operator" "")
15681                  (const_string "fmul")
15682                (match_operand:MODEF 3 "div_operator" "")
15683                  (const_string "fdiv")
15684               ]
15685               (const_string "fop")))
15686    (set_attr "fp_int_src" "true")
15687    (set_attr "mode" "<X87MODEI12:MODE>")])
15688
15689 (define_insn "*fop_<MODEF:mode>_3_i387"
15690   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15691         (match_operator:MODEF 3 "binary_fp_operator"
15692           [(match_operand:MODEF 1 "register_operand" "0,0")
15693            (float:MODEF
15694              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15695   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15696    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15697    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15698   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15699   [(set (attr "type")
15700         (cond [(match_operand:MODEF 3 "mult_operator" "")
15701                  (const_string "fmul")
15702                (match_operand:MODEF 3 "div_operator" "")
15703                  (const_string "fdiv")
15704               ]
15705               (const_string "fop")))
15706    (set_attr "fp_int_src" "true")
15707    (set_attr "mode" "<MODE>")])
15708
15709 (define_insn "*fop_df_4_i387"
15710   [(set (match_operand:DF 0 "register_operand" "=f,f")
15711         (match_operator:DF 3 "binary_fp_operator"
15712            [(float_extend:DF
15713              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15714             (match_operand:DF 2 "register_operand" "0,f")]))]
15715   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15716    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15717    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15718   "* return output_387_binary_op (insn, operands);"
15719   [(set (attr "type")
15720         (cond [(match_operand:DF 3 "mult_operator" "")
15721                  (const_string "fmul")
15722                (match_operand:DF 3 "div_operator" "")
15723                  (const_string "fdiv")
15724               ]
15725               (const_string "fop")))
15726    (set_attr "mode" "SF")])
15727
15728 (define_insn "*fop_df_5_i387"
15729   [(set (match_operand:DF 0 "register_operand" "=f,f")
15730         (match_operator:DF 3 "binary_fp_operator"
15731           [(match_operand:DF 1 "register_operand" "0,f")
15732            (float_extend:DF
15733             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15734   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15735    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15736   "* return output_387_binary_op (insn, operands);"
15737   [(set (attr "type")
15738         (cond [(match_operand:DF 3 "mult_operator" "")
15739                  (const_string "fmul")
15740                (match_operand:DF 3 "div_operator" "")
15741                  (const_string "fdiv")
15742               ]
15743               (const_string "fop")))
15744    (set_attr "mode" "SF")])
15745
15746 (define_insn "*fop_df_6_i387"
15747   [(set (match_operand:DF 0 "register_operand" "=f,f")
15748         (match_operator:DF 3 "binary_fp_operator"
15749           [(float_extend:DF
15750             (match_operand:SF 1 "register_operand" "0,f"))
15751            (float_extend:DF
15752             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15753   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15754    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15755   "* return output_387_binary_op (insn, operands);"
15756   [(set (attr "type")
15757         (cond [(match_operand:DF 3 "mult_operator" "")
15758                  (const_string "fmul")
15759                (match_operand:DF 3 "div_operator" "")
15760                  (const_string "fdiv")
15761               ]
15762               (const_string "fop")))
15763    (set_attr "mode" "SF")])
15764
15765 (define_insn "*fop_xf_comm_i387"
15766   [(set (match_operand:XF 0 "register_operand" "=f")
15767         (match_operator:XF 3 "binary_fp_operator"
15768                         [(match_operand:XF 1 "register_operand" "%0")
15769                          (match_operand:XF 2 "register_operand" "f")]))]
15770   "TARGET_80387
15771    && COMMUTATIVE_ARITH_P (operands[3])"
15772   "* return output_387_binary_op (insn, operands);"
15773   [(set (attr "type")
15774         (if_then_else (match_operand:XF 3 "mult_operator" "")
15775            (const_string "fmul")
15776            (const_string "fop")))
15777    (set_attr "mode" "XF")])
15778
15779 (define_insn "*fop_xf_1_i387"
15780   [(set (match_operand:XF 0 "register_operand" "=f,f")
15781         (match_operator:XF 3 "binary_fp_operator"
15782                         [(match_operand:XF 1 "register_operand" "0,f")
15783                          (match_operand:XF 2 "register_operand" "f,0")]))]
15784   "TARGET_80387
15785    && !COMMUTATIVE_ARITH_P (operands[3])"
15786   "* return output_387_binary_op (insn, operands);"
15787   [(set (attr "type")
15788         (cond [(match_operand:XF 3 "mult_operator" "")
15789                  (const_string "fmul")
15790                (match_operand:XF 3 "div_operator" "")
15791                  (const_string "fdiv")
15792               ]
15793               (const_string "fop")))
15794    (set_attr "mode" "XF")])
15795
15796 (define_insn "*fop_xf_2_i387"
15797   [(set (match_operand:XF 0 "register_operand" "=f,f")
15798         (match_operator:XF 3 "binary_fp_operator"
15799           [(float:XF
15800              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15801            (match_operand:XF 2 "register_operand" "0,0")]))]
15802   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15803   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15804   [(set (attr "type")
15805         (cond [(match_operand:XF 3 "mult_operator" "")
15806                  (const_string "fmul")
15807                (match_operand:XF 3 "div_operator" "")
15808                  (const_string "fdiv")
15809               ]
15810               (const_string "fop")))
15811    (set_attr "fp_int_src" "true")
15812    (set_attr "mode" "<MODE>")])
15813
15814 (define_insn "*fop_xf_3_i387"
15815   [(set (match_operand:XF 0 "register_operand" "=f,f")
15816         (match_operator:XF 3 "binary_fp_operator"
15817           [(match_operand:XF 1 "register_operand" "0,0")
15818            (float:XF
15819              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15820   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15821   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15822   [(set (attr "type")
15823         (cond [(match_operand:XF 3 "mult_operator" "")
15824                  (const_string "fmul")
15825                (match_operand:XF 3 "div_operator" "")
15826                  (const_string "fdiv")
15827               ]
15828               (const_string "fop")))
15829    (set_attr "fp_int_src" "true")
15830    (set_attr "mode" "<MODE>")])
15831
15832 (define_insn "*fop_xf_4_i387"
15833   [(set (match_operand:XF 0 "register_operand" "=f,f")
15834         (match_operator:XF 3 "binary_fp_operator"
15835            [(float_extend:XF
15836               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15837             (match_operand:XF 2 "register_operand" "0,f")]))]
15838   "TARGET_80387"
15839   "* return output_387_binary_op (insn, operands);"
15840   [(set (attr "type")
15841         (cond [(match_operand:XF 3 "mult_operator" "")
15842                  (const_string "fmul")
15843                (match_operand:XF 3 "div_operator" "")
15844                  (const_string "fdiv")
15845               ]
15846               (const_string "fop")))
15847    (set_attr "mode" "<MODE>")])
15848
15849 (define_insn "*fop_xf_5_i387"
15850   [(set (match_operand:XF 0 "register_operand" "=f,f")
15851         (match_operator:XF 3 "binary_fp_operator"
15852           [(match_operand:XF 1 "register_operand" "0,f")
15853            (float_extend:XF
15854              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15855   "TARGET_80387"
15856   "* return output_387_binary_op (insn, operands);"
15857   [(set (attr "type")
15858         (cond [(match_operand:XF 3 "mult_operator" "")
15859                  (const_string "fmul")
15860                (match_operand:XF 3 "div_operator" "")
15861                  (const_string "fdiv")
15862               ]
15863               (const_string "fop")))
15864    (set_attr "mode" "<MODE>")])
15865
15866 (define_insn "*fop_xf_6_i387"
15867   [(set (match_operand:XF 0 "register_operand" "=f,f")
15868         (match_operator:XF 3 "binary_fp_operator"
15869           [(float_extend:XF
15870              (match_operand:MODEF 1 "register_operand" "0,f"))
15871            (float_extend:XF
15872              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15873   "TARGET_80387"
15874   "* return output_387_binary_op (insn, operands);"
15875   [(set (attr "type")
15876         (cond [(match_operand:XF 3 "mult_operator" "")
15877                  (const_string "fmul")
15878                (match_operand:XF 3 "div_operator" "")
15879                  (const_string "fdiv")
15880               ]
15881               (const_string "fop")))
15882    (set_attr "mode" "<MODE>")])
15883
15884 (define_split
15885   [(set (match_operand 0 "register_operand" "")
15886         (match_operator 3 "binary_fp_operator"
15887            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15888             (match_operand 2 "register_operand" "")]))]
15889   "reload_completed
15890    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15891    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15892   [(const_int 0)]
15893 {
15894   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15895   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15896   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15897                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15898                                           GET_MODE (operands[3]),
15899                                           operands[4],
15900                                           operands[2])));
15901   ix86_free_from_memory (GET_MODE (operands[1]));
15902   DONE;
15903 })
15904
15905 (define_split
15906   [(set (match_operand 0 "register_operand" "")
15907         (match_operator 3 "binary_fp_operator"
15908            [(match_operand 1 "register_operand" "")
15909             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15910   "reload_completed
15911    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15912    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15913   [(const_int 0)]
15914 {
15915   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15916   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15917   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15918                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15919                                           GET_MODE (operands[3]),
15920                                           operands[1],
15921                                           operands[4])));
15922   ix86_free_from_memory (GET_MODE (operands[2]));
15923   DONE;
15924 })
15925 \f
15926 ;; FPU special functions.
15927
15928 ;; This pattern implements a no-op XFmode truncation for
15929 ;; all fancy i386 XFmode math functions.
15930
15931 (define_insn "truncxf<mode>2_i387_noop_unspec"
15932   [(set (match_operand:MODEF 0 "register_operand" "=f")
15933         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15934         UNSPEC_TRUNC_NOOP))]
15935   "TARGET_USE_FANCY_MATH_387"
15936   "* return output_387_reg_move (insn, operands);"
15937   [(set_attr "type" "fmov")
15938    (set_attr "mode" "<MODE>")])
15939
15940 (define_insn "sqrtxf2"
15941   [(set (match_operand:XF 0 "register_operand" "=f")
15942         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15943   "TARGET_USE_FANCY_MATH_387"
15944   "fsqrt"
15945   [(set_attr "type" "fpspc")
15946    (set_attr "mode" "XF")
15947    (set_attr "athlon_decode" "direct")
15948    (set_attr "amdfam10_decode" "direct")])
15949
15950 (define_insn "sqrt_extend<mode>xf2_i387"
15951   [(set (match_operand:XF 0 "register_operand" "=f")
15952         (sqrt:XF
15953           (float_extend:XF
15954             (match_operand:MODEF 1 "register_operand" "0"))))]
15955   "TARGET_USE_FANCY_MATH_387"
15956   "fsqrt"
15957   [(set_attr "type" "fpspc")
15958    (set_attr "mode" "XF")
15959    (set_attr "athlon_decode" "direct")
15960    (set_attr "amdfam10_decode" "direct")])
15961
15962 (define_insn "*rsqrtsf2_sse"
15963   [(set (match_operand:SF 0 "register_operand" "=x")
15964         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15965                    UNSPEC_RSQRT))]
15966   "TARGET_SSE_MATH"
15967   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15968   [(set_attr "type" "sse")
15969    (set_attr "atom_sse_attr" "rcp")
15970    (set_attr "prefix" "maybe_vex")
15971    (set_attr "mode" "SF")])
15972
15973 (define_expand "rsqrtsf2"
15974   [(set (match_operand:SF 0 "register_operand" "")
15975         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15976                    UNSPEC_RSQRT))]
15977   "TARGET_SSE_MATH"
15978 {
15979   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15980   DONE;
15981 })
15982
15983 (define_insn "*sqrt<mode>2_sse"
15984   [(set (match_operand:MODEF 0 "register_operand" "=x")
15985         (sqrt:MODEF
15986           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15987   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15988   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15989   [(set_attr "type" "sse")
15990    (set_attr "atom_sse_attr" "sqrt")
15991    (set_attr "prefix" "maybe_vex")
15992    (set_attr "mode" "<MODE>")
15993    (set_attr "athlon_decode" "*")
15994    (set_attr "amdfam10_decode" "*")])
15995
15996 (define_expand "sqrt<mode>2"
15997   [(set (match_operand:MODEF 0 "register_operand" "")
15998         (sqrt:MODEF
15999           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16000   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16001    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16002 {
16003   if (<MODE>mode == SFmode
16004       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16005       && flag_finite_math_only && !flag_trapping_math
16006       && flag_unsafe_math_optimizations)
16007     {
16008       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16009       DONE;
16010     }
16011
16012   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16013     {
16014       rtx op0 = gen_reg_rtx (XFmode);
16015       rtx op1 = force_reg (<MODE>mode, operands[1]);
16016
16017       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16018       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16019       DONE;
16020    }
16021 })
16022
16023 (define_insn "fpremxf4_i387"
16024   [(set (match_operand:XF 0 "register_operand" "=f")
16025         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16026                     (match_operand:XF 3 "register_operand" "1")]
16027                    UNSPEC_FPREM_F))
16028    (set (match_operand:XF 1 "register_operand" "=u")
16029         (unspec:XF [(match_dup 2) (match_dup 3)]
16030                    UNSPEC_FPREM_U))
16031    (set (reg:CCFP FPSR_REG)
16032         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16033                      UNSPEC_C2_FLAG))]
16034   "TARGET_USE_FANCY_MATH_387"
16035   "fprem"
16036   [(set_attr "type" "fpspc")
16037    (set_attr "mode" "XF")])
16038
16039 (define_expand "fmodxf3"
16040   [(use (match_operand:XF 0 "register_operand" ""))
16041    (use (match_operand:XF 1 "general_operand" ""))
16042    (use (match_operand:XF 2 "general_operand" ""))]
16043   "TARGET_USE_FANCY_MATH_387"
16044 {
16045   rtx label = gen_label_rtx ();
16046
16047   rtx op1 = gen_reg_rtx (XFmode);
16048   rtx op2 = gen_reg_rtx (XFmode);
16049
16050   emit_move_insn (op2, operands[2]);
16051   emit_move_insn (op1, operands[1]);
16052
16053   emit_label (label);
16054   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16055   ix86_emit_fp_unordered_jump (label);
16056   LABEL_NUSES (label) = 1;
16057
16058   emit_move_insn (operands[0], op1);
16059   DONE;
16060 })
16061
16062 (define_expand "fmod<mode>3"
16063   [(use (match_operand:MODEF 0 "register_operand" ""))
16064    (use (match_operand:MODEF 1 "general_operand" ""))
16065    (use (match_operand:MODEF 2 "general_operand" ""))]
16066   "TARGET_USE_FANCY_MATH_387"
16067 {
16068   rtx label = gen_label_rtx ();
16069
16070   rtx op1 = gen_reg_rtx (XFmode);
16071   rtx op2 = gen_reg_rtx (XFmode);
16072
16073   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16074   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16075
16076   emit_label (label);
16077   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16078   ix86_emit_fp_unordered_jump (label);
16079   LABEL_NUSES (label) = 1;
16080
16081   /* Truncate the result properly for strict SSE math.  */
16082   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16083       && !TARGET_MIX_SSE_I387)
16084     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16085   else
16086     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16087
16088   DONE;
16089 })
16090
16091 (define_insn "fprem1xf4_i387"
16092   [(set (match_operand:XF 0 "register_operand" "=f")
16093         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16094                     (match_operand:XF 3 "register_operand" "1")]
16095                    UNSPEC_FPREM1_F))
16096    (set (match_operand:XF 1 "register_operand" "=u")
16097         (unspec:XF [(match_dup 2) (match_dup 3)]
16098                    UNSPEC_FPREM1_U))
16099    (set (reg:CCFP FPSR_REG)
16100         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16101                      UNSPEC_C2_FLAG))]
16102   "TARGET_USE_FANCY_MATH_387"
16103   "fprem1"
16104   [(set_attr "type" "fpspc")
16105    (set_attr "mode" "XF")])
16106
16107 (define_expand "remainderxf3"
16108   [(use (match_operand:XF 0 "register_operand" ""))
16109    (use (match_operand:XF 1 "general_operand" ""))
16110    (use (match_operand:XF 2 "general_operand" ""))]
16111   "TARGET_USE_FANCY_MATH_387"
16112 {
16113   rtx label = gen_label_rtx ();
16114
16115   rtx op1 = gen_reg_rtx (XFmode);
16116   rtx op2 = gen_reg_rtx (XFmode);
16117
16118   emit_move_insn (op2, operands[2]);
16119   emit_move_insn (op1, operands[1]);
16120
16121   emit_label (label);
16122   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16123   ix86_emit_fp_unordered_jump (label);
16124   LABEL_NUSES (label) = 1;
16125
16126   emit_move_insn (operands[0], op1);
16127   DONE;
16128 })
16129
16130 (define_expand "remainder<mode>3"
16131   [(use (match_operand:MODEF 0 "register_operand" ""))
16132    (use (match_operand:MODEF 1 "general_operand" ""))
16133    (use (match_operand:MODEF 2 "general_operand" ""))]
16134   "TARGET_USE_FANCY_MATH_387"
16135 {
16136   rtx label = gen_label_rtx ();
16137
16138   rtx op1 = gen_reg_rtx (XFmode);
16139   rtx op2 = gen_reg_rtx (XFmode);
16140
16141   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16142   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16143
16144   emit_label (label);
16145
16146   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16147   ix86_emit_fp_unordered_jump (label);
16148   LABEL_NUSES (label) = 1;
16149
16150   /* Truncate the result properly for strict SSE math.  */
16151   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16152       && !TARGET_MIX_SSE_I387)
16153     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16154   else
16155     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16156
16157   DONE;
16158 })
16159
16160 (define_insn "*sinxf2_i387"
16161   [(set (match_operand:XF 0 "register_operand" "=f")
16162         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16163   "TARGET_USE_FANCY_MATH_387
16164    && flag_unsafe_math_optimizations"
16165   "fsin"
16166   [(set_attr "type" "fpspc")
16167    (set_attr "mode" "XF")])
16168
16169 (define_insn "*sin_extend<mode>xf2_i387"
16170   [(set (match_operand:XF 0 "register_operand" "=f")
16171         (unspec:XF [(float_extend:XF
16172                       (match_operand:MODEF 1 "register_operand" "0"))]
16173                    UNSPEC_SIN))]
16174   "TARGET_USE_FANCY_MATH_387
16175    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16176        || TARGET_MIX_SSE_I387)
16177    && flag_unsafe_math_optimizations"
16178   "fsin"
16179   [(set_attr "type" "fpspc")
16180    (set_attr "mode" "XF")])
16181
16182 (define_insn "*cosxf2_i387"
16183   [(set (match_operand:XF 0 "register_operand" "=f")
16184         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16185   "TARGET_USE_FANCY_MATH_387
16186    && flag_unsafe_math_optimizations"
16187   "fcos"
16188   [(set_attr "type" "fpspc")
16189    (set_attr "mode" "XF")])
16190
16191 (define_insn "*cos_extend<mode>xf2_i387"
16192   [(set (match_operand:XF 0 "register_operand" "=f")
16193         (unspec:XF [(float_extend:XF
16194                       (match_operand:MODEF 1 "register_operand" "0"))]
16195                    UNSPEC_COS))]
16196   "TARGET_USE_FANCY_MATH_387
16197    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16198        || TARGET_MIX_SSE_I387)
16199    && flag_unsafe_math_optimizations"
16200   "fcos"
16201   [(set_attr "type" "fpspc")
16202    (set_attr "mode" "XF")])
16203
16204 ;; When sincos pattern is defined, sin and cos builtin functions will be
16205 ;; expanded to sincos pattern with one of its outputs left unused.
16206 ;; CSE pass will figure out if two sincos patterns can be combined,
16207 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16208 ;; depending on the unused output.
16209
16210 (define_insn "sincosxf3"
16211   [(set (match_operand:XF 0 "register_operand" "=f")
16212         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16213                    UNSPEC_SINCOS_COS))
16214    (set (match_operand:XF 1 "register_operand" "=u")
16215         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16216   "TARGET_USE_FANCY_MATH_387
16217    && flag_unsafe_math_optimizations"
16218   "fsincos"
16219   [(set_attr "type" "fpspc")
16220    (set_attr "mode" "XF")])
16221
16222 (define_split
16223   [(set (match_operand:XF 0 "register_operand" "")
16224         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16225                    UNSPEC_SINCOS_COS))
16226    (set (match_operand:XF 1 "register_operand" "")
16227         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16228   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16229    && !(reload_completed || reload_in_progress)"
16230   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16231   "")
16232
16233 (define_split
16234   [(set (match_operand:XF 0 "register_operand" "")
16235         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16236                    UNSPEC_SINCOS_COS))
16237    (set (match_operand:XF 1 "register_operand" "")
16238         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16239   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16240    && !(reload_completed || reload_in_progress)"
16241   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16242   "")
16243
16244 (define_insn "sincos_extend<mode>xf3_i387"
16245   [(set (match_operand:XF 0 "register_operand" "=f")
16246         (unspec:XF [(float_extend:XF
16247                       (match_operand:MODEF 2 "register_operand" "0"))]
16248                    UNSPEC_SINCOS_COS))
16249    (set (match_operand:XF 1 "register_operand" "=u")
16250         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16251   "TARGET_USE_FANCY_MATH_387
16252    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16253        || TARGET_MIX_SSE_I387)
16254    && flag_unsafe_math_optimizations"
16255   "fsincos"
16256   [(set_attr "type" "fpspc")
16257    (set_attr "mode" "XF")])
16258
16259 (define_split
16260   [(set (match_operand:XF 0 "register_operand" "")
16261         (unspec:XF [(float_extend:XF
16262                       (match_operand:MODEF 2 "register_operand" ""))]
16263                    UNSPEC_SINCOS_COS))
16264    (set (match_operand:XF 1 "register_operand" "")
16265         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16266   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16267    && !(reload_completed || reload_in_progress)"
16268   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16269   "")
16270
16271 (define_split
16272   [(set (match_operand:XF 0 "register_operand" "")
16273         (unspec:XF [(float_extend:XF
16274                       (match_operand:MODEF 2 "register_operand" ""))]
16275                    UNSPEC_SINCOS_COS))
16276    (set (match_operand:XF 1 "register_operand" "")
16277         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16278   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16279    && !(reload_completed || reload_in_progress)"
16280   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16281   "")
16282
16283 (define_expand "sincos<mode>3"
16284   [(use (match_operand:MODEF 0 "register_operand" ""))
16285    (use (match_operand:MODEF 1 "register_operand" ""))
16286    (use (match_operand:MODEF 2 "register_operand" ""))]
16287   "TARGET_USE_FANCY_MATH_387
16288    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16289        || TARGET_MIX_SSE_I387)
16290    && flag_unsafe_math_optimizations"
16291 {
16292   rtx op0 = gen_reg_rtx (XFmode);
16293   rtx op1 = gen_reg_rtx (XFmode);
16294
16295   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16296   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16297   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16298   DONE;
16299 })
16300
16301 (define_insn "fptanxf4_i387"
16302   [(set (match_operand:XF 0 "register_operand" "=f")
16303         (match_operand:XF 3 "const_double_operand" "F"))
16304    (set (match_operand:XF 1 "register_operand" "=u")
16305         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16306                    UNSPEC_TAN))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && flag_unsafe_math_optimizations
16309    && standard_80387_constant_p (operands[3]) == 2"
16310   "fptan"
16311   [(set_attr "type" "fpspc")
16312    (set_attr "mode" "XF")])
16313
16314 (define_insn "fptan_extend<mode>xf4_i387"
16315   [(set (match_operand:MODEF 0 "register_operand" "=f")
16316         (match_operand:MODEF 3 "const_double_operand" "F"))
16317    (set (match_operand:XF 1 "register_operand" "=u")
16318         (unspec:XF [(float_extend:XF
16319                       (match_operand:MODEF 2 "register_operand" "0"))]
16320                    UNSPEC_TAN))]
16321   "TARGET_USE_FANCY_MATH_387
16322    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16323        || TARGET_MIX_SSE_I387)
16324    && flag_unsafe_math_optimizations
16325    && standard_80387_constant_p (operands[3]) == 2"
16326   "fptan"
16327   [(set_attr "type" "fpspc")
16328    (set_attr "mode" "XF")])
16329
16330 (define_expand "tanxf2"
16331   [(use (match_operand:XF 0 "register_operand" ""))
16332    (use (match_operand:XF 1 "register_operand" ""))]
16333   "TARGET_USE_FANCY_MATH_387
16334    && flag_unsafe_math_optimizations"
16335 {
16336   rtx one = gen_reg_rtx (XFmode);
16337   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16338
16339   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16340   DONE;
16341 })
16342
16343 (define_expand "tan<mode>2"
16344   [(use (match_operand:MODEF 0 "register_operand" ""))
16345    (use (match_operand:MODEF 1 "register_operand" ""))]
16346   "TARGET_USE_FANCY_MATH_387
16347    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16348        || TARGET_MIX_SSE_I387)
16349    && flag_unsafe_math_optimizations"
16350 {
16351   rtx op0 = gen_reg_rtx (XFmode);
16352
16353   rtx one = gen_reg_rtx (<MODE>mode);
16354   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16355
16356   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16357                                              operands[1], op2));
16358   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16359   DONE;
16360 })
16361
16362 (define_insn "*fpatanxf3_i387"
16363   [(set (match_operand:XF 0 "register_operand" "=f")
16364         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16365                     (match_operand:XF 2 "register_operand" "u")]
16366                    UNSPEC_FPATAN))
16367    (clobber (match_scratch:XF 3 "=2"))]
16368   "TARGET_USE_FANCY_MATH_387
16369    && flag_unsafe_math_optimizations"
16370   "fpatan"
16371   [(set_attr "type" "fpspc")
16372    (set_attr "mode" "XF")])
16373
16374 (define_insn "fpatan_extend<mode>xf3_i387"
16375   [(set (match_operand:XF 0 "register_operand" "=f")
16376         (unspec:XF [(float_extend:XF
16377                       (match_operand:MODEF 1 "register_operand" "0"))
16378                     (float_extend:XF
16379                       (match_operand:MODEF 2 "register_operand" "u"))]
16380                    UNSPEC_FPATAN))
16381    (clobber (match_scratch:XF 3 "=2"))]
16382   "TARGET_USE_FANCY_MATH_387
16383    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16384        || TARGET_MIX_SSE_I387)
16385    && flag_unsafe_math_optimizations"
16386   "fpatan"
16387   [(set_attr "type" "fpspc")
16388    (set_attr "mode" "XF")])
16389
16390 (define_expand "atan2xf3"
16391   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16392                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16393                                (match_operand:XF 1 "register_operand" "")]
16394                               UNSPEC_FPATAN))
16395               (clobber (match_scratch:XF 3 ""))])]
16396   "TARGET_USE_FANCY_MATH_387
16397    && flag_unsafe_math_optimizations"
16398   "")
16399
16400 (define_expand "atan2<mode>3"
16401   [(use (match_operand:MODEF 0 "register_operand" ""))
16402    (use (match_operand:MODEF 1 "register_operand" ""))
16403    (use (match_operand:MODEF 2 "register_operand" ""))]
16404   "TARGET_USE_FANCY_MATH_387
16405    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16406        || TARGET_MIX_SSE_I387)
16407    && flag_unsafe_math_optimizations"
16408 {
16409   rtx op0 = gen_reg_rtx (XFmode);
16410
16411   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16412   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16413   DONE;
16414 })
16415
16416 (define_expand "atanxf2"
16417   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16418                    (unspec:XF [(match_dup 2)
16419                                (match_operand:XF 1 "register_operand" "")]
16420                               UNSPEC_FPATAN))
16421               (clobber (match_scratch:XF 3 ""))])]
16422   "TARGET_USE_FANCY_MATH_387
16423    && flag_unsafe_math_optimizations"
16424 {
16425   operands[2] = gen_reg_rtx (XFmode);
16426   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16427 })
16428
16429 (define_expand "atan<mode>2"
16430   [(use (match_operand:MODEF 0 "register_operand" ""))
16431    (use (match_operand:MODEF 1 "register_operand" ""))]
16432   "TARGET_USE_FANCY_MATH_387
16433    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16434        || TARGET_MIX_SSE_I387)
16435    && flag_unsafe_math_optimizations"
16436 {
16437   rtx op0 = gen_reg_rtx (XFmode);
16438
16439   rtx op2 = gen_reg_rtx (<MODE>mode);
16440   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16441
16442   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16443   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16444   DONE;
16445 })
16446
16447 (define_expand "asinxf2"
16448   [(set (match_dup 2)
16449         (mult:XF (match_operand:XF 1 "register_operand" "")
16450                  (match_dup 1)))
16451    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16452    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16453    (parallel [(set (match_operand:XF 0 "register_operand" "")
16454                    (unspec:XF [(match_dup 5) (match_dup 1)]
16455                               UNSPEC_FPATAN))
16456               (clobber (match_scratch:XF 6 ""))])]
16457   "TARGET_USE_FANCY_MATH_387
16458    && flag_unsafe_math_optimizations"
16459 {
16460   int i;
16461
16462   if (optimize_insn_for_size_p ())
16463     FAIL;
16464
16465   for (i = 2; i < 6; i++)
16466     operands[i] = gen_reg_rtx (XFmode);
16467
16468   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16469 })
16470
16471 (define_expand "asin<mode>2"
16472   [(use (match_operand:MODEF 0 "register_operand" ""))
16473    (use (match_operand:MODEF 1 "general_operand" ""))]
16474  "TARGET_USE_FANCY_MATH_387
16475    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16476        || TARGET_MIX_SSE_I387)
16477    && flag_unsafe_math_optimizations"
16478 {
16479   rtx op0 = gen_reg_rtx (XFmode);
16480   rtx op1 = gen_reg_rtx (XFmode);
16481
16482   if (optimize_insn_for_size_p ())
16483     FAIL;
16484
16485   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16486   emit_insn (gen_asinxf2 (op0, op1));
16487   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16488   DONE;
16489 })
16490
16491 (define_expand "acosxf2"
16492   [(set (match_dup 2)
16493         (mult:XF (match_operand:XF 1 "register_operand" "")
16494                  (match_dup 1)))
16495    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16496    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16497    (parallel [(set (match_operand:XF 0 "register_operand" "")
16498                    (unspec:XF [(match_dup 1) (match_dup 5)]
16499                               UNSPEC_FPATAN))
16500               (clobber (match_scratch:XF 6 ""))])]
16501   "TARGET_USE_FANCY_MATH_387
16502    && flag_unsafe_math_optimizations"
16503 {
16504   int i;
16505
16506   if (optimize_insn_for_size_p ())
16507     FAIL;
16508
16509   for (i = 2; i < 6; i++)
16510     operands[i] = gen_reg_rtx (XFmode);
16511
16512   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16513 })
16514
16515 (define_expand "acos<mode>2"
16516   [(use (match_operand:MODEF 0 "register_operand" ""))
16517    (use (match_operand:MODEF 1 "general_operand" ""))]
16518  "TARGET_USE_FANCY_MATH_387
16519    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16520        || TARGET_MIX_SSE_I387)
16521    && flag_unsafe_math_optimizations"
16522 {
16523   rtx op0 = gen_reg_rtx (XFmode);
16524   rtx op1 = gen_reg_rtx (XFmode);
16525
16526   if (optimize_insn_for_size_p ())
16527     FAIL;
16528
16529   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16530   emit_insn (gen_acosxf2 (op0, op1));
16531   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16532   DONE;
16533 })
16534
16535 (define_insn "fyl2xxf3_i387"
16536   [(set (match_operand:XF 0 "register_operand" "=f")
16537         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16538                     (match_operand:XF 2 "register_operand" "u")]
16539                    UNSPEC_FYL2X))
16540    (clobber (match_scratch:XF 3 "=2"))]
16541   "TARGET_USE_FANCY_MATH_387
16542    && flag_unsafe_math_optimizations"
16543   "fyl2x"
16544   [(set_attr "type" "fpspc")
16545    (set_attr "mode" "XF")])
16546
16547 (define_insn "fyl2x_extend<mode>xf3_i387"
16548   [(set (match_operand:XF 0 "register_operand" "=f")
16549         (unspec:XF [(float_extend:XF
16550                       (match_operand:MODEF 1 "register_operand" "0"))
16551                     (match_operand:XF 2 "register_operand" "u")]
16552                    UNSPEC_FYL2X))
16553    (clobber (match_scratch:XF 3 "=2"))]
16554   "TARGET_USE_FANCY_MATH_387
16555    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16556        || TARGET_MIX_SSE_I387)
16557    && flag_unsafe_math_optimizations"
16558   "fyl2x"
16559   [(set_attr "type" "fpspc")
16560    (set_attr "mode" "XF")])
16561
16562 (define_expand "logxf2"
16563   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16564                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16565                                (match_dup 2)] UNSPEC_FYL2X))
16566               (clobber (match_scratch:XF 3 ""))])]
16567   "TARGET_USE_FANCY_MATH_387
16568    && flag_unsafe_math_optimizations"
16569 {
16570   operands[2] = gen_reg_rtx (XFmode);
16571   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16572 })
16573
16574 (define_expand "log<mode>2"
16575   [(use (match_operand:MODEF 0 "register_operand" ""))
16576    (use (match_operand:MODEF 1 "register_operand" ""))]
16577   "TARGET_USE_FANCY_MATH_387
16578    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16579        || TARGET_MIX_SSE_I387)
16580    && flag_unsafe_math_optimizations"
16581 {
16582   rtx op0 = gen_reg_rtx (XFmode);
16583
16584   rtx op2 = gen_reg_rtx (XFmode);
16585   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16586
16587   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16588   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16589   DONE;
16590 })
16591
16592 (define_expand "log10xf2"
16593   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16594                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16595                                (match_dup 2)] UNSPEC_FYL2X))
16596               (clobber (match_scratch:XF 3 ""))])]
16597   "TARGET_USE_FANCY_MATH_387
16598    && flag_unsafe_math_optimizations"
16599 {
16600   operands[2] = gen_reg_rtx (XFmode);
16601   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16602 })
16603
16604 (define_expand "log10<mode>2"
16605   [(use (match_operand:MODEF 0 "register_operand" ""))
16606    (use (match_operand:MODEF 1 "register_operand" ""))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16609        || TARGET_MIX_SSE_I387)
16610    && flag_unsafe_math_optimizations"
16611 {
16612   rtx op0 = gen_reg_rtx (XFmode);
16613
16614   rtx op2 = gen_reg_rtx (XFmode);
16615   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16616
16617   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16618   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16619   DONE;
16620 })
16621
16622 (define_expand "log2xf2"
16623   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16624                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16625                                (match_dup 2)] UNSPEC_FYL2X))
16626               (clobber (match_scratch:XF 3 ""))])]
16627   "TARGET_USE_FANCY_MATH_387
16628    && flag_unsafe_math_optimizations"
16629 {
16630   operands[2] = gen_reg_rtx (XFmode);
16631   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16632 })
16633
16634 (define_expand "log2<mode>2"
16635   [(use (match_operand:MODEF 0 "register_operand" ""))
16636    (use (match_operand:MODEF 1 "register_operand" ""))]
16637   "TARGET_USE_FANCY_MATH_387
16638    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16639        || TARGET_MIX_SSE_I387)
16640    && flag_unsafe_math_optimizations"
16641 {
16642   rtx op0 = gen_reg_rtx (XFmode);
16643
16644   rtx op2 = gen_reg_rtx (XFmode);
16645   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16646
16647   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16648   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16649   DONE;
16650 })
16651
16652 (define_insn "fyl2xp1xf3_i387"
16653   [(set (match_operand:XF 0 "register_operand" "=f")
16654         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16655                     (match_operand:XF 2 "register_operand" "u")]
16656                    UNSPEC_FYL2XP1))
16657    (clobber (match_scratch:XF 3 "=2"))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && flag_unsafe_math_optimizations"
16660   "fyl2xp1"
16661   [(set_attr "type" "fpspc")
16662    (set_attr "mode" "XF")])
16663
16664 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16665   [(set (match_operand:XF 0 "register_operand" "=f")
16666         (unspec:XF [(float_extend:XF
16667                       (match_operand:MODEF 1 "register_operand" "0"))
16668                     (match_operand:XF 2 "register_operand" "u")]
16669                    UNSPEC_FYL2XP1))
16670    (clobber (match_scratch:XF 3 "=2"))]
16671   "TARGET_USE_FANCY_MATH_387
16672    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16673        || TARGET_MIX_SSE_I387)
16674    && flag_unsafe_math_optimizations"
16675   "fyl2xp1"
16676   [(set_attr "type" "fpspc")
16677    (set_attr "mode" "XF")])
16678
16679 (define_expand "log1pxf2"
16680   [(use (match_operand:XF 0 "register_operand" ""))
16681    (use (match_operand:XF 1 "register_operand" ""))]
16682   "TARGET_USE_FANCY_MATH_387
16683    && flag_unsafe_math_optimizations"
16684 {
16685   if (optimize_insn_for_size_p ())
16686     FAIL;
16687
16688   ix86_emit_i387_log1p (operands[0], operands[1]);
16689   DONE;
16690 })
16691
16692 (define_expand "log1p<mode>2"
16693   [(use (match_operand:MODEF 0 "register_operand" ""))
16694    (use (match_operand:MODEF 1 "register_operand" ""))]
16695   "TARGET_USE_FANCY_MATH_387
16696    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16697        || TARGET_MIX_SSE_I387)
16698    && flag_unsafe_math_optimizations"
16699 {
16700   rtx op0;
16701
16702   if (optimize_insn_for_size_p ())
16703     FAIL;
16704
16705   op0 = gen_reg_rtx (XFmode);
16706
16707   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16708
16709   ix86_emit_i387_log1p (op0, operands[1]);
16710   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16711   DONE;
16712 })
16713
16714 (define_insn "fxtractxf3_i387"
16715   [(set (match_operand:XF 0 "register_operand" "=f")
16716         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16717                    UNSPEC_XTRACT_FRACT))
16718    (set (match_operand:XF 1 "register_operand" "=u")
16719         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16720   "TARGET_USE_FANCY_MATH_387
16721    && flag_unsafe_math_optimizations"
16722   "fxtract"
16723   [(set_attr "type" "fpspc")
16724    (set_attr "mode" "XF")])
16725
16726 (define_insn "fxtract_extend<mode>xf3_i387"
16727   [(set (match_operand:XF 0 "register_operand" "=f")
16728         (unspec:XF [(float_extend:XF
16729                       (match_operand:MODEF 2 "register_operand" "0"))]
16730                    UNSPEC_XTRACT_FRACT))
16731    (set (match_operand:XF 1 "register_operand" "=u")
16732         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16735        || TARGET_MIX_SSE_I387)
16736    && flag_unsafe_math_optimizations"
16737   "fxtract"
16738   [(set_attr "type" "fpspc")
16739    (set_attr "mode" "XF")])
16740
16741 (define_expand "logbxf2"
16742   [(parallel [(set (match_dup 2)
16743                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16744                               UNSPEC_XTRACT_FRACT))
16745               (set (match_operand:XF 0 "register_operand" "")
16746                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16747   "TARGET_USE_FANCY_MATH_387
16748    && flag_unsafe_math_optimizations"
16749 {
16750   operands[2] = gen_reg_rtx (XFmode);
16751 })
16752
16753 (define_expand "logb<mode>2"
16754   [(use (match_operand:MODEF 0 "register_operand" ""))
16755    (use (match_operand:MODEF 1 "register_operand" ""))]
16756   "TARGET_USE_FANCY_MATH_387
16757    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16758        || TARGET_MIX_SSE_I387)
16759    && flag_unsafe_math_optimizations"
16760 {
16761   rtx op0 = gen_reg_rtx (XFmode);
16762   rtx op1 = gen_reg_rtx (XFmode);
16763
16764   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16765   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16766   DONE;
16767 })
16768
16769 (define_expand "ilogbxf2"
16770   [(use (match_operand:SI 0 "register_operand" ""))
16771    (use (match_operand:XF 1 "register_operand" ""))]
16772   "TARGET_USE_FANCY_MATH_387
16773    && flag_unsafe_math_optimizations"
16774 {
16775   rtx op0, op1;
16776
16777   if (optimize_insn_for_size_p ())
16778     FAIL;
16779
16780   op0 = gen_reg_rtx (XFmode);
16781   op1 = gen_reg_rtx (XFmode);
16782
16783   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16784   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16785   DONE;
16786 })
16787
16788 (define_expand "ilogb<mode>2"
16789   [(use (match_operand:SI 0 "register_operand" ""))
16790    (use (match_operand:MODEF 1 "register_operand" ""))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793        || TARGET_MIX_SSE_I387)
16794    && flag_unsafe_math_optimizations"
16795 {
16796   rtx op0, op1;
16797
16798   if (optimize_insn_for_size_p ())
16799     FAIL;
16800
16801   op0 = gen_reg_rtx (XFmode);
16802   op1 = gen_reg_rtx (XFmode);
16803
16804   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16805   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16806   DONE;
16807 })
16808
16809 (define_insn "*f2xm1xf2_i387"
16810   [(set (match_operand:XF 0 "register_operand" "=f")
16811         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16812                    UNSPEC_F2XM1))]
16813   "TARGET_USE_FANCY_MATH_387
16814    && flag_unsafe_math_optimizations"
16815   "f2xm1"
16816   [(set_attr "type" "fpspc")
16817    (set_attr "mode" "XF")])
16818
16819 (define_insn "*fscalexf4_i387"
16820   [(set (match_operand:XF 0 "register_operand" "=f")
16821         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16822                     (match_operand:XF 3 "register_operand" "1")]
16823                    UNSPEC_FSCALE_FRACT))
16824    (set (match_operand:XF 1 "register_operand" "=u")
16825         (unspec:XF [(match_dup 2) (match_dup 3)]
16826                    UNSPEC_FSCALE_EXP))]
16827   "TARGET_USE_FANCY_MATH_387
16828    && flag_unsafe_math_optimizations"
16829   "fscale"
16830   [(set_attr "type" "fpspc")
16831    (set_attr "mode" "XF")])
16832
16833 (define_expand "expNcorexf3"
16834   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16835                                (match_operand:XF 2 "register_operand" "")))
16836    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16837    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16838    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16839    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16840    (parallel [(set (match_operand:XF 0 "register_operand" "")
16841                    (unspec:XF [(match_dup 8) (match_dup 4)]
16842                               UNSPEC_FSCALE_FRACT))
16843               (set (match_dup 9)
16844                    (unspec:XF [(match_dup 8) (match_dup 4)]
16845                               UNSPEC_FSCALE_EXP))])]
16846   "TARGET_USE_FANCY_MATH_387
16847    && flag_unsafe_math_optimizations"
16848 {
16849   int i;
16850
16851   if (optimize_insn_for_size_p ())
16852     FAIL;
16853
16854   for (i = 3; i < 10; i++)
16855     operands[i] = gen_reg_rtx (XFmode);
16856
16857   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16858 })
16859
16860 (define_expand "expxf2"
16861   [(use (match_operand:XF 0 "register_operand" ""))
16862    (use (match_operand:XF 1 "register_operand" ""))]
16863   "TARGET_USE_FANCY_MATH_387
16864    && flag_unsafe_math_optimizations"
16865 {
16866   rtx op2;
16867
16868   if (optimize_insn_for_size_p ())
16869     FAIL;
16870
16871   op2 = gen_reg_rtx (XFmode);
16872   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16873
16874   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16875   DONE;
16876 })
16877
16878 (define_expand "exp<mode>2"
16879   [(use (match_operand:MODEF 0 "register_operand" ""))
16880    (use (match_operand:MODEF 1 "general_operand" ""))]
16881  "TARGET_USE_FANCY_MATH_387
16882    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16883        || TARGET_MIX_SSE_I387)
16884    && flag_unsafe_math_optimizations"
16885 {
16886   rtx op0, op1;
16887
16888   if (optimize_insn_for_size_p ())
16889     FAIL;
16890
16891   op0 = gen_reg_rtx (XFmode);
16892   op1 = gen_reg_rtx (XFmode);
16893
16894   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16895   emit_insn (gen_expxf2 (op0, op1));
16896   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16897   DONE;
16898 })
16899
16900 (define_expand "exp10xf2"
16901   [(use (match_operand:XF 0 "register_operand" ""))
16902    (use (match_operand:XF 1 "register_operand" ""))]
16903   "TARGET_USE_FANCY_MATH_387
16904    && flag_unsafe_math_optimizations"
16905 {
16906   rtx op2;
16907
16908   if (optimize_insn_for_size_p ())
16909     FAIL;
16910
16911   op2 = gen_reg_rtx (XFmode);
16912   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16913
16914   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16915   DONE;
16916 })
16917
16918 (define_expand "exp10<mode>2"
16919   [(use (match_operand:MODEF 0 "register_operand" ""))
16920    (use (match_operand:MODEF 1 "general_operand" ""))]
16921  "TARGET_USE_FANCY_MATH_387
16922    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16923        || TARGET_MIX_SSE_I387)
16924    && flag_unsafe_math_optimizations"
16925 {
16926   rtx op0, op1;
16927
16928   if (optimize_insn_for_size_p ())
16929     FAIL;
16930
16931   op0 = gen_reg_rtx (XFmode);
16932   op1 = gen_reg_rtx (XFmode);
16933
16934   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16935   emit_insn (gen_exp10xf2 (op0, op1));
16936   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16937   DONE;
16938 })
16939
16940 (define_expand "exp2xf2"
16941   [(use (match_operand:XF 0 "register_operand" ""))
16942    (use (match_operand:XF 1 "register_operand" ""))]
16943   "TARGET_USE_FANCY_MATH_387
16944    && flag_unsafe_math_optimizations"
16945 {
16946   rtx op2;
16947
16948   if (optimize_insn_for_size_p ())
16949     FAIL;
16950
16951   op2 = gen_reg_rtx (XFmode);
16952   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16953
16954   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16955   DONE;
16956 })
16957
16958 (define_expand "exp2<mode>2"
16959   [(use (match_operand:MODEF 0 "register_operand" ""))
16960    (use (match_operand:MODEF 1 "general_operand" ""))]
16961  "TARGET_USE_FANCY_MATH_387
16962    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16963        || TARGET_MIX_SSE_I387)
16964    && flag_unsafe_math_optimizations"
16965 {
16966   rtx op0, op1;
16967
16968   if (optimize_insn_for_size_p ())
16969     FAIL;
16970
16971   op0 = gen_reg_rtx (XFmode);
16972   op1 = gen_reg_rtx (XFmode);
16973
16974   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16975   emit_insn (gen_exp2xf2 (op0, op1));
16976   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16977   DONE;
16978 })
16979
16980 (define_expand "expm1xf2"
16981   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16982                                (match_dup 2)))
16983    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16984    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16985    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16986    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16987    (parallel [(set (match_dup 7)
16988                    (unspec:XF [(match_dup 6) (match_dup 4)]
16989                               UNSPEC_FSCALE_FRACT))
16990               (set (match_dup 8)
16991                    (unspec:XF [(match_dup 6) (match_dup 4)]
16992                               UNSPEC_FSCALE_EXP))])
16993    (parallel [(set (match_dup 10)
16994                    (unspec:XF [(match_dup 9) (match_dup 8)]
16995                               UNSPEC_FSCALE_FRACT))
16996               (set (match_dup 11)
16997                    (unspec:XF [(match_dup 9) (match_dup 8)]
16998                               UNSPEC_FSCALE_EXP))])
16999    (set (match_dup 12) (minus:XF (match_dup 10)
17000                                  (float_extend:XF (match_dup 13))))
17001    (set (match_operand:XF 0 "register_operand" "")
17002         (plus:XF (match_dup 12) (match_dup 7)))]
17003   "TARGET_USE_FANCY_MATH_387
17004    && flag_unsafe_math_optimizations"
17005 {
17006   int i;
17007
17008   if (optimize_insn_for_size_p ())
17009     FAIL;
17010
17011   for (i = 2; i < 13; i++)
17012     operands[i] = gen_reg_rtx (XFmode);
17013
17014   operands[13]
17015     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17016
17017   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17018 })
17019
17020 (define_expand "expm1<mode>2"
17021   [(use (match_operand:MODEF 0 "register_operand" ""))
17022    (use (match_operand:MODEF 1 "general_operand" ""))]
17023  "TARGET_USE_FANCY_MATH_387
17024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17025        || TARGET_MIX_SSE_I387)
17026    && flag_unsafe_math_optimizations"
17027 {
17028   rtx op0, op1;
17029
17030   if (optimize_insn_for_size_p ())
17031     FAIL;
17032
17033   op0 = gen_reg_rtx (XFmode);
17034   op1 = gen_reg_rtx (XFmode);
17035
17036   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17037   emit_insn (gen_expm1xf2 (op0, op1));
17038   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17039   DONE;
17040 })
17041
17042 (define_expand "ldexpxf3"
17043   [(set (match_dup 3)
17044         (float:XF (match_operand:SI 2 "register_operand" "")))
17045    (parallel [(set (match_operand:XF 0 " register_operand" "")
17046                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17047                                (match_dup 3)]
17048                               UNSPEC_FSCALE_FRACT))
17049               (set (match_dup 4)
17050                    (unspec:XF [(match_dup 1) (match_dup 3)]
17051                               UNSPEC_FSCALE_EXP))])]
17052   "TARGET_USE_FANCY_MATH_387
17053    && flag_unsafe_math_optimizations"
17054 {
17055   if (optimize_insn_for_size_p ())
17056     FAIL;
17057
17058   operands[3] = gen_reg_rtx (XFmode);
17059   operands[4] = gen_reg_rtx (XFmode);
17060 })
17061
17062 (define_expand "ldexp<mode>3"
17063   [(use (match_operand:MODEF 0 "register_operand" ""))
17064    (use (match_operand:MODEF 1 "general_operand" ""))
17065    (use (match_operand:SI 2 "register_operand" ""))]
17066  "TARGET_USE_FANCY_MATH_387
17067    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17068        || TARGET_MIX_SSE_I387)
17069    && flag_unsafe_math_optimizations"
17070 {
17071   rtx op0, op1;
17072
17073   if (optimize_insn_for_size_p ())
17074     FAIL;
17075
17076   op0 = gen_reg_rtx (XFmode);
17077   op1 = gen_reg_rtx (XFmode);
17078
17079   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17080   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17081   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17082   DONE;
17083 })
17084
17085 (define_expand "scalbxf3"
17086   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17087                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17088                                (match_operand:XF 2 "register_operand" "")]
17089                               UNSPEC_FSCALE_FRACT))
17090               (set (match_dup 3)
17091                    (unspec:XF [(match_dup 1) (match_dup 2)]
17092                               UNSPEC_FSCALE_EXP))])]
17093   "TARGET_USE_FANCY_MATH_387
17094    && flag_unsafe_math_optimizations"
17095 {
17096   if (optimize_insn_for_size_p ())
17097     FAIL;
17098
17099   operands[3] = gen_reg_rtx (XFmode);
17100 })
17101
17102 (define_expand "scalb<mode>3"
17103   [(use (match_operand:MODEF 0 "register_operand" ""))
17104    (use (match_operand:MODEF 1 "general_operand" ""))
17105    (use (match_operand:MODEF 2 "general_operand" ""))]
17106  "TARGET_USE_FANCY_MATH_387
17107    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17108        || TARGET_MIX_SSE_I387)
17109    && flag_unsafe_math_optimizations"
17110 {
17111   rtx op0, op1, op2;
17112
17113   if (optimize_insn_for_size_p ())
17114     FAIL;
17115
17116   op0 = gen_reg_rtx (XFmode);
17117   op1 = gen_reg_rtx (XFmode);
17118   op2 = gen_reg_rtx (XFmode);
17119
17120   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17121   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17122   emit_insn (gen_scalbxf3 (op0, op1, op2));
17123   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17124   DONE;
17125 })
17126
17127 (define_expand "significandxf2"
17128   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17129                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17130                               UNSPEC_XTRACT_FRACT))
17131               (set (match_dup 2)
17132                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations"
17135 {
17136   operands[2] = gen_reg_rtx (XFmode);
17137 })
17138
17139 (define_expand "significand<mode>2"
17140   [(use (match_operand:MODEF 0 "register_operand" ""))
17141    (use (match_operand:MODEF 1 "register_operand" ""))]
17142   "TARGET_USE_FANCY_MATH_387
17143    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17144        || TARGET_MIX_SSE_I387)
17145    && flag_unsafe_math_optimizations"
17146 {
17147   rtx op0 = gen_reg_rtx (XFmode);
17148   rtx op1 = gen_reg_rtx (XFmode);
17149
17150   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17151   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17152   DONE;
17153 })
17154 \f
17155
17156 (define_insn "sse4_1_round<mode>2"
17157   [(set (match_operand:MODEF 0 "register_operand" "=x")
17158         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17159                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17160                       UNSPEC_ROUND))]
17161   "TARGET_ROUND"
17162   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17163   [(set_attr "type" "ssecvt")
17164    (set_attr "prefix_extra" "1")
17165    (set_attr "prefix" "maybe_vex")
17166    (set_attr "mode" "<MODE>")])
17167
17168 (define_insn "rintxf2"
17169   [(set (match_operand:XF 0 "register_operand" "=f")
17170         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17171                    UNSPEC_FRNDINT))]
17172   "TARGET_USE_FANCY_MATH_387
17173    && flag_unsafe_math_optimizations"
17174   "frndint"
17175   [(set_attr "type" "fpspc")
17176    (set_attr "mode" "XF")])
17177
17178 (define_expand "rint<mode>2"
17179   [(use (match_operand:MODEF 0 "register_operand" ""))
17180    (use (match_operand:MODEF 1 "register_operand" ""))]
17181   "(TARGET_USE_FANCY_MATH_387
17182     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183         || TARGET_MIX_SSE_I387)
17184     && flag_unsafe_math_optimizations)
17185    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17186        && !flag_trapping_math)"
17187 {
17188   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17189       && !flag_trapping_math)
17190     {
17191       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17192         FAIL;
17193       if (TARGET_ROUND)
17194         emit_insn (gen_sse4_1_round<mode>2
17195                    (operands[0], operands[1], GEN_INT (0x04)));
17196       else
17197         ix86_expand_rint (operand0, operand1);
17198     }
17199   else
17200     {
17201       rtx op0 = gen_reg_rtx (XFmode);
17202       rtx op1 = gen_reg_rtx (XFmode);
17203
17204       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17205       emit_insn (gen_rintxf2 (op0, op1));
17206
17207       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17208     }
17209   DONE;
17210 })
17211
17212 (define_expand "round<mode>2"
17213   [(match_operand:MODEF 0 "register_operand" "")
17214    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17215   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17216    && !flag_trapping_math && !flag_rounding_math"
17217 {
17218   if (optimize_insn_for_size_p ())
17219     FAIL;
17220   if (TARGET_64BIT || (<MODE>mode != DFmode))
17221     ix86_expand_round (operand0, operand1);
17222   else
17223     ix86_expand_rounddf_32 (operand0, operand1);
17224   DONE;
17225 })
17226
17227 (define_insn_and_split "*fistdi2_1"
17228   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17229         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17230                    UNSPEC_FIST))]
17231   "TARGET_USE_FANCY_MATH_387
17232    && can_create_pseudo_p ()"
17233   "#"
17234   "&& 1"
17235   [(const_int 0)]
17236 {
17237   if (memory_operand (operands[0], VOIDmode))
17238     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17239   else
17240     {
17241       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17242       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17243                                          operands[2]));
17244     }
17245   DONE;
17246 }
17247   [(set_attr "type" "fpspc")
17248    (set_attr "mode" "DI")])
17249
17250 (define_insn "fistdi2"
17251   [(set (match_operand:DI 0 "memory_operand" "=m")
17252         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17253                    UNSPEC_FIST))
17254    (clobber (match_scratch:XF 2 "=&1f"))]
17255   "TARGET_USE_FANCY_MATH_387"
17256   "* return output_fix_trunc (insn, operands, 0);"
17257   [(set_attr "type" "fpspc")
17258    (set_attr "mode" "DI")])
17259
17260 (define_insn "fistdi2_with_temp"
17261   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17262         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17263                    UNSPEC_FIST))
17264    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17265    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17266   "TARGET_USE_FANCY_MATH_387"
17267   "#"
17268   [(set_attr "type" "fpspc")
17269    (set_attr "mode" "DI")])
17270
17271 (define_split
17272   [(set (match_operand:DI 0 "register_operand" "")
17273         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17274                    UNSPEC_FIST))
17275    (clobber (match_operand:DI 2 "memory_operand" ""))
17276    (clobber (match_scratch 3 ""))]
17277   "reload_completed"
17278   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17279               (clobber (match_dup 3))])
17280    (set (match_dup 0) (match_dup 2))]
17281   "")
17282
17283 (define_split
17284   [(set (match_operand:DI 0 "memory_operand" "")
17285         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17286                    UNSPEC_FIST))
17287    (clobber (match_operand:DI 2 "memory_operand" ""))
17288    (clobber (match_scratch 3 ""))]
17289   "reload_completed"
17290   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17291               (clobber (match_dup 3))])]
17292   "")
17293
17294 (define_insn_and_split "*fist<mode>2_1"
17295   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17296         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17297                            UNSPEC_FIST))]
17298   "TARGET_USE_FANCY_MATH_387
17299    && can_create_pseudo_p ()"
17300   "#"
17301   "&& 1"
17302   [(const_int 0)]
17303 {
17304   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17305   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17306                                         operands[2]));
17307   DONE;
17308 }
17309   [(set_attr "type" "fpspc")
17310    (set_attr "mode" "<MODE>")])
17311
17312 (define_insn "fist<mode>2"
17313   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17314         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17315                            UNSPEC_FIST))]
17316   "TARGET_USE_FANCY_MATH_387"
17317   "* return output_fix_trunc (insn, operands, 0);"
17318   [(set_attr "type" "fpspc")
17319    (set_attr "mode" "<MODE>")])
17320
17321 (define_insn "fist<mode>2_with_temp"
17322   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17323         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17324                            UNSPEC_FIST))
17325    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17326   "TARGET_USE_FANCY_MATH_387"
17327   "#"
17328   [(set_attr "type" "fpspc")
17329    (set_attr "mode" "<MODE>")])
17330
17331 (define_split
17332   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17333         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17334                            UNSPEC_FIST))
17335    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17336   "reload_completed"
17337   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17338    (set (match_dup 0) (match_dup 2))]
17339   "")
17340
17341 (define_split
17342   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17343         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17344                            UNSPEC_FIST))
17345    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17346   "reload_completed"
17347   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17348   "")
17349
17350 (define_expand "lrintxf<mode>2"
17351   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17352      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17353                       UNSPEC_FIST))]
17354   "TARGET_USE_FANCY_MATH_387"
17355   "")
17356
17357 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17358   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17359      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17360                         UNSPEC_FIX_NOTRUNC))]
17361   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17362    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17363   "")
17364
17365 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17366   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17367    (match_operand:MODEF 1 "register_operand" "")]
17368   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17369    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17370    && !flag_trapping_math && !flag_rounding_math"
17371 {
17372   if (optimize_insn_for_size_p ())
17373     FAIL;
17374   ix86_expand_lround (operand0, operand1);
17375   DONE;
17376 })
17377
17378 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17379 (define_insn_and_split "frndintxf2_floor"
17380   [(set (match_operand:XF 0 "register_operand" "")
17381         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17382          UNSPEC_FRNDINT_FLOOR))
17383    (clobber (reg:CC FLAGS_REG))]
17384   "TARGET_USE_FANCY_MATH_387
17385    && flag_unsafe_math_optimizations
17386    && can_create_pseudo_p ()"
17387   "#"
17388   "&& 1"
17389   [(const_int 0)]
17390 {
17391   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17392
17393   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17394   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17395
17396   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17397                                         operands[2], operands[3]));
17398   DONE;
17399 }
17400   [(set_attr "type" "frndint")
17401    (set_attr "i387_cw" "floor")
17402    (set_attr "mode" "XF")])
17403
17404 (define_insn "frndintxf2_floor_i387"
17405   [(set (match_operand:XF 0 "register_operand" "=f")
17406         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17407          UNSPEC_FRNDINT_FLOOR))
17408    (use (match_operand:HI 2 "memory_operand" "m"))
17409    (use (match_operand:HI 3 "memory_operand" "m"))]
17410   "TARGET_USE_FANCY_MATH_387
17411    && flag_unsafe_math_optimizations"
17412   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17413   [(set_attr "type" "frndint")
17414    (set_attr "i387_cw" "floor")
17415    (set_attr "mode" "XF")])
17416
17417 (define_expand "floorxf2"
17418   [(use (match_operand:XF 0 "register_operand" ""))
17419    (use (match_operand:XF 1 "register_operand" ""))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && flag_unsafe_math_optimizations"
17422 {
17423   if (optimize_insn_for_size_p ())
17424     FAIL;
17425   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17426   DONE;
17427 })
17428
17429 (define_expand "floor<mode>2"
17430   [(use (match_operand:MODEF 0 "register_operand" ""))
17431    (use (match_operand:MODEF 1 "register_operand" ""))]
17432   "(TARGET_USE_FANCY_MATH_387
17433     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17434         || TARGET_MIX_SSE_I387)
17435     && flag_unsafe_math_optimizations)
17436    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17437        && !flag_trapping_math)"
17438 {
17439   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17440       && !flag_trapping_math
17441       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17442     {
17443       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17444         FAIL;
17445       if (TARGET_ROUND)
17446         emit_insn (gen_sse4_1_round<mode>2
17447                    (operands[0], operands[1], GEN_INT (0x01)));
17448       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17449         ix86_expand_floorceil (operand0, operand1, true);
17450       else
17451         ix86_expand_floorceildf_32 (operand0, operand1, true);
17452     }
17453   else
17454     {
17455       rtx op0, op1;
17456
17457       if (optimize_insn_for_size_p ())
17458         FAIL;
17459
17460       op0 = gen_reg_rtx (XFmode);
17461       op1 = gen_reg_rtx (XFmode);
17462       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17463       emit_insn (gen_frndintxf2_floor (op0, op1));
17464
17465       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17466     }
17467   DONE;
17468 })
17469
17470 (define_insn_and_split "*fist<mode>2_floor_1"
17471   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17472         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17473          UNSPEC_FIST_FLOOR))
17474    (clobber (reg:CC FLAGS_REG))]
17475   "TARGET_USE_FANCY_MATH_387
17476    && flag_unsafe_math_optimizations
17477    && can_create_pseudo_p ()"
17478   "#"
17479   "&& 1"
17480   [(const_int 0)]
17481 {
17482   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17483
17484   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17485   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17486   if (memory_operand (operands[0], VOIDmode))
17487     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17488                                       operands[2], operands[3]));
17489   else
17490     {
17491       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17492       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17493                                                   operands[2], operands[3],
17494                                                   operands[4]));
17495     }
17496   DONE;
17497 }
17498   [(set_attr "type" "fistp")
17499    (set_attr "i387_cw" "floor")
17500    (set_attr "mode" "<MODE>")])
17501
17502 (define_insn "fistdi2_floor"
17503   [(set (match_operand:DI 0 "memory_operand" "=m")
17504         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17505          UNSPEC_FIST_FLOOR))
17506    (use (match_operand:HI 2 "memory_operand" "m"))
17507    (use (match_operand:HI 3 "memory_operand" "m"))
17508    (clobber (match_scratch:XF 4 "=&1f"))]
17509   "TARGET_USE_FANCY_MATH_387
17510    && flag_unsafe_math_optimizations"
17511   "* return output_fix_trunc (insn, operands, 0);"
17512   [(set_attr "type" "fistp")
17513    (set_attr "i387_cw" "floor")
17514    (set_attr "mode" "DI")])
17515
17516 (define_insn "fistdi2_floor_with_temp"
17517   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17518         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17519          UNSPEC_FIST_FLOOR))
17520    (use (match_operand:HI 2 "memory_operand" "m,m"))
17521    (use (match_operand:HI 3 "memory_operand" "m,m"))
17522    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17523    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17524   "TARGET_USE_FANCY_MATH_387
17525    && flag_unsafe_math_optimizations"
17526   "#"
17527   [(set_attr "type" "fistp")
17528    (set_attr "i387_cw" "floor")
17529    (set_attr "mode" "DI")])
17530
17531 (define_split
17532   [(set (match_operand:DI 0 "register_operand" "")
17533         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17534          UNSPEC_FIST_FLOOR))
17535    (use (match_operand:HI 2 "memory_operand" ""))
17536    (use (match_operand:HI 3 "memory_operand" ""))
17537    (clobber (match_operand:DI 4 "memory_operand" ""))
17538    (clobber (match_scratch 5 ""))]
17539   "reload_completed"
17540   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17541               (use (match_dup 2))
17542               (use (match_dup 3))
17543               (clobber (match_dup 5))])
17544    (set (match_dup 0) (match_dup 4))]
17545   "")
17546
17547 (define_split
17548   [(set (match_operand:DI 0 "memory_operand" "")
17549         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17550          UNSPEC_FIST_FLOOR))
17551    (use (match_operand:HI 2 "memory_operand" ""))
17552    (use (match_operand:HI 3 "memory_operand" ""))
17553    (clobber (match_operand:DI 4 "memory_operand" ""))
17554    (clobber (match_scratch 5 ""))]
17555   "reload_completed"
17556   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17557               (use (match_dup 2))
17558               (use (match_dup 3))
17559               (clobber (match_dup 5))])]
17560   "")
17561
17562 (define_insn "fist<mode>2_floor"
17563   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17564         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17565          UNSPEC_FIST_FLOOR))
17566    (use (match_operand:HI 2 "memory_operand" "m"))
17567    (use (match_operand:HI 3 "memory_operand" "m"))]
17568   "TARGET_USE_FANCY_MATH_387
17569    && flag_unsafe_math_optimizations"
17570   "* return output_fix_trunc (insn, operands, 0);"
17571   [(set_attr "type" "fistp")
17572    (set_attr "i387_cw" "floor")
17573    (set_attr "mode" "<MODE>")])
17574
17575 (define_insn "fist<mode>2_floor_with_temp"
17576   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17577         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17578          UNSPEC_FIST_FLOOR))
17579    (use (match_operand:HI 2 "memory_operand" "m,m"))
17580    (use (match_operand:HI 3 "memory_operand" "m,m"))
17581    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17582   "TARGET_USE_FANCY_MATH_387
17583    && flag_unsafe_math_optimizations"
17584   "#"
17585   [(set_attr "type" "fistp")
17586    (set_attr "i387_cw" "floor")
17587    (set_attr "mode" "<MODE>")])
17588
17589 (define_split
17590   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17591         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17592          UNSPEC_FIST_FLOOR))
17593    (use (match_operand:HI 2 "memory_operand" ""))
17594    (use (match_operand:HI 3 "memory_operand" ""))
17595    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17596   "reload_completed"
17597   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17598                                   UNSPEC_FIST_FLOOR))
17599               (use (match_dup 2))
17600               (use (match_dup 3))])
17601    (set (match_dup 0) (match_dup 4))]
17602   "")
17603
17604 (define_split
17605   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17606         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17607          UNSPEC_FIST_FLOOR))
17608    (use (match_operand:HI 2 "memory_operand" ""))
17609    (use (match_operand:HI 3 "memory_operand" ""))
17610    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17611   "reload_completed"
17612   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17613                                   UNSPEC_FIST_FLOOR))
17614               (use (match_dup 2))
17615               (use (match_dup 3))])]
17616   "")
17617
17618 (define_expand "lfloorxf<mode>2"
17619   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17620                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17621                     UNSPEC_FIST_FLOOR))
17622               (clobber (reg:CC FLAGS_REG))])]
17623   "TARGET_USE_FANCY_MATH_387
17624    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17625    && flag_unsafe_math_optimizations"
17626   "")
17627
17628 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17629   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17630    (match_operand:MODEF 1 "register_operand" "")]
17631   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17632    && !flag_trapping_math"
17633 {
17634   if (TARGET_64BIT && optimize_insn_for_size_p ())
17635     FAIL;
17636   ix86_expand_lfloorceil (operand0, operand1, true);
17637   DONE;
17638 })
17639
17640 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17641 (define_insn_and_split "frndintxf2_ceil"
17642   [(set (match_operand:XF 0 "register_operand" "")
17643         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17644          UNSPEC_FRNDINT_CEIL))
17645    (clobber (reg:CC FLAGS_REG))]
17646   "TARGET_USE_FANCY_MATH_387
17647    && flag_unsafe_math_optimizations
17648    && can_create_pseudo_p ()"
17649   "#"
17650   "&& 1"
17651   [(const_int 0)]
17652 {
17653   ix86_optimize_mode_switching[I387_CEIL] = 1;
17654
17655   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17656   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17657
17658   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17659                                        operands[2], operands[3]));
17660   DONE;
17661 }
17662   [(set_attr "type" "frndint")
17663    (set_attr "i387_cw" "ceil")
17664    (set_attr "mode" "XF")])
17665
17666 (define_insn "frndintxf2_ceil_i387"
17667   [(set (match_operand:XF 0 "register_operand" "=f")
17668         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17669          UNSPEC_FRNDINT_CEIL))
17670    (use (match_operand:HI 2 "memory_operand" "m"))
17671    (use (match_operand:HI 3 "memory_operand" "m"))]
17672   "TARGET_USE_FANCY_MATH_387
17673    && flag_unsafe_math_optimizations"
17674   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17675   [(set_attr "type" "frndint")
17676    (set_attr "i387_cw" "ceil")
17677    (set_attr "mode" "XF")])
17678
17679 (define_expand "ceilxf2"
17680   [(use (match_operand:XF 0 "register_operand" ""))
17681    (use (match_operand:XF 1 "register_operand" ""))]
17682   "TARGET_USE_FANCY_MATH_387
17683    && flag_unsafe_math_optimizations"
17684 {
17685   if (optimize_insn_for_size_p ())
17686     FAIL;
17687   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17688   DONE;
17689 })
17690
17691 (define_expand "ceil<mode>2"
17692   [(use (match_operand:MODEF 0 "register_operand" ""))
17693    (use (match_operand:MODEF 1 "register_operand" ""))]
17694   "(TARGET_USE_FANCY_MATH_387
17695     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17696         || TARGET_MIX_SSE_I387)
17697     && flag_unsafe_math_optimizations)
17698    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17699        && !flag_trapping_math)"
17700 {
17701   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17702       && !flag_trapping_math
17703       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17704     {
17705       if (TARGET_ROUND)
17706         emit_insn (gen_sse4_1_round<mode>2
17707                    (operands[0], operands[1], GEN_INT (0x02)));
17708       else if (optimize_insn_for_size_p ())
17709         FAIL;
17710       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17711         ix86_expand_floorceil (operand0, operand1, false);
17712       else
17713         ix86_expand_floorceildf_32 (operand0, operand1, false);
17714     }
17715   else
17716     {
17717       rtx op0, op1;
17718
17719       if (optimize_insn_for_size_p ())
17720         FAIL;
17721
17722       op0 = gen_reg_rtx (XFmode);
17723       op1 = gen_reg_rtx (XFmode);
17724       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17725       emit_insn (gen_frndintxf2_ceil (op0, op1));
17726
17727       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17728     }
17729   DONE;
17730 })
17731
17732 (define_insn_and_split "*fist<mode>2_ceil_1"
17733   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17734         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17735          UNSPEC_FIST_CEIL))
17736    (clobber (reg:CC FLAGS_REG))]
17737   "TARGET_USE_FANCY_MATH_387
17738    && flag_unsafe_math_optimizations
17739    && can_create_pseudo_p ()"
17740   "#"
17741   "&& 1"
17742   [(const_int 0)]
17743 {
17744   ix86_optimize_mode_switching[I387_CEIL] = 1;
17745
17746   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17747   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17748   if (memory_operand (operands[0], VOIDmode))
17749     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17750                                      operands[2], operands[3]));
17751   else
17752     {
17753       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17754       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17755                                                  operands[2], operands[3],
17756                                                  operands[4]));
17757     }
17758   DONE;
17759 }
17760   [(set_attr "type" "fistp")
17761    (set_attr "i387_cw" "ceil")
17762    (set_attr "mode" "<MODE>")])
17763
17764 (define_insn "fistdi2_ceil"
17765   [(set (match_operand:DI 0 "memory_operand" "=m")
17766         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17767          UNSPEC_FIST_CEIL))
17768    (use (match_operand:HI 2 "memory_operand" "m"))
17769    (use (match_operand:HI 3 "memory_operand" "m"))
17770    (clobber (match_scratch:XF 4 "=&1f"))]
17771   "TARGET_USE_FANCY_MATH_387
17772    && flag_unsafe_math_optimizations"
17773   "* return output_fix_trunc (insn, operands, 0);"
17774   [(set_attr "type" "fistp")
17775    (set_attr "i387_cw" "ceil")
17776    (set_attr "mode" "DI")])
17777
17778 (define_insn "fistdi2_ceil_with_temp"
17779   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17780         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17781          UNSPEC_FIST_CEIL))
17782    (use (match_operand:HI 2 "memory_operand" "m,m"))
17783    (use (match_operand:HI 3 "memory_operand" "m,m"))
17784    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17785    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17786   "TARGET_USE_FANCY_MATH_387
17787    && flag_unsafe_math_optimizations"
17788   "#"
17789   [(set_attr "type" "fistp")
17790    (set_attr "i387_cw" "ceil")
17791    (set_attr "mode" "DI")])
17792
17793 (define_split
17794   [(set (match_operand:DI 0 "register_operand" "")
17795         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17796          UNSPEC_FIST_CEIL))
17797    (use (match_operand:HI 2 "memory_operand" ""))
17798    (use (match_operand:HI 3 "memory_operand" ""))
17799    (clobber (match_operand:DI 4 "memory_operand" ""))
17800    (clobber (match_scratch 5 ""))]
17801   "reload_completed"
17802   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17803               (use (match_dup 2))
17804               (use (match_dup 3))
17805               (clobber (match_dup 5))])
17806    (set (match_dup 0) (match_dup 4))]
17807   "")
17808
17809 (define_split
17810   [(set (match_operand:DI 0 "memory_operand" "")
17811         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17812          UNSPEC_FIST_CEIL))
17813    (use (match_operand:HI 2 "memory_operand" ""))
17814    (use (match_operand:HI 3 "memory_operand" ""))
17815    (clobber (match_operand:DI 4 "memory_operand" ""))
17816    (clobber (match_scratch 5 ""))]
17817   "reload_completed"
17818   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17819               (use (match_dup 2))
17820               (use (match_dup 3))
17821               (clobber (match_dup 5))])]
17822   "")
17823
17824 (define_insn "fist<mode>2_ceil"
17825   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17826         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17827          UNSPEC_FIST_CEIL))
17828    (use (match_operand:HI 2 "memory_operand" "m"))
17829    (use (match_operand:HI 3 "memory_operand" "m"))]
17830   "TARGET_USE_FANCY_MATH_387
17831    && flag_unsafe_math_optimizations"
17832   "* return output_fix_trunc (insn, operands, 0);"
17833   [(set_attr "type" "fistp")
17834    (set_attr "i387_cw" "ceil")
17835    (set_attr "mode" "<MODE>")])
17836
17837 (define_insn "fist<mode>2_ceil_with_temp"
17838   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17839         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17840          UNSPEC_FIST_CEIL))
17841    (use (match_operand:HI 2 "memory_operand" "m,m"))
17842    (use (match_operand:HI 3 "memory_operand" "m,m"))
17843    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17844   "TARGET_USE_FANCY_MATH_387
17845    && flag_unsafe_math_optimizations"
17846   "#"
17847   [(set_attr "type" "fistp")
17848    (set_attr "i387_cw" "ceil")
17849    (set_attr "mode" "<MODE>")])
17850
17851 (define_split
17852   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17853         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17854          UNSPEC_FIST_CEIL))
17855    (use (match_operand:HI 2 "memory_operand" ""))
17856    (use (match_operand:HI 3 "memory_operand" ""))
17857    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17858   "reload_completed"
17859   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17860                                   UNSPEC_FIST_CEIL))
17861               (use (match_dup 2))
17862               (use (match_dup 3))])
17863    (set (match_dup 0) (match_dup 4))]
17864   "")
17865
17866 (define_split
17867   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17868         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17869          UNSPEC_FIST_CEIL))
17870    (use (match_operand:HI 2 "memory_operand" ""))
17871    (use (match_operand:HI 3 "memory_operand" ""))
17872    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17873   "reload_completed"
17874   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17875                                   UNSPEC_FIST_CEIL))
17876               (use (match_dup 2))
17877               (use (match_dup 3))])]
17878   "")
17879
17880 (define_expand "lceilxf<mode>2"
17881   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17882                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17883                     UNSPEC_FIST_CEIL))
17884               (clobber (reg:CC FLAGS_REG))])]
17885   "TARGET_USE_FANCY_MATH_387
17886    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17887    && flag_unsafe_math_optimizations"
17888   "")
17889
17890 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17891   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17892    (match_operand:MODEF 1 "register_operand" "")]
17893   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17894    && !flag_trapping_math"
17895 {
17896   ix86_expand_lfloorceil (operand0, operand1, false);
17897   DONE;
17898 })
17899
17900 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17901 (define_insn_and_split "frndintxf2_trunc"
17902   [(set (match_operand:XF 0 "register_operand" "")
17903         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17904          UNSPEC_FRNDINT_TRUNC))
17905    (clobber (reg:CC FLAGS_REG))]
17906   "TARGET_USE_FANCY_MATH_387
17907    && flag_unsafe_math_optimizations
17908    && can_create_pseudo_p ()"
17909   "#"
17910   "&& 1"
17911   [(const_int 0)]
17912 {
17913   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17914
17915   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17916   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17917
17918   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17919                                         operands[2], operands[3]));
17920   DONE;
17921 }
17922   [(set_attr "type" "frndint")
17923    (set_attr "i387_cw" "trunc")
17924    (set_attr "mode" "XF")])
17925
17926 (define_insn "frndintxf2_trunc_i387"
17927   [(set (match_operand:XF 0 "register_operand" "=f")
17928         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17929          UNSPEC_FRNDINT_TRUNC))
17930    (use (match_operand:HI 2 "memory_operand" "m"))
17931    (use (match_operand:HI 3 "memory_operand" "m"))]
17932   "TARGET_USE_FANCY_MATH_387
17933    && flag_unsafe_math_optimizations"
17934   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17935   [(set_attr "type" "frndint")
17936    (set_attr "i387_cw" "trunc")
17937    (set_attr "mode" "XF")])
17938
17939 (define_expand "btruncxf2"
17940   [(use (match_operand:XF 0 "register_operand" ""))
17941    (use (match_operand:XF 1 "register_operand" ""))]
17942   "TARGET_USE_FANCY_MATH_387
17943    && flag_unsafe_math_optimizations"
17944 {
17945   if (optimize_insn_for_size_p ())
17946     FAIL;
17947   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17948   DONE;
17949 })
17950
17951 (define_expand "btrunc<mode>2"
17952   [(use (match_operand:MODEF 0 "register_operand" ""))
17953    (use (match_operand:MODEF 1 "register_operand" ""))]
17954   "(TARGET_USE_FANCY_MATH_387
17955     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17956         || TARGET_MIX_SSE_I387)
17957     && flag_unsafe_math_optimizations)
17958    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17959        && !flag_trapping_math)"
17960 {
17961   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17962       && !flag_trapping_math
17963       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17964     {
17965       if (TARGET_ROUND)
17966         emit_insn (gen_sse4_1_round<mode>2
17967                    (operands[0], operands[1], GEN_INT (0x03)));
17968       else if (optimize_insn_for_size_p ())
17969         FAIL;
17970       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17971         ix86_expand_trunc (operand0, operand1);
17972       else
17973         ix86_expand_truncdf_32 (operand0, operand1);
17974     }
17975   else
17976     {
17977       rtx op0, op1;
17978
17979       if (optimize_insn_for_size_p ())
17980         FAIL;
17981
17982       op0 = gen_reg_rtx (XFmode);
17983       op1 = gen_reg_rtx (XFmode);
17984       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17985       emit_insn (gen_frndintxf2_trunc (op0, op1));
17986
17987       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17988     }
17989   DONE;
17990 })
17991
17992 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17993 (define_insn_and_split "frndintxf2_mask_pm"
17994   [(set (match_operand:XF 0 "register_operand" "")
17995         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17996          UNSPEC_FRNDINT_MASK_PM))
17997    (clobber (reg:CC FLAGS_REG))]
17998   "TARGET_USE_FANCY_MATH_387
17999    && flag_unsafe_math_optimizations
18000    && can_create_pseudo_p ()"
18001   "#"
18002   "&& 1"
18003   [(const_int 0)]
18004 {
18005   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18006
18007   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18008   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18009
18010   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18011                                           operands[2], operands[3]));
18012   DONE;
18013 }
18014   [(set_attr "type" "frndint")
18015    (set_attr "i387_cw" "mask_pm")
18016    (set_attr "mode" "XF")])
18017
18018 (define_insn "frndintxf2_mask_pm_i387"
18019   [(set (match_operand:XF 0 "register_operand" "=f")
18020         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18021          UNSPEC_FRNDINT_MASK_PM))
18022    (use (match_operand:HI 2 "memory_operand" "m"))
18023    (use (match_operand:HI 3 "memory_operand" "m"))]
18024   "TARGET_USE_FANCY_MATH_387
18025    && flag_unsafe_math_optimizations"
18026   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18027   [(set_attr "type" "frndint")
18028    (set_attr "i387_cw" "mask_pm")
18029    (set_attr "mode" "XF")])
18030
18031 (define_expand "nearbyintxf2"
18032   [(use (match_operand:XF 0 "register_operand" ""))
18033    (use (match_operand:XF 1 "register_operand" ""))]
18034   "TARGET_USE_FANCY_MATH_387
18035    && flag_unsafe_math_optimizations"
18036 {
18037   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18038
18039   DONE;
18040 })
18041
18042 (define_expand "nearbyint<mode>2"
18043   [(use (match_operand:MODEF 0 "register_operand" ""))
18044    (use (match_operand:MODEF 1 "register_operand" ""))]
18045   "TARGET_USE_FANCY_MATH_387
18046    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18047        || TARGET_MIX_SSE_I387)
18048    && flag_unsafe_math_optimizations"
18049 {
18050   rtx op0 = gen_reg_rtx (XFmode);
18051   rtx op1 = gen_reg_rtx (XFmode);
18052
18053   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18054   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18055
18056   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18057   DONE;
18058 })
18059
18060 (define_insn "fxam<mode>2_i387"
18061   [(set (match_operand:HI 0 "register_operand" "=a")
18062         (unspec:HI
18063           [(match_operand:X87MODEF 1 "register_operand" "f")]
18064           UNSPEC_FXAM))]
18065   "TARGET_USE_FANCY_MATH_387"
18066   "fxam\n\tfnstsw\t%0"
18067   [(set_attr "type" "multi")
18068    (set_attr "length" "4")
18069    (set_attr "unit" "i387")
18070    (set_attr "mode" "<MODE>")])
18071
18072 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18073   [(set (match_operand:HI 0 "register_operand" "")
18074         (unspec:HI
18075           [(match_operand:MODEF 1 "memory_operand" "")]
18076           UNSPEC_FXAM_MEM))]
18077   "TARGET_USE_FANCY_MATH_387
18078    && can_create_pseudo_p ()"
18079   "#"
18080   "&& 1"
18081   [(set (match_dup 2)(match_dup 1))
18082    (set (match_dup 0)
18083         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18084 {
18085   operands[2] = gen_reg_rtx (<MODE>mode);
18086
18087   MEM_VOLATILE_P (operands[1]) = 1;
18088 }
18089   [(set_attr "type" "multi")
18090    (set_attr "unit" "i387")
18091    (set_attr "mode" "<MODE>")])
18092
18093 (define_expand "isinfxf2"
18094   [(use (match_operand:SI 0 "register_operand" ""))
18095    (use (match_operand:XF 1 "register_operand" ""))]
18096   "TARGET_USE_FANCY_MATH_387
18097    && TARGET_C99_FUNCTIONS"
18098 {
18099   rtx mask = GEN_INT (0x45);
18100   rtx val = GEN_INT (0x05);
18101
18102   rtx cond;
18103
18104   rtx scratch = gen_reg_rtx (HImode);
18105   rtx res = gen_reg_rtx (QImode);
18106
18107   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18108
18109   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18110   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18111   cond = gen_rtx_fmt_ee (EQ, QImode,
18112                          gen_rtx_REG (CCmode, FLAGS_REG),
18113                          const0_rtx);
18114   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18115   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18116   DONE;
18117 })
18118
18119 (define_expand "isinf<mode>2"
18120   [(use (match_operand:SI 0 "register_operand" ""))
18121    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18122   "TARGET_USE_FANCY_MATH_387
18123    && TARGET_C99_FUNCTIONS
18124    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18125 {
18126   rtx mask = GEN_INT (0x45);
18127   rtx val = GEN_INT (0x05);
18128
18129   rtx cond;
18130
18131   rtx scratch = gen_reg_rtx (HImode);
18132   rtx res = gen_reg_rtx (QImode);
18133
18134   /* Remove excess precision by forcing value through memory. */
18135   if (memory_operand (operands[1], VOIDmode))
18136     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18137   else
18138     {
18139       enum ix86_stack_slot slot = (virtuals_instantiated
18140                                    ? SLOT_TEMP
18141                                    : SLOT_VIRTUAL);
18142       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18143
18144       emit_move_insn (temp, operands[1]);
18145       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18146     }
18147
18148   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18149   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18150   cond = gen_rtx_fmt_ee (EQ, QImode,
18151                          gen_rtx_REG (CCmode, FLAGS_REG),
18152                          const0_rtx);
18153   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18154   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18155   DONE;
18156 })
18157
18158 (define_expand "signbit<mode>2"
18159   [(use (match_operand:SI 0 "register_operand" ""))
18160    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18161   "TARGET_USE_FANCY_MATH_387
18162    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18163 {
18164   rtx mask = GEN_INT (0x0200);
18165
18166   rtx scratch = gen_reg_rtx (HImode);
18167
18168   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18169   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18170   DONE;
18171 })
18172 \f
18173 ;; Block operation instructions
18174
18175 (define_insn "cld"
18176   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18177   ""
18178   "cld"
18179   [(set_attr "length" "1")
18180    (set_attr "length_immediate" "0")
18181    (set_attr "modrm" "0")])
18182
18183 (define_expand "movmemsi"
18184   [(use (match_operand:BLK 0 "memory_operand" ""))
18185    (use (match_operand:BLK 1 "memory_operand" ""))
18186    (use (match_operand:SI 2 "nonmemory_operand" ""))
18187    (use (match_operand:SI 3 "const_int_operand" ""))
18188    (use (match_operand:SI 4 "const_int_operand" ""))
18189    (use (match_operand:SI 5 "const_int_operand" ""))]
18190   ""
18191 {
18192  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18193                          operands[4], operands[5]))
18194    DONE;
18195  else
18196    FAIL;
18197 })
18198
18199 (define_expand "movmemdi"
18200   [(use (match_operand:BLK 0 "memory_operand" ""))
18201    (use (match_operand:BLK 1 "memory_operand" ""))
18202    (use (match_operand:DI 2 "nonmemory_operand" ""))
18203    (use (match_operand:DI 3 "const_int_operand" ""))
18204    (use (match_operand:SI 4 "const_int_operand" ""))
18205    (use (match_operand:SI 5 "const_int_operand" ""))]
18206   "TARGET_64BIT"
18207 {
18208  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18209                          operands[4], operands[5]))
18210    DONE;
18211  else
18212    FAIL;
18213 })
18214
18215 ;; Most CPUs don't like single string operations
18216 ;; Handle this case here to simplify previous expander.
18217
18218 (define_expand "strmov"
18219   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18220    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18221    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18222               (clobber (reg:CC FLAGS_REG))])
18223    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18224               (clobber (reg:CC FLAGS_REG))])]
18225   ""
18226 {
18227   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18228
18229   /* If .md ever supports :P for Pmode, these can be directly
18230      in the pattern above.  */
18231   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18232   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18233
18234   /* Can't use this if the user has appropriated esi or edi.  */
18235   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18236       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18237     {
18238       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18239                                       operands[2], operands[3],
18240                                       operands[5], operands[6]));
18241       DONE;
18242     }
18243
18244   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18245 })
18246
18247 (define_expand "strmov_singleop"
18248   [(parallel [(set (match_operand 1 "memory_operand" "")
18249                    (match_operand 3 "memory_operand" ""))
18250               (set (match_operand 0 "register_operand" "")
18251                    (match_operand 4 "" ""))
18252               (set (match_operand 2 "register_operand" "")
18253                    (match_operand 5 "" ""))])]
18254   ""
18255   "ix86_current_function_needs_cld = 1;")
18256
18257 (define_insn "*strmovdi_rex_1"
18258   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18259         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18260    (set (match_operand:DI 0 "register_operand" "=D")
18261         (plus:DI (match_dup 2)
18262                  (const_int 8)))
18263    (set (match_operand:DI 1 "register_operand" "=S")
18264         (plus:DI (match_dup 3)
18265                  (const_int 8)))]
18266   "TARGET_64BIT"
18267   "movsq"
18268   [(set_attr "type" "str")
18269    (set_attr "mode" "DI")
18270    (set_attr "memory" "both")])
18271
18272 (define_insn "*strmovsi_1"
18273   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18274         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18275    (set (match_operand:SI 0 "register_operand" "=D")
18276         (plus:SI (match_dup 2)
18277                  (const_int 4)))
18278    (set (match_operand:SI 1 "register_operand" "=S")
18279         (plus:SI (match_dup 3)
18280                  (const_int 4)))]
18281   "!TARGET_64BIT"
18282   "movs{l|d}"
18283   [(set_attr "type" "str")
18284    (set_attr "mode" "SI")
18285    (set_attr "memory" "both")])
18286
18287 (define_insn "*strmovsi_rex_1"
18288   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18289         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18290    (set (match_operand:DI 0 "register_operand" "=D")
18291         (plus:DI (match_dup 2)
18292                  (const_int 4)))
18293    (set (match_operand:DI 1 "register_operand" "=S")
18294         (plus:DI (match_dup 3)
18295                  (const_int 4)))]
18296   "TARGET_64BIT"
18297   "movs{l|d}"
18298   [(set_attr "type" "str")
18299    (set_attr "mode" "SI")
18300    (set_attr "memory" "both")])
18301
18302 (define_insn "*strmovhi_1"
18303   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18304         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18305    (set (match_operand:SI 0 "register_operand" "=D")
18306         (plus:SI (match_dup 2)
18307                  (const_int 2)))
18308    (set (match_operand:SI 1 "register_operand" "=S")
18309         (plus:SI (match_dup 3)
18310                  (const_int 2)))]
18311   "!TARGET_64BIT"
18312   "movsw"
18313   [(set_attr "type" "str")
18314    (set_attr "memory" "both")
18315    (set_attr "mode" "HI")])
18316
18317 (define_insn "*strmovhi_rex_1"
18318   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18319         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18320    (set (match_operand:DI 0 "register_operand" "=D")
18321         (plus:DI (match_dup 2)
18322                  (const_int 2)))
18323    (set (match_operand:DI 1 "register_operand" "=S")
18324         (plus:DI (match_dup 3)
18325                  (const_int 2)))]
18326   "TARGET_64BIT"
18327   "movsw"
18328   [(set_attr "type" "str")
18329    (set_attr "memory" "both")
18330    (set_attr "mode" "HI")])
18331
18332 (define_insn "*strmovqi_1"
18333   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18334         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18335    (set (match_operand:SI 0 "register_operand" "=D")
18336         (plus:SI (match_dup 2)
18337                  (const_int 1)))
18338    (set (match_operand:SI 1 "register_operand" "=S")
18339         (plus:SI (match_dup 3)
18340                  (const_int 1)))]
18341   "!TARGET_64BIT"
18342   "movsb"
18343   [(set_attr "type" "str")
18344    (set_attr "memory" "both")
18345    (set_attr "mode" "QI")])
18346
18347 (define_insn "*strmovqi_rex_1"
18348   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18349         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18350    (set (match_operand:DI 0 "register_operand" "=D")
18351         (plus:DI (match_dup 2)
18352                  (const_int 1)))
18353    (set (match_operand:DI 1 "register_operand" "=S")
18354         (plus:DI (match_dup 3)
18355                  (const_int 1)))]
18356   "TARGET_64BIT"
18357   "movsb"
18358   [(set_attr "type" "str")
18359    (set_attr "memory" "both")
18360    (set_attr "prefix_rex" "0")
18361    (set_attr "mode" "QI")])
18362
18363 (define_expand "rep_mov"
18364   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18365               (set (match_operand 0 "register_operand" "")
18366                    (match_operand 5 "" ""))
18367               (set (match_operand 2 "register_operand" "")
18368                    (match_operand 6 "" ""))
18369               (set (match_operand 1 "memory_operand" "")
18370                    (match_operand 3 "memory_operand" ""))
18371               (use (match_dup 4))])]
18372   ""
18373   "ix86_current_function_needs_cld = 1;")
18374
18375 (define_insn "*rep_movdi_rex64"
18376   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18377    (set (match_operand:DI 0 "register_operand" "=D")
18378         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18379                             (const_int 3))
18380                  (match_operand:DI 3 "register_operand" "0")))
18381    (set (match_operand:DI 1 "register_operand" "=S")
18382         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18383                  (match_operand:DI 4 "register_operand" "1")))
18384    (set (mem:BLK (match_dup 3))
18385         (mem:BLK (match_dup 4)))
18386    (use (match_dup 5))]
18387   "TARGET_64BIT"
18388   "rep movsq"
18389   [(set_attr "type" "str")
18390    (set_attr "prefix_rep" "1")
18391    (set_attr "memory" "both")
18392    (set_attr "mode" "DI")])
18393
18394 (define_insn "*rep_movsi"
18395   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18396    (set (match_operand:SI 0 "register_operand" "=D")
18397         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18398                             (const_int 2))
18399                  (match_operand:SI 3 "register_operand" "0")))
18400    (set (match_operand:SI 1 "register_operand" "=S")
18401         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18402                  (match_operand:SI 4 "register_operand" "1")))
18403    (set (mem:BLK (match_dup 3))
18404         (mem:BLK (match_dup 4)))
18405    (use (match_dup 5))]
18406   "!TARGET_64BIT"
18407   "rep movs{l|d}"
18408   [(set_attr "type" "str")
18409    (set_attr "prefix_rep" "1")
18410    (set_attr "memory" "both")
18411    (set_attr "mode" "SI")])
18412
18413 (define_insn "*rep_movsi_rex64"
18414   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18415    (set (match_operand:DI 0 "register_operand" "=D")
18416         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18417                             (const_int 2))
18418                  (match_operand:DI 3 "register_operand" "0")))
18419    (set (match_operand:DI 1 "register_operand" "=S")
18420         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18421                  (match_operand:DI 4 "register_operand" "1")))
18422    (set (mem:BLK (match_dup 3))
18423         (mem:BLK (match_dup 4)))
18424    (use (match_dup 5))]
18425   "TARGET_64BIT"
18426   "rep movs{l|d}"
18427   [(set_attr "type" "str")
18428    (set_attr "prefix_rep" "1")
18429    (set_attr "memory" "both")
18430    (set_attr "mode" "SI")])
18431
18432 (define_insn "*rep_movqi"
18433   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18434    (set (match_operand:SI 0 "register_operand" "=D")
18435         (plus:SI (match_operand:SI 3 "register_operand" "0")
18436                  (match_operand:SI 5 "register_operand" "2")))
18437    (set (match_operand:SI 1 "register_operand" "=S")
18438         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18439    (set (mem:BLK (match_dup 3))
18440         (mem:BLK (match_dup 4)))
18441    (use (match_dup 5))]
18442   "!TARGET_64BIT"
18443   "rep movsb"
18444   [(set_attr "type" "str")
18445    (set_attr "prefix_rep" "1")
18446    (set_attr "memory" "both")
18447    (set_attr "mode" "SI")])
18448
18449 (define_insn "*rep_movqi_rex64"
18450   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18451    (set (match_operand:DI 0 "register_operand" "=D")
18452         (plus:DI (match_operand:DI 3 "register_operand" "0")
18453                  (match_operand:DI 5 "register_operand" "2")))
18454    (set (match_operand:DI 1 "register_operand" "=S")
18455         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18456    (set (mem:BLK (match_dup 3))
18457         (mem:BLK (match_dup 4)))
18458    (use (match_dup 5))]
18459   "TARGET_64BIT"
18460   "rep movsb"
18461   [(set_attr "type" "str")
18462    (set_attr "prefix_rep" "1")
18463    (set_attr "memory" "both")
18464    (set_attr "mode" "SI")])
18465
18466 (define_expand "setmemsi"
18467    [(use (match_operand:BLK 0 "memory_operand" ""))
18468     (use (match_operand:SI 1 "nonmemory_operand" ""))
18469     (use (match_operand 2 "const_int_operand" ""))
18470     (use (match_operand 3 "const_int_operand" ""))
18471     (use (match_operand:SI 4 "const_int_operand" ""))
18472     (use (match_operand:SI 5 "const_int_operand" ""))]
18473   ""
18474 {
18475  if (ix86_expand_setmem (operands[0], operands[1],
18476                          operands[2], operands[3],
18477                          operands[4], operands[5]))
18478    DONE;
18479  else
18480    FAIL;
18481 })
18482
18483 (define_expand "setmemdi"
18484    [(use (match_operand:BLK 0 "memory_operand" ""))
18485     (use (match_operand:DI 1 "nonmemory_operand" ""))
18486     (use (match_operand 2 "const_int_operand" ""))
18487     (use (match_operand 3 "const_int_operand" ""))
18488     (use (match_operand 4 "const_int_operand" ""))
18489     (use (match_operand 5 "const_int_operand" ""))]
18490   "TARGET_64BIT"
18491 {
18492  if (ix86_expand_setmem (operands[0], operands[1],
18493                          operands[2], operands[3],
18494                          operands[4], operands[5]))
18495    DONE;
18496  else
18497    FAIL;
18498 })
18499
18500 ;; Most CPUs don't like single string operations
18501 ;; Handle this case here to simplify previous expander.
18502
18503 (define_expand "strset"
18504   [(set (match_operand 1 "memory_operand" "")
18505         (match_operand 2 "register_operand" ""))
18506    (parallel [(set (match_operand 0 "register_operand" "")
18507                    (match_dup 3))
18508               (clobber (reg:CC FLAGS_REG))])]
18509   ""
18510 {
18511   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18512     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18513
18514   /* If .md ever supports :P for Pmode, this can be directly
18515      in the pattern above.  */
18516   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18517                               GEN_INT (GET_MODE_SIZE (GET_MODE
18518                                                       (operands[2]))));
18519   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18520     {
18521       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18522                                       operands[3]));
18523       DONE;
18524     }
18525 })
18526
18527 (define_expand "strset_singleop"
18528   [(parallel [(set (match_operand 1 "memory_operand" "")
18529                    (match_operand 2 "register_operand" ""))
18530               (set (match_operand 0 "register_operand" "")
18531                    (match_operand 3 "" ""))])]
18532   ""
18533   "ix86_current_function_needs_cld = 1;")
18534
18535 (define_insn "*strsetdi_rex_1"
18536   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18537         (match_operand:DI 2 "register_operand" "a"))
18538    (set (match_operand:DI 0 "register_operand" "=D")
18539         (plus:DI (match_dup 1)
18540                  (const_int 8)))]
18541   "TARGET_64BIT"
18542   "stosq"
18543   [(set_attr "type" "str")
18544    (set_attr "memory" "store")
18545    (set_attr "mode" "DI")])
18546
18547 (define_insn "*strsetsi_1"
18548   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18549         (match_operand:SI 2 "register_operand" "a"))
18550    (set (match_operand:SI 0 "register_operand" "=D")
18551         (plus:SI (match_dup 1)
18552                  (const_int 4)))]
18553   "!TARGET_64BIT"
18554   "stos{l|d}"
18555   [(set_attr "type" "str")
18556    (set_attr "memory" "store")
18557    (set_attr "mode" "SI")])
18558
18559 (define_insn "*strsetsi_rex_1"
18560   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18561         (match_operand:SI 2 "register_operand" "a"))
18562    (set (match_operand:DI 0 "register_operand" "=D")
18563         (plus:DI (match_dup 1)
18564                  (const_int 4)))]
18565   "TARGET_64BIT"
18566   "stos{l|d}"
18567   [(set_attr "type" "str")
18568    (set_attr "memory" "store")
18569    (set_attr "mode" "SI")])
18570
18571 (define_insn "*strsethi_1"
18572   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18573         (match_operand:HI 2 "register_operand" "a"))
18574    (set (match_operand:SI 0 "register_operand" "=D")
18575         (plus:SI (match_dup 1)
18576                  (const_int 2)))]
18577   "!TARGET_64BIT"
18578   "stosw"
18579   [(set_attr "type" "str")
18580    (set_attr "memory" "store")
18581    (set_attr "mode" "HI")])
18582
18583 (define_insn "*strsethi_rex_1"
18584   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18585         (match_operand:HI 2 "register_operand" "a"))
18586    (set (match_operand:DI 0 "register_operand" "=D")
18587         (plus:DI (match_dup 1)
18588                  (const_int 2)))]
18589   "TARGET_64BIT"
18590   "stosw"
18591   [(set_attr "type" "str")
18592    (set_attr "memory" "store")
18593    (set_attr "mode" "HI")])
18594
18595 (define_insn "*strsetqi_1"
18596   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18597         (match_operand:QI 2 "register_operand" "a"))
18598    (set (match_operand:SI 0 "register_operand" "=D")
18599         (plus:SI (match_dup 1)
18600                  (const_int 1)))]
18601   "!TARGET_64BIT"
18602   "stosb"
18603   [(set_attr "type" "str")
18604    (set_attr "memory" "store")
18605    (set_attr "mode" "QI")])
18606
18607 (define_insn "*strsetqi_rex_1"
18608   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18609         (match_operand:QI 2 "register_operand" "a"))
18610    (set (match_operand:DI 0 "register_operand" "=D")
18611         (plus:DI (match_dup 1)
18612                  (const_int 1)))]
18613   "TARGET_64BIT"
18614   "stosb"
18615   [(set_attr "type" "str")
18616    (set_attr "memory" "store")
18617    (set_attr "prefix_rex" "0")
18618    (set_attr "mode" "QI")])
18619
18620 (define_expand "rep_stos"
18621   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18622               (set (match_operand 0 "register_operand" "")
18623                    (match_operand 4 "" ""))
18624               (set (match_operand 2 "memory_operand" "") (const_int 0))
18625               (use (match_operand 3 "register_operand" ""))
18626               (use (match_dup 1))])]
18627   ""
18628   "ix86_current_function_needs_cld = 1;")
18629
18630 (define_insn "*rep_stosdi_rex64"
18631   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18632    (set (match_operand:DI 0 "register_operand" "=D")
18633         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18634                             (const_int 3))
18635                  (match_operand:DI 3 "register_operand" "0")))
18636    (set (mem:BLK (match_dup 3))
18637         (const_int 0))
18638    (use (match_operand:DI 2 "register_operand" "a"))
18639    (use (match_dup 4))]
18640   "TARGET_64BIT"
18641   "rep stosq"
18642   [(set_attr "type" "str")
18643    (set_attr "prefix_rep" "1")
18644    (set_attr "memory" "store")
18645    (set_attr "mode" "DI")])
18646
18647 (define_insn "*rep_stossi"
18648   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18649    (set (match_operand:SI 0 "register_operand" "=D")
18650         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18651                             (const_int 2))
18652                  (match_operand:SI 3 "register_operand" "0")))
18653    (set (mem:BLK (match_dup 3))
18654         (const_int 0))
18655    (use (match_operand:SI 2 "register_operand" "a"))
18656    (use (match_dup 4))]
18657   "!TARGET_64BIT"
18658   "rep stos{l|d}"
18659   [(set_attr "type" "str")
18660    (set_attr "prefix_rep" "1")
18661    (set_attr "memory" "store")
18662    (set_attr "mode" "SI")])
18663
18664 (define_insn "*rep_stossi_rex64"
18665   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18666    (set (match_operand:DI 0 "register_operand" "=D")
18667         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18668                             (const_int 2))
18669                  (match_operand:DI 3 "register_operand" "0")))
18670    (set (mem:BLK (match_dup 3))
18671         (const_int 0))
18672    (use (match_operand:SI 2 "register_operand" "a"))
18673    (use (match_dup 4))]
18674   "TARGET_64BIT"
18675   "rep stos{l|d}"
18676   [(set_attr "type" "str")
18677    (set_attr "prefix_rep" "1")
18678    (set_attr "memory" "store")
18679    (set_attr "mode" "SI")])
18680
18681 (define_insn "*rep_stosqi"
18682   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18683    (set (match_operand:SI 0 "register_operand" "=D")
18684         (plus:SI (match_operand:SI 3 "register_operand" "0")
18685                  (match_operand:SI 4 "register_operand" "1")))
18686    (set (mem:BLK (match_dup 3))
18687         (const_int 0))
18688    (use (match_operand:QI 2 "register_operand" "a"))
18689    (use (match_dup 4))]
18690   "!TARGET_64BIT"
18691   "rep stosb"
18692   [(set_attr "type" "str")
18693    (set_attr "prefix_rep" "1")
18694    (set_attr "memory" "store")
18695    (set_attr "mode" "QI")])
18696
18697 (define_insn "*rep_stosqi_rex64"
18698   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18699    (set (match_operand:DI 0 "register_operand" "=D")
18700         (plus:DI (match_operand:DI 3 "register_operand" "0")
18701                  (match_operand:DI 4 "register_operand" "1")))
18702    (set (mem:BLK (match_dup 3))
18703         (const_int 0))
18704    (use (match_operand:QI 2 "register_operand" "a"))
18705    (use (match_dup 4))]
18706   "TARGET_64BIT"
18707   "rep stosb"
18708   [(set_attr "type" "str")
18709    (set_attr "prefix_rep" "1")
18710    (set_attr "memory" "store")
18711    (set_attr "prefix_rex" "0")
18712    (set_attr "mode" "QI")])
18713
18714 (define_expand "cmpstrnsi"
18715   [(set (match_operand:SI 0 "register_operand" "")
18716         (compare:SI (match_operand:BLK 1 "general_operand" "")
18717                     (match_operand:BLK 2 "general_operand" "")))
18718    (use (match_operand 3 "general_operand" ""))
18719    (use (match_operand 4 "immediate_operand" ""))]
18720   ""
18721 {
18722   rtx addr1, addr2, out, outlow, count, countreg, align;
18723
18724   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18725     FAIL;
18726
18727   /* Can't use this if the user has appropriated esi or edi.  */
18728   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18729     FAIL;
18730
18731   out = operands[0];
18732   if (!REG_P (out))
18733     out = gen_reg_rtx (SImode);
18734
18735   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18736   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18737   if (addr1 != XEXP (operands[1], 0))
18738     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18739   if (addr2 != XEXP (operands[2], 0))
18740     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18741
18742   count = operands[3];
18743   countreg = ix86_zero_extend_to_Pmode (count);
18744
18745   /* %%% Iff we are testing strict equality, we can use known alignment
18746      to good advantage.  This may be possible with combine, particularly
18747      once cc0 is dead.  */
18748   align = operands[4];
18749
18750   if (CONST_INT_P (count))
18751     {
18752       if (INTVAL (count) == 0)
18753         {
18754           emit_move_insn (operands[0], const0_rtx);
18755           DONE;
18756         }
18757       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18758                                      operands[1], operands[2]));
18759     }
18760   else
18761     {
18762       rtx (*cmp_insn)(rtx, rtx);
18763
18764       if (TARGET_64BIT)
18765         cmp_insn = gen_cmpdi_1;
18766       else
18767         cmp_insn = gen_cmpsi_1;
18768       emit_insn (cmp_insn (countreg, countreg));
18769       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18770                                   operands[1], operands[2]));
18771     }
18772
18773   outlow = gen_lowpart (QImode, out);
18774   emit_insn (gen_cmpintqi (outlow));
18775   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18776
18777   if (operands[0] != out)
18778     emit_move_insn (operands[0], out);
18779
18780   DONE;
18781 })
18782
18783 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18784
18785 (define_expand "cmpintqi"
18786   [(set (match_dup 1)
18787         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18788    (set (match_dup 2)
18789         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18790    (parallel [(set (match_operand:QI 0 "register_operand" "")
18791                    (minus:QI (match_dup 1)
18792                              (match_dup 2)))
18793               (clobber (reg:CC FLAGS_REG))])]
18794   ""
18795   "operands[1] = gen_reg_rtx (QImode);
18796    operands[2] = gen_reg_rtx (QImode);")
18797
18798 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18799 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18800
18801 (define_expand "cmpstrnqi_nz_1"
18802   [(parallel [(set (reg:CC FLAGS_REG)
18803                    (compare:CC (match_operand 4 "memory_operand" "")
18804                                (match_operand 5 "memory_operand" "")))
18805               (use (match_operand 2 "register_operand" ""))
18806               (use (match_operand:SI 3 "immediate_operand" ""))
18807               (clobber (match_operand 0 "register_operand" ""))
18808               (clobber (match_operand 1 "register_operand" ""))
18809               (clobber (match_dup 2))])]
18810   ""
18811   "ix86_current_function_needs_cld = 1;")
18812
18813 (define_insn "*cmpstrnqi_nz_1"
18814   [(set (reg:CC FLAGS_REG)
18815         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18816                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18817    (use (match_operand:SI 6 "register_operand" "2"))
18818    (use (match_operand:SI 3 "immediate_operand" "i"))
18819    (clobber (match_operand:SI 0 "register_operand" "=S"))
18820    (clobber (match_operand:SI 1 "register_operand" "=D"))
18821    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18822   "!TARGET_64BIT"
18823   "repz cmpsb"
18824   [(set_attr "type" "str")
18825    (set_attr "mode" "QI")
18826    (set_attr "prefix_rep" "1")])
18827
18828 (define_insn "*cmpstrnqi_nz_rex_1"
18829   [(set (reg:CC FLAGS_REG)
18830         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18831                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18832    (use (match_operand:DI 6 "register_operand" "2"))
18833    (use (match_operand:SI 3 "immediate_operand" "i"))
18834    (clobber (match_operand:DI 0 "register_operand" "=S"))
18835    (clobber (match_operand:DI 1 "register_operand" "=D"))
18836    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18837   "TARGET_64BIT"
18838   "repz cmpsb"
18839   [(set_attr "type" "str")
18840    (set_attr "mode" "QI")
18841    (set_attr "prefix_rex" "0")
18842    (set_attr "prefix_rep" "1")])
18843
18844 ;; The same, but the count is not known to not be zero.
18845
18846 (define_expand "cmpstrnqi_1"
18847   [(parallel [(set (reg:CC FLAGS_REG)
18848                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18849                                      (const_int 0))
18850                   (compare:CC (match_operand 4 "memory_operand" "")
18851                               (match_operand 5 "memory_operand" ""))
18852                   (const_int 0)))
18853               (use (match_operand:SI 3 "immediate_operand" ""))
18854               (use (reg:CC FLAGS_REG))
18855               (clobber (match_operand 0 "register_operand" ""))
18856               (clobber (match_operand 1 "register_operand" ""))
18857               (clobber (match_dup 2))])]
18858   ""
18859   "ix86_current_function_needs_cld = 1;")
18860
18861 (define_insn "*cmpstrnqi_1"
18862   [(set (reg:CC FLAGS_REG)
18863         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18864                              (const_int 0))
18865           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18866                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18867           (const_int 0)))
18868    (use (match_operand:SI 3 "immediate_operand" "i"))
18869    (use (reg:CC FLAGS_REG))
18870    (clobber (match_operand:SI 0 "register_operand" "=S"))
18871    (clobber (match_operand:SI 1 "register_operand" "=D"))
18872    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18873   "!TARGET_64BIT"
18874   "repz cmpsb"
18875   [(set_attr "type" "str")
18876    (set_attr "mode" "QI")
18877    (set_attr "prefix_rep" "1")])
18878
18879 (define_insn "*cmpstrnqi_rex_1"
18880   [(set (reg:CC FLAGS_REG)
18881         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18882                              (const_int 0))
18883           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18884                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18885           (const_int 0)))
18886    (use (match_operand:SI 3 "immediate_operand" "i"))
18887    (use (reg:CC FLAGS_REG))
18888    (clobber (match_operand:DI 0 "register_operand" "=S"))
18889    (clobber (match_operand:DI 1 "register_operand" "=D"))
18890    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18891   "TARGET_64BIT"
18892   "repz cmpsb"
18893   [(set_attr "type" "str")
18894    (set_attr "mode" "QI")
18895    (set_attr "prefix_rex" "0")
18896    (set_attr "prefix_rep" "1")])
18897
18898 (define_expand "strlensi"
18899   [(set (match_operand:SI 0 "register_operand" "")
18900         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18901                     (match_operand:QI 2 "immediate_operand" "")
18902                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18903   ""
18904 {
18905  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18906    DONE;
18907  else
18908    FAIL;
18909 })
18910
18911 (define_expand "strlendi"
18912   [(set (match_operand:DI 0 "register_operand" "")
18913         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18914                     (match_operand:QI 2 "immediate_operand" "")
18915                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18916   ""
18917 {
18918  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18919    DONE;
18920  else
18921    FAIL;
18922 })
18923
18924 (define_expand "strlenqi_1"
18925   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18926               (clobber (match_operand 1 "register_operand" ""))
18927               (clobber (reg:CC FLAGS_REG))])]
18928   ""
18929   "ix86_current_function_needs_cld = 1;")
18930
18931 (define_insn "*strlenqi_1"
18932   [(set (match_operand:SI 0 "register_operand" "=&c")
18933         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18934                     (match_operand:QI 2 "register_operand" "a")
18935                     (match_operand:SI 3 "immediate_operand" "i")
18936                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18937    (clobber (match_operand:SI 1 "register_operand" "=D"))
18938    (clobber (reg:CC FLAGS_REG))]
18939   "!TARGET_64BIT"
18940   "repnz scasb"
18941   [(set_attr "type" "str")
18942    (set_attr "mode" "QI")
18943    (set_attr "prefix_rep" "1")])
18944
18945 (define_insn "*strlenqi_rex_1"
18946   [(set (match_operand:DI 0 "register_operand" "=&c")
18947         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18948                     (match_operand:QI 2 "register_operand" "a")
18949                     (match_operand:DI 3 "immediate_operand" "i")
18950                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18951    (clobber (match_operand:DI 1 "register_operand" "=D"))
18952    (clobber (reg:CC FLAGS_REG))]
18953   "TARGET_64BIT"
18954   "repnz scasb"
18955   [(set_attr "type" "str")
18956    (set_attr "mode" "QI")
18957    (set_attr "prefix_rex" "0")
18958    (set_attr "prefix_rep" "1")])
18959
18960 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18961 ;; handled in combine, but it is not currently up to the task.
18962 ;; When used for their truth value, the cmpstrn* expanders generate
18963 ;; code like this:
18964 ;;
18965 ;;   repz cmpsb
18966 ;;   seta       %al
18967 ;;   setb       %dl
18968 ;;   cmpb       %al, %dl
18969 ;;   jcc        label
18970 ;;
18971 ;; The intermediate three instructions are unnecessary.
18972
18973 ;; This one handles cmpstrn*_nz_1...
18974 (define_peephole2
18975   [(parallel[
18976      (set (reg:CC FLAGS_REG)
18977           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18978                       (mem:BLK (match_operand 5 "register_operand" ""))))
18979      (use (match_operand 6 "register_operand" ""))
18980      (use (match_operand:SI 3 "immediate_operand" ""))
18981      (clobber (match_operand 0 "register_operand" ""))
18982      (clobber (match_operand 1 "register_operand" ""))
18983      (clobber (match_operand 2 "register_operand" ""))])
18984    (set (match_operand:QI 7 "register_operand" "")
18985         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18986    (set (match_operand:QI 8 "register_operand" "")
18987         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18988    (set (reg FLAGS_REG)
18989         (compare (match_dup 7) (match_dup 8)))
18990   ]
18991   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18992   [(parallel[
18993      (set (reg:CC FLAGS_REG)
18994           (compare:CC (mem:BLK (match_dup 4))
18995                       (mem:BLK (match_dup 5))))
18996      (use (match_dup 6))
18997      (use (match_dup 3))
18998      (clobber (match_dup 0))
18999      (clobber (match_dup 1))
19000      (clobber (match_dup 2))])]
19001   "")
19002
19003 ;; ...and this one handles cmpstrn*_1.
19004 (define_peephole2
19005   [(parallel[
19006      (set (reg:CC FLAGS_REG)
19007           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19008                                (const_int 0))
19009             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19010                         (mem:BLK (match_operand 5 "register_operand" "")))
19011             (const_int 0)))
19012      (use (match_operand:SI 3 "immediate_operand" ""))
19013      (use (reg:CC FLAGS_REG))
19014      (clobber (match_operand 0 "register_operand" ""))
19015      (clobber (match_operand 1 "register_operand" ""))
19016      (clobber (match_operand 2 "register_operand" ""))])
19017    (set (match_operand:QI 7 "register_operand" "")
19018         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19019    (set (match_operand:QI 8 "register_operand" "")
19020         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19021    (set (reg FLAGS_REG)
19022         (compare (match_dup 7) (match_dup 8)))
19023   ]
19024   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19025   [(parallel[
19026      (set (reg:CC FLAGS_REG)
19027           (if_then_else:CC (ne (match_dup 6)
19028                                (const_int 0))
19029             (compare:CC (mem:BLK (match_dup 4))
19030                         (mem:BLK (match_dup 5)))
19031             (const_int 0)))
19032      (use (match_dup 3))
19033      (use (reg:CC FLAGS_REG))
19034      (clobber (match_dup 0))
19035      (clobber (match_dup 1))
19036      (clobber (match_dup 2))])]
19037   "")
19038
19039
19040 \f
19041 ;; Conditional move instructions.
19042
19043 (define_expand "mov<mode>cc"
19044   [(set (match_operand:SWIM 0 "register_operand" "")
19045         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
19046                            (match_operand:SWIM 2 "general_operand" "")
19047                            (match_operand:SWIM 3 "general_operand" "")))]
19048   ""
19049   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19050
19051 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19052 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19053 ;; So just document what we're doing explicitly.
19054
19055 (define_expand "x86_mov<mode>cc_0_m1"
19056   [(parallel
19057     [(set (match_operand:SWI48 0 "register_operand" "")
19058           (if_then_else:SWI48
19059             (match_operator:SWI48 2 "ix86_carry_flag_operator"
19060              [(match_operand 1 "flags_reg_operand" "")
19061               (const_int 0)])
19062             (const_int -1)
19063             (const_int 0)))
19064      (clobber (reg:CC FLAGS_REG))])]
19065   ""
19066   "")
19067
19068 (define_insn "*x86_mov<mode>cc_0_m1"
19069   [(set (match_operand:SWI48 0 "register_operand" "=r")
19070         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19071                              [(reg FLAGS_REG) (const_int 0)])
19072           (const_int -1)
19073           (const_int 0)))
19074    (clobber (reg:CC FLAGS_REG))]
19075   ""
19076   "sbb{<imodesuffix>}\t%0, %0"
19077   ; Since we don't have the proper number of operands for an alu insn,
19078   ; fill in all the blanks.
19079   [(set_attr "type" "alu")
19080    (set_attr "use_carry" "1")
19081    (set_attr "pent_pair" "pu")
19082    (set_attr "memory" "none")
19083    (set_attr "imm_disp" "false")
19084    (set_attr "mode" "<MODE>")
19085    (set_attr "length_immediate" "0")])
19086
19087 (define_insn "*x86_mov<mode>cc_0_m1_se"
19088   [(set (match_operand:SWI48 0 "register_operand" "=r")
19089         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19090                              [(reg FLAGS_REG) (const_int 0)])
19091                             (const_int 1)
19092                             (const_int 0)))
19093    (clobber (reg:CC FLAGS_REG))]
19094   ""
19095   "sbb{<imodesuffix>}\t%0, %0"
19096   [(set_attr "type" "alu")
19097    (set_attr "use_carry" "1")
19098    (set_attr "pent_pair" "pu")
19099    (set_attr "memory" "none")
19100    (set_attr "imm_disp" "false")
19101    (set_attr "mode" "<MODE>")
19102    (set_attr "length_immediate" "0")])
19103
19104 (define_insn "*x86_mov<mode>cc_0_m1_neg"
19105   [(set (match_operand:SWI48 0 "register_operand" "=r")
19106         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19107                     [(reg FLAGS_REG) (const_int 0)])))]
19108   ""
19109   "sbb{<imodesuffix>}\t%0, %0"
19110   [(set_attr "type" "alu")
19111    (set_attr "use_carry" "1")
19112    (set_attr "pent_pair" "pu")
19113    (set_attr "memory" "none")
19114    (set_attr "imm_disp" "false")
19115    (set_attr "mode" "<MODE>")
19116    (set_attr "length_immediate" "0")])
19117
19118 (define_insn "*mov<mode>cc_noc"
19119   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
19120         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
19121                                [(reg FLAGS_REG) (const_int 0)])
19122           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
19123           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
19124   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19125   "@
19126    cmov%O2%C1\t{%2, %0|%0, %2}
19127    cmov%O2%c1\t{%3, %0|%0, %3}"
19128   [(set_attr "type" "icmov")
19129    (set_attr "mode" "<MODE>")])
19130
19131 (define_insn_and_split "*movqicc_noc"
19132   [(set (match_operand:QI 0 "register_operand" "=r,r")
19133         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19134                            [(match_operand 4 "flags_reg_operand" "")
19135                             (const_int 0)])
19136                       (match_operand:QI 2 "register_operand" "r,0")
19137                       (match_operand:QI 3 "register_operand" "0,r")))]
19138   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19139   "#"
19140   "&& reload_completed"
19141   [(set (match_dup 0)
19142         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19143                       (match_dup 2)
19144                       (match_dup 3)))]
19145   "operands[0] = gen_lowpart (SImode, operands[0]);
19146    operands[2] = gen_lowpart (SImode, operands[2]);
19147    operands[3] = gen_lowpart (SImode, operands[3]);"
19148   [(set_attr "type" "icmov")
19149    (set_attr "mode" "SI")])
19150
19151 (define_expand "mov<mode>cc"
19152   [(set (match_operand:X87MODEF 0 "register_operand" "")
19153         (if_then_else:X87MODEF
19154           (match_operand 1 "ix86_fp_comparison_operator" "")
19155           (match_operand:X87MODEF 2 "register_operand" "")
19156           (match_operand:X87MODEF 3 "register_operand" "")))]
19157   "(TARGET_80387 && TARGET_CMOVE)
19158    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19159   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19160
19161 (define_insn "*movsfcc_1_387"
19162   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19163         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19164                                 [(reg FLAGS_REG) (const_int 0)])
19165                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19166                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19167   "TARGET_80387 && TARGET_CMOVE
19168    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19169   "@
19170    fcmov%F1\t{%2, %0|%0, %2}
19171    fcmov%f1\t{%3, %0|%0, %3}
19172    cmov%O2%C1\t{%2, %0|%0, %2}
19173    cmov%O2%c1\t{%3, %0|%0, %3}"
19174   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19175    (set_attr "mode" "SF,SF,SI,SI")])
19176
19177 (define_insn "*movdfcc_1"
19178   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19179         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19180                                 [(reg FLAGS_REG) (const_int 0)])
19181                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19182                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19183   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19184    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19185   "@
19186    fcmov%F1\t{%2, %0|%0, %2}
19187    fcmov%f1\t{%3, %0|%0, %3}
19188    #
19189    #"
19190   [(set_attr "type" "fcmov,fcmov,multi,multi")
19191    (set_attr "mode" "DF")])
19192
19193 (define_insn "*movdfcc_1_rex64"
19194   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19195         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19196                                 [(reg FLAGS_REG) (const_int 0)])
19197                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19198                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19199   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19200    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19201   "@
19202    fcmov%F1\t{%2, %0|%0, %2}
19203    fcmov%f1\t{%3, %0|%0, %3}
19204    cmov%O2%C1\t{%2, %0|%0, %2}
19205    cmov%O2%c1\t{%3, %0|%0, %3}"
19206   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19207    (set_attr "mode" "DF")])
19208
19209 (define_split
19210   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19211         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19212                                 [(match_operand 4 "flags_reg_operand" "")
19213                                  (const_int 0)])
19214                       (match_operand:DF 2 "nonimmediate_operand" "")
19215                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19216   "!TARGET_64BIT && reload_completed"
19217   [(set (match_dup 2)
19218         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19219                       (match_dup 5)
19220                       (match_dup 6)))
19221    (set (match_dup 3)
19222         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19223                       (match_dup 7)
19224                       (match_dup 8)))]
19225   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19226    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19227
19228 (define_insn "*movxfcc_1"
19229   [(set (match_operand:XF 0 "register_operand" "=f,f")
19230         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19231                                 [(reg FLAGS_REG) (const_int 0)])
19232                       (match_operand:XF 2 "register_operand" "f,0")
19233                       (match_operand:XF 3 "register_operand" "0,f")))]
19234   "TARGET_80387 && TARGET_CMOVE"
19235   "@
19236    fcmov%F1\t{%2, %0|%0, %2}
19237    fcmov%f1\t{%3, %0|%0, %3}"
19238   [(set_attr "type" "fcmov")
19239    (set_attr "mode" "XF")])
19240
19241 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
19242 ;; the scalar versions to have only XMM registers as operands.
19243
19244 ;; XOP conditional move
19245 (define_insn "*xop_pcmov_<mode>"
19246   [(set (match_operand:MODEF 0 "register_operand" "=x")
19247         (if_then_else:MODEF
19248           (match_operand:MODEF 1 "register_operand" "x")
19249           (match_operand:MODEF 2 "register_operand" "x")
19250           (match_operand:MODEF 3 "register_operand" "x")))]
19251   "TARGET_XOP"
19252   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19253   [(set_attr "type" "sse4arg")])
19254
19255 ;; These versions of the min/max patterns are intentionally ignorant of
19256 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19257 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19258 ;; are undefined in this condition, we're certain this is correct.
19259
19260 (define_insn "*avx_<code><mode>3"
19261   [(set (match_operand:MODEF 0 "register_operand" "=x")
19262         (smaxmin:MODEF
19263           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19264           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19265   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19266   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19267   [(set_attr "type" "sseadd")
19268    (set_attr "prefix" "vex")
19269    (set_attr "mode" "<MODE>")])
19270
19271 (define_insn "<code><mode>3"
19272   [(set (match_operand:MODEF 0 "register_operand" "=x")
19273         (smaxmin:MODEF
19274           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19275           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19276   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19277   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19278   [(set_attr "type" "sseadd")
19279    (set_attr "mode" "<MODE>")])
19280
19281 ;; These versions of the min/max patterns implement exactly the operations
19282 ;;   min = (op1 < op2 ? op1 : op2)
19283 ;;   max = (!(op1 < op2) ? op1 : op2)
19284 ;; Their operands are not commutative, and thus they may be used in the
19285 ;; presence of -0.0 and NaN.
19286
19287 (define_insn "*avx_ieee_smin<mode>3"
19288   [(set (match_operand:MODEF 0 "register_operand" "=x")
19289         (unspec:MODEF
19290           [(match_operand:MODEF 1 "register_operand" "x")
19291            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19292          UNSPEC_IEEE_MIN))]
19293   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19294   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19295   [(set_attr "type" "sseadd")
19296    (set_attr "prefix" "vex")
19297    (set_attr "mode" "<MODE>")])
19298
19299 (define_insn "*ieee_smin<mode>3"
19300   [(set (match_operand:MODEF 0 "register_operand" "=x")
19301         (unspec:MODEF
19302           [(match_operand:MODEF 1 "register_operand" "0")
19303            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19304          UNSPEC_IEEE_MIN))]
19305   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19306   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19307   [(set_attr "type" "sseadd")
19308    (set_attr "mode" "<MODE>")])
19309
19310 (define_insn "*avx_ieee_smax<mode>3"
19311   [(set (match_operand:MODEF 0 "register_operand" "=x")
19312         (unspec:MODEF
19313           [(match_operand:MODEF 1 "register_operand" "0")
19314            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19315          UNSPEC_IEEE_MAX))]
19316   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19317   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19318   [(set_attr "type" "sseadd")
19319    (set_attr "prefix" "vex")
19320    (set_attr "mode" "<MODE>")])
19321
19322 (define_insn "*ieee_smax<mode>3"
19323   [(set (match_operand:MODEF 0 "register_operand" "=x")
19324         (unspec:MODEF
19325           [(match_operand:MODEF 1 "register_operand" "0")
19326            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19327          UNSPEC_IEEE_MAX))]
19328   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19329   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19330   [(set_attr "type" "sseadd")
19331    (set_attr "mode" "<MODE>")])
19332
19333 ;; Make two stack loads independent:
19334 ;;   fld aa              fld aa
19335 ;;   fld %st(0)     ->   fld bb
19336 ;;   fmul bb             fmul %st(1), %st
19337 ;;
19338 ;; Actually we only match the last two instructions for simplicity.
19339 (define_peephole2
19340   [(set (match_operand 0 "fp_register_operand" "")
19341         (match_operand 1 "fp_register_operand" ""))
19342    (set (match_dup 0)
19343         (match_operator 2 "binary_fp_operator"
19344            [(match_dup 0)
19345             (match_operand 3 "memory_operand" "")]))]
19346   "REGNO (operands[0]) != REGNO (operands[1])"
19347   [(set (match_dup 0) (match_dup 3))
19348    (set (match_dup 0) (match_dup 4))]
19349
19350   ;; The % modifier is not operational anymore in peephole2's, so we have to
19351   ;; swap the operands manually in the case of addition and multiplication.
19352   "if (COMMUTATIVE_ARITH_P (operands[2]))
19353      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19354                                  operands[0], operands[1]);
19355    else
19356      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19357                                  operands[1], operands[0]);")
19358
19359 ;; Conditional addition patterns
19360 (define_expand "add<mode>cc"
19361   [(match_operand:SWI 0 "register_operand" "")
19362    (match_operand 1 "comparison_operator" "")
19363    (match_operand:SWI 2 "register_operand" "")
19364    (match_operand:SWI 3 "const_int_operand" "")]
19365   ""
19366   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19367
19368 \f
19369 ;; Misc patterns (?)
19370
19371 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19372 ;; Otherwise there will be nothing to keep
19373 ;;
19374 ;; [(set (reg ebp) (reg esp))]
19375 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19376 ;;  (clobber (eflags)]
19377 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19378 ;;
19379 ;; in proper program order.
19380 (define_insn "pro_epilogue_adjust_stack_1"
19381   [(set (match_operand:SI 0 "register_operand" "=r,r")
19382         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19383                  (match_operand:SI 2 "immediate_operand" "i,i")))
19384    (clobber (reg:CC FLAGS_REG))
19385    (clobber (mem:BLK (scratch)))]
19386   "!TARGET_64BIT"
19387 {
19388   switch (get_attr_type (insn))
19389     {
19390     case TYPE_IMOV:
19391       return "mov{l}\t{%1, %0|%0, %1}";
19392
19393     case TYPE_ALU:
19394       if (CONST_INT_P (operands[2])
19395           && (INTVAL (operands[2]) == 128
19396               || (INTVAL (operands[2]) < 0
19397                   && INTVAL (operands[2]) != -128)))
19398         {
19399           operands[2] = GEN_INT (-INTVAL (operands[2]));
19400           return "sub{l}\t{%2, %0|%0, %2}";
19401         }
19402       return "add{l}\t{%2, %0|%0, %2}";
19403
19404     case TYPE_LEA:
19405       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19406       return "lea{l}\t{%a2, %0|%0, %a2}";
19407
19408     default:
19409       gcc_unreachable ();
19410     }
19411 }
19412   [(set (attr "type")
19413         (cond [(and (eq_attr "alternative" "0") 
19414                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19415                  (const_string "alu")
19416                (match_operand:SI 2 "const0_operand" "")
19417                  (const_string "imov")
19418               ]
19419               (const_string "lea")))
19420    (set (attr "length_immediate")
19421         (cond [(eq_attr "type" "imov")
19422                  (const_string "0")
19423                (and (eq_attr "type" "alu")
19424                     (match_operand 2 "const128_operand" ""))
19425                  (const_string "1")
19426               ]
19427               (const_string "*")))
19428    (set_attr "mode" "SI")])
19429
19430 (define_insn "pro_epilogue_adjust_stack_rex64"
19431   [(set (match_operand:DI 0 "register_operand" "=r,r")
19432         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19433                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19434    (clobber (reg:CC FLAGS_REG))
19435    (clobber (mem:BLK (scratch)))]
19436   "TARGET_64BIT"
19437 {
19438   switch (get_attr_type (insn))
19439     {
19440     case TYPE_IMOV:
19441       return "mov{q}\t{%1, %0|%0, %1}";
19442
19443     case TYPE_ALU:
19444       if (CONST_INT_P (operands[2])
19445           /* Avoid overflows.  */
19446           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19447           && (INTVAL (operands[2]) == 128
19448               || (INTVAL (operands[2]) < 0
19449                   && INTVAL (operands[2]) != -128)))
19450         {
19451           operands[2] = GEN_INT (-INTVAL (operands[2]));
19452           return "sub{q}\t{%2, %0|%0, %2}";
19453         }
19454       return "add{q}\t{%2, %0|%0, %2}";
19455
19456     case TYPE_LEA:
19457       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19458       return "lea{q}\t{%a2, %0|%0, %a2}";
19459
19460     default:
19461       gcc_unreachable ();
19462     }
19463 }
19464   [(set (attr "type")
19465         (cond [(and (eq_attr "alternative" "0")
19466                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19467                  (const_string "alu")
19468                (match_operand:DI 2 "const0_operand" "")
19469                  (const_string "imov")
19470               ]
19471               (const_string "lea")))
19472    (set (attr "length_immediate")
19473         (cond [(eq_attr "type" "imov")
19474                  (const_string "0")
19475                (and (eq_attr "type" "alu")
19476                     (match_operand 2 "const128_operand" ""))
19477                  (const_string "1")
19478               ]
19479               (const_string "*")))
19480    (set_attr "mode" "DI")])
19481
19482 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19483   [(set (match_operand:DI 0 "register_operand" "=r,r")
19484         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19485                  (match_operand:DI 3 "immediate_operand" "i,i")))
19486    (use (match_operand:DI 2 "register_operand" "r,r"))
19487    (clobber (reg:CC FLAGS_REG))
19488    (clobber (mem:BLK (scratch)))]
19489   "TARGET_64BIT"
19490 {
19491   switch (get_attr_type (insn))
19492     {
19493     case TYPE_ALU:
19494       return "add{q}\t{%2, %0|%0, %2}";
19495
19496     case TYPE_LEA:
19497       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19498       return "lea{q}\t{%a2, %0|%0, %a2}";
19499
19500     default:
19501       gcc_unreachable ();
19502     }
19503 }
19504   [(set_attr "type" "alu,lea")
19505    (set_attr "mode" "DI")])
19506
19507 (define_insn "allocate_stack_worker_32"
19508   [(set (match_operand:SI 0 "register_operand" "=a")
19509         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19510                             UNSPECV_STACK_PROBE))
19511    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19512    (clobber (reg:CC FLAGS_REG))]
19513   "!TARGET_64BIT && TARGET_STACK_PROBE"
19514   "call\t___chkstk"
19515   [(set_attr "type" "multi")
19516    (set_attr "length" "5")])
19517
19518 (define_insn "allocate_stack_worker_64"
19519   [(set (match_operand:DI 0 "register_operand" "=a")
19520         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19521                             UNSPECV_STACK_PROBE))
19522    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19523    (clobber (reg:DI R10_REG))
19524    (clobber (reg:DI R11_REG))
19525    (clobber (reg:CC FLAGS_REG))]
19526   "TARGET_64BIT && TARGET_STACK_PROBE"
19527   "call\t___chkstk"
19528   [(set_attr "type" "multi")
19529    (set_attr "length" "5")])
19530
19531 (define_expand "allocate_stack"
19532   [(match_operand 0 "register_operand" "")
19533    (match_operand 1 "general_operand" "")]
19534   "TARGET_STACK_PROBE"
19535 {
19536   rtx x;
19537
19538 #ifndef CHECK_STACK_LIMIT
19539 #define CHECK_STACK_LIMIT 0
19540 #endif
19541
19542   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19543       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19544     {
19545       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19546                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19547       if (x != stack_pointer_rtx)
19548         emit_move_insn (stack_pointer_rtx, x);
19549     }
19550   else
19551     {
19552       x = copy_to_mode_reg (Pmode, operands[1]);
19553       if (TARGET_64BIT)
19554         x = gen_allocate_stack_worker_64 (x, x);
19555       else
19556         x = gen_allocate_stack_worker_32 (x, x);
19557       emit_insn (x);
19558     }
19559
19560   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19561   DONE;
19562 })
19563
19564 ;; Use IOR for stack probes, this is shorter.
19565 (define_expand "probe_stack"
19566   [(match_operand 0 "memory_operand" "")]
19567   ""
19568 {
19569   if (GET_MODE (operands[0]) == DImode)
19570     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19571   else
19572     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19573   DONE;
19574 })
19575
19576 (define_expand "builtin_setjmp_receiver"
19577   [(label_ref (match_operand 0 "" ""))]
19578   "!TARGET_64BIT && flag_pic"
19579 {
19580 #if TARGET_MACHO
19581   if (TARGET_MACHO)
19582     {
19583       rtx xops[3];
19584       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19585       rtx label_rtx = gen_label_rtx ();
19586       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19587       xops[0] = xops[1] = picreg;
19588       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19589       ix86_expand_binary_operator (MINUS, SImode, xops);
19590     }
19591   else
19592 #endif
19593     emit_insn (gen_set_got (pic_offset_table_rtx));
19594   DONE;
19595 })
19596 \f
19597 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19598
19599 (define_split
19600   [(set (match_operand 0 "register_operand" "")
19601         (match_operator 3 "promotable_binary_operator"
19602            [(match_operand 1 "register_operand" "")
19603             (match_operand 2 "aligned_operand" "")]))
19604    (clobber (reg:CC FLAGS_REG))]
19605   "! TARGET_PARTIAL_REG_STALL && reload_completed
19606    && ((GET_MODE (operands[0]) == HImode
19607         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19608             /* ??? next two lines just !satisfies_constraint_K (...) */
19609             || !CONST_INT_P (operands[2])
19610             || satisfies_constraint_K (operands[2])))
19611        || (GET_MODE (operands[0]) == QImode
19612            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19613   [(parallel [(set (match_dup 0)
19614                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19615               (clobber (reg:CC FLAGS_REG))])]
19616   "operands[0] = gen_lowpart (SImode, operands[0]);
19617    operands[1] = gen_lowpart (SImode, operands[1]);
19618    if (GET_CODE (operands[3]) != ASHIFT)
19619      operands[2] = gen_lowpart (SImode, operands[2]);
19620    PUT_MODE (operands[3], SImode);")
19621
19622 ; Promote the QImode tests, as i386 has encoding of the AND
19623 ; instruction with 32-bit sign-extended immediate and thus the
19624 ; instruction size is unchanged, except in the %eax case for
19625 ; which it is increased by one byte, hence the ! optimize_size.
19626 (define_split
19627   [(set (match_operand 0 "flags_reg_operand" "")
19628         (match_operator 2 "compare_operator"
19629           [(and (match_operand 3 "aligned_operand" "")
19630                 (match_operand 4 "const_int_operand" ""))
19631            (const_int 0)]))
19632    (set (match_operand 1 "register_operand" "")
19633         (and (match_dup 3) (match_dup 4)))]
19634   "! TARGET_PARTIAL_REG_STALL && reload_completed
19635    && optimize_insn_for_speed_p ()
19636    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19637        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19638    /* Ensure that the operand will remain sign-extended immediate.  */
19639    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19640   [(parallel [(set (match_dup 0)
19641                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19642                                     (const_int 0)]))
19643               (set (match_dup 1)
19644                    (and:SI (match_dup 3) (match_dup 4)))])]
19645 {
19646   operands[4]
19647     = gen_int_mode (INTVAL (operands[4])
19648                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19649   operands[1] = gen_lowpart (SImode, operands[1]);
19650   operands[3] = gen_lowpart (SImode, operands[3]);
19651 })
19652
19653 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19654 ; the TEST instruction with 32-bit sign-extended immediate and thus
19655 ; the instruction size would at least double, which is not what we
19656 ; want even with ! optimize_size.
19657 (define_split
19658   [(set (match_operand 0 "flags_reg_operand" "")
19659         (match_operator 1 "compare_operator"
19660           [(and (match_operand:HI 2 "aligned_operand" "")
19661                 (match_operand:HI 3 "const_int_operand" ""))
19662            (const_int 0)]))]
19663   "! TARGET_PARTIAL_REG_STALL && reload_completed
19664    && ! TARGET_FAST_PREFIX
19665    && optimize_insn_for_speed_p ()
19666    /* Ensure that the operand will remain sign-extended immediate.  */
19667    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19668   [(set (match_dup 0)
19669         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19670                          (const_int 0)]))]
19671 {
19672   operands[3]
19673     = gen_int_mode (INTVAL (operands[3])
19674                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19675   operands[2] = gen_lowpart (SImode, operands[2]);
19676 })
19677
19678 (define_split
19679   [(set (match_operand 0 "register_operand" "")
19680         (neg (match_operand 1 "register_operand" "")))
19681    (clobber (reg:CC FLAGS_REG))]
19682   "! TARGET_PARTIAL_REG_STALL && reload_completed
19683    && (GET_MODE (operands[0]) == HImode
19684        || (GET_MODE (operands[0]) == QImode
19685            && (TARGET_PROMOTE_QImode
19686                || optimize_insn_for_size_p ())))"
19687   [(parallel [(set (match_dup 0)
19688                    (neg:SI (match_dup 1)))
19689               (clobber (reg:CC FLAGS_REG))])]
19690   "operands[0] = gen_lowpart (SImode, operands[0]);
19691    operands[1] = gen_lowpart (SImode, operands[1]);")
19692
19693 (define_split
19694   [(set (match_operand 0 "register_operand" "")
19695         (not (match_operand 1 "register_operand" "")))]
19696   "! TARGET_PARTIAL_REG_STALL && reload_completed
19697    && (GET_MODE (operands[0]) == HImode
19698        || (GET_MODE (operands[0]) == QImode
19699            && (TARGET_PROMOTE_QImode
19700                || optimize_insn_for_size_p ())))"
19701   [(set (match_dup 0)
19702         (not:SI (match_dup 1)))]
19703   "operands[0] = gen_lowpart (SImode, operands[0]);
19704    operands[1] = gen_lowpart (SImode, operands[1]);")
19705
19706 (define_split
19707   [(set (match_operand 0 "register_operand" "")
19708         (if_then_else (match_operator 1 "comparison_operator"
19709                                 [(reg FLAGS_REG) (const_int 0)])
19710                       (match_operand 2 "register_operand" "")
19711                       (match_operand 3 "register_operand" "")))]
19712   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19713    && (GET_MODE (operands[0]) == HImode
19714        || (GET_MODE (operands[0]) == QImode
19715            && (TARGET_PROMOTE_QImode
19716                || optimize_insn_for_size_p ())))"
19717   [(set (match_dup 0)
19718         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19719   "operands[0] = gen_lowpart (SImode, operands[0]);
19720    operands[2] = gen_lowpart (SImode, operands[2]);
19721    operands[3] = gen_lowpart (SImode, operands[3]);")
19722
19723 \f
19724 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19725 ;; transform a complex memory operation into two memory to register operations.
19726
19727 ;; Don't push memory operands
19728 (define_peephole2
19729   [(set (match_operand:SI 0 "push_operand" "")
19730         (match_operand:SI 1 "memory_operand" ""))
19731    (match_scratch:SI 2 "r")]
19732   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19733    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19734   [(set (match_dup 2) (match_dup 1))
19735    (set (match_dup 0) (match_dup 2))]
19736   "")
19737
19738 (define_peephole2
19739   [(set (match_operand:DI 0 "push_operand" "")
19740         (match_operand:DI 1 "memory_operand" ""))
19741    (match_scratch:DI 2 "r")]
19742   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19743    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19744   [(set (match_dup 2) (match_dup 1))
19745    (set (match_dup 0) (match_dup 2))]
19746   "")
19747
19748 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19749 ;; SImode pushes.
19750 (define_peephole2
19751   [(set (match_operand:SF 0 "push_operand" "")
19752         (match_operand:SF 1 "memory_operand" ""))
19753    (match_scratch:SF 2 "r")]
19754   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19755    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19756   [(set (match_dup 2) (match_dup 1))
19757    (set (match_dup 0) (match_dup 2))]
19758   "")
19759
19760 (define_peephole2
19761   [(set (match_operand:HI 0 "push_operand" "")
19762         (match_operand:HI 1 "memory_operand" ""))
19763    (match_scratch:HI 2 "r")]
19764   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19765    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19766   [(set (match_dup 2) (match_dup 1))
19767    (set (match_dup 0) (match_dup 2))]
19768   "")
19769
19770 (define_peephole2
19771   [(set (match_operand:QI 0 "push_operand" "")
19772         (match_operand:QI 1 "memory_operand" ""))
19773    (match_scratch:QI 2 "q")]
19774   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19775    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19776   [(set (match_dup 2) (match_dup 1))
19777    (set (match_dup 0) (match_dup 2))]
19778   "")
19779
19780 ;; Don't move an immediate directly to memory when the instruction
19781 ;; gets too big.
19782 (define_peephole2
19783   [(match_scratch:SI 1 "r")
19784    (set (match_operand:SI 0 "memory_operand" "")
19785         (const_int 0))]
19786   "optimize_insn_for_speed_p ()
19787    && ! TARGET_USE_MOV0
19788    && TARGET_SPLIT_LONG_MOVES
19789    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19790    && peep2_regno_dead_p (0, FLAGS_REG)"
19791   [(parallel [(set (match_dup 1) (const_int 0))
19792               (clobber (reg:CC FLAGS_REG))])
19793    (set (match_dup 0) (match_dup 1))]
19794   "")
19795
19796 (define_peephole2
19797   [(match_scratch:HI 1 "r")
19798    (set (match_operand:HI 0 "memory_operand" "")
19799         (const_int 0))]
19800   "optimize_insn_for_speed_p ()
19801    && ! TARGET_USE_MOV0
19802    && TARGET_SPLIT_LONG_MOVES
19803    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19804    && peep2_regno_dead_p (0, FLAGS_REG)"
19805   [(parallel [(set (match_dup 2) (const_int 0))
19806               (clobber (reg:CC FLAGS_REG))])
19807    (set (match_dup 0) (match_dup 1))]
19808   "operands[2] = gen_lowpart (SImode, operands[1]);")
19809
19810 (define_peephole2
19811   [(match_scratch:QI 1 "q")
19812    (set (match_operand:QI 0 "memory_operand" "")
19813         (const_int 0))]
19814   "optimize_insn_for_speed_p ()
19815    && ! TARGET_USE_MOV0
19816    && TARGET_SPLIT_LONG_MOVES
19817    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19818    && peep2_regno_dead_p (0, FLAGS_REG)"
19819   [(parallel [(set (match_dup 2) (const_int 0))
19820               (clobber (reg:CC FLAGS_REG))])
19821    (set (match_dup 0) (match_dup 1))]
19822   "operands[2] = gen_lowpart (SImode, operands[1]);")
19823
19824 (define_peephole2
19825   [(match_scratch:SI 2 "r")
19826    (set (match_operand:SI 0 "memory_operand" "")
19827         (match_operand:SI 1 "immediate_operand" ""))]
19828   "optimize_insn_for_speed_p ()
19829    && TARGET_SPLIT_LONG_MOVES
19830    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19831   [(set (match_dup 2) (match_dup 1))
19832    (set (match_dup 0) (match_dup 2))]
19833   "")
19834
19835 (define_peephole2
19836   [(match_scratch:HI 2 "r")
19837    (set (match_operand:HI 0 "memory_operand" "")
19838         (match_operand:HI 1 "immediate_operand" ""))]
19839   "optimize_insn_for_speed_p ()
19840    && TARGET_SPLIT_LONG_MOVES
19841    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19842   [(set (match_dup 2) (match_dup 1))
19843    (set (match_dup 0) (match_dup 2))]
19844   "")
19845
19846 (define_peephole2
19847   [(match_scratch:QI 2 "q")
19848    (set (match_operand:QI 0 "memory_operand" "")
19849         (match_operand:QI 1 "immediate_operand" ""))]
19850   "optimize_insn_for_speed_p ()
19851    && TARGET_SPLIT_LONG_MOVES
19852    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19853   [(set (match_dup 2) (match_dup 1))
19854    (set (match_dup 0) (match_dup 2))]
19855   "")
19856
19857 ;; Don't compare memory with zero, load and use a test instead.
19858 (define_peephole2
19859   [(set (match_operand 0 "flags_reg_operand" "")
19860         (match_operator 1 "compare_operator"
19861           [(match_operand:SI 2 "memory_operand" "")
19862            (const_int 0)]))
19863    (match_scratch:SI 3 "r")]
19864   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19865   [(set (match_dup 3) (match_dup 2))
19866    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19867   "")
19868
19869 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19870 ;; Don't split NOTs with a displacement operand, because resulting XOR
19871 ;; will not be pairable anyway.
19872 ;;
19873 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19874 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19875 ;; so this split helps here as well.
19876 ;;
19877 ;; Note: Can't do this as a regular split because we can't get proper
19878 ;; lifetime information then.
19879
19880 (define_peephole2
19881   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19882         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19883   "optimize_insn_for_speed_p ()
19884    && ((TARGET_NOT_UNPAIRABLE
19885         && (!MEM_P (operands[0])
19886             || !memory_displacement_operand (operands[0], SImode)))
19887        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19888    && peep2_regno_dead_p (0, FLAGS_REG)"
19889   [(parallel [(set (match_dup 0)
19890                    (xor:SI (match_dup 1) (const_int -1)))
19891               (clobber (reg:CC FLAGS_REG))])]
19892   "")
19893
19894 (define_peephole2
19895   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19896         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19897   "optimize_insn_for_speed_p ()
19898    && ((TARGET_NOT_UNPAIRABLE
19899         && (!MEM_P (operands[0])
19900             || !memory_displacement_operand (operands[0], HImode)))
19901        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19902    && peep2_regno_dead_p (0, FLAGS_REG)"
19903   [(parallel [(set (match_dup 0)
19904                    (xor:HI (match_dup 1) (const_int -1)))
19905               (clobber (reg:CC FLAGS_REG))])]
19906   "")
19907
19908 (define_peephole2
19909   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19910         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19911   "optimize_insn_for_speed_p ()
19912    && ((TARGET_NOT_UNPAIRABLE
19913         && (!MEM_P (operands[0])
19914             || !memory_displacement_operand (operands[0], QImode)))
19915        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19916    && peep2_regno_dead_p (0, FLAGS_REG)"
19917   [(parallel [(set (match_dup 0)
19918                    (xor:QI (match_dup 1) (const_int -1)))
19919               (clobber (reg:CC FLAGS_REG))])]
19920   "")
19921
19922 ;; Non pairable "test imm, reg" instructions can be translated to
19923 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19924 ;; byte opcode instead of two, have a short form for byte operands),
19925 ;; so do it for other CPUs as well.  Given that the value was dead,
19926 ;; this should not create any new dependencies.  Pass on the sub-word
19927 ;; versions if we're concerned about partial register stalls.
19928
19929 (define_peephole2
19930   [(set (match_operand 0 "flags_reg_operand" "")
19931         (match_operator 1 "compare_operator"
19932           [(and:SI (match_operand:SI 2 "register_operand" "")
19933                    (match_operand:SI 3 "immediate_operand" ""))
19934            (const_int 0)]))]
19935   "ix86_match_ccmode (insn, CCNOmode)
19936    && (true_regnum (operands[2]) != AX_REG
19937        || satisfies_constraint_K (operands[3]))
19938    && peep2_reg_dead_p (1, operands[2])"
19939   [(parallel
19940      [(set (match_dup 0)
19941            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19942                             (const_int 0)]))
19943       (set (match_dup 2)
19944            (and:SI (match_dup 2) (match_dup 3)))])]
19945   "")
19946
19947 ;; We don't need to handle HImode case, because it will be promoted to SImode
19948 ;; on ! TARGET_PARTIAL_REG_STALL
19949
19950 (define_peephole2
19951   [(set (match_operand 0 "flags_reg_operand" "")
19952         (match_operator 1 "compare_operator"
19953           [(and:QI (match_operand:QI 2 "register_operand" "")
19954                    (match_operand:QI 3 "immediate_operand" ""))
19955            (const_int 0)]))]
19956   "! TARGET_PARTIAL_REG_STALL
19957    && ix86_match_ccmode (insn, CCNOmode)
19958    && true_regnum (operands[2]) != AX_REG
19959    && peep2_reg_dead_p (1, operands[2])"
19960   [(parallel
19961      [(set (match_dup 0)
19962            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19963                             (const_int 0)]))
19964       (set (match_dup 2)
19965            (and:QI (match_dup 2) (match_dup 3)))])]
19966   "")
19967
19968 (define_peephole2
19969   [(set (match_operand 0 "flags_reg_operand" "")
19970         (match_operator 1 "compare_operator"
19971           [(and:SI
19972              (zero_extract:SI
19973                (match_operand 2 "ext_register_operand" "")
19974                (const_int 8)
19975                (const_int 8))
19976              (match_operand 3 "const_int_operand" ""))
19977            (const_int 0)]))]
19978   "! TARGET_PARTIAL_REG_STALL
19979    && ix86_match_ccmode (insn, CCNOmode)
19980    && true_regnum (operands[2]) != AX_REG
19981    && peep2_reg_dead_p (1, operands[2])"
19982   [(parallel [(set (match_dup 0)
19983                    (match_op_dup 1
19984                      [(and:SI
19985                         (zero_extract:SI
19986                           (match_dup 2)
19987                           (const_int 8)
19988                           (const_int 8))
19989                         (match_dup 3))
19990                       (const_int 0)]))
19991               (set (zero_extract:SI (match_dup 2)
19992                                     (const_int 8)
19993                                     (const_int 8))
19994                    (and:SI
19995                      (zero_extract:SI
19996                        (match_dup 2)
19997                        (const_int 8)
19998                        (const_int 8))
19999                      (match_dup 3)))])]
20000   "")
20001
20002 ;; Don't do logical operations with memory inputs.
20003 (define_peephole2
20004   [(match_scratch:SI 2 "r")
20005    (parallel [(set (match_operand:SI 0 "register_operand" "")
20006                    (match_operator:SI 3 "arith_or_logical_operator"
20007                      [(match_dup 0)
20008                       (match_operand:SI 1 "memory_operand" "")]))
20009               (clobber (reg:CC FLAGS_REG))])]
20010   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20011   [(set (match_dup 2) (match_dup 1))
20012    (parallel [(set (match_dup 0)
20013                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20014               (clobber (reg:CC FLAGS_REG))])]
20015   "")
20016
20017 (define_peephole2
20018   [(match_scratch:SI 2 "r")
20019    (parallel [(set (match_operand:SI 0 "register_operand" "")
20020                    (match_operator:SI 3 "arith_or_logical_operator"
20021                      [(match_operand:SI 1 "memory_operand" "")
20022                       (match_dup 0)]))
20023               (clobber (reg:CC FLAGS_REG))])]
20024   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20025   [(set (match_dup 2) (match_dup 1))
20026    (parallel [(set (match_dup 0)
20027                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20028               (clobber (reg:CC FLAGS_REG))])]
20029   "")
20030
20031 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20032 ;; refers to the destination of the load!
20033
20034 (define_peephole2
20035   [(set (match_operand:SI 0 "register_operand" "")
20036         (match_operand:SI 1 "register_operand" ""))
20037    (parallel [(set (match_dup 0)
20038                    (match_operator:SI 3 "commutative_operator"
20039                      [(match_dup 0)
20040                       (match_operand:SI 2 "memory_operand" "")]))
20041               (clobber (reg:CC FLAGS_REG))])]
20042   "REGNO (operands[0]) != REGNO (operands[1])
20043    && GENERAL_REGNO_P (REGNO (operands[0]))
20044    && GENERAL_REGNO_P (REGNO (operands[1]))"
20045   [(set (match_dup 0) (match_dup 4))
20046    (parallel [(set (match_dup 0)
20047                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20048               (clobber (reg:CC FLAGS_REG))])]
20049   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20050
20051 (define_peephole2
20052   [(set (match_operand 0 "register_operand" "")
20053         (match_operand 1 "register_operand" ""))
20054    (set (match_dup 0)
20055                    (match_operator 3 "commutative_operator"
20056                      [(match_dup 0)
20057                       (match_operand 2 "memory_operand" "")]))]
20058   "REGNO (operands[0]) != REGNO (operands[1])
20059    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20060        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20061   [(set (match_dup 0) (match_dup 2))
20062    (set (match_dup 0)
20063         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20064   "")
20065
20066 ; Don't do logical operations with memory outputs
20067 ;
20068 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20069 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20070 ; the same decoder scheduling characteristics as the original.
20071
20072 (define_peephole2
20073   [(match_scratch:SI 2 "r")
20074    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20075                    (match_operator:SI 3 "arith_or_logical_operator"
20076                      [(match_dup 0)
20077                       (match_operand:SI 1 "nonmemory_operand" "")]))
20078               (clobber (reg:CC FLAGS_REG))])]
20079   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20080    /* Do not split stack checking probes.  */
20081    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20082   [(set (match_dup 2) (match_dup 0))
20083    (parallel [(set (match_dup 2)
20084                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20085               (clobber (reg:CC FLAGS_REG))])
20086    (set (match_dup 0) (match_dup 2))]
20087   "")
20088
20089 (define_peephole2
20090   [(match_scratch:SI 2 "r")
20091    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20092                    (match_operator:SI 3 "arith_or_logical_operator"
20093                      [(match_operand:SI 1 "nonmemory_operand" "")
20094                       (match_dup 0)]))
20095               (clobber (reg:CC FLAGS_REG))])]
20096   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20097    /* Do not split stack checking probes.  */
20098    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20099   [(set (match_dup 2) (match_dup 0))
20100    (parallel [(set (match_dup 2)
20101                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20102               (clobber (reg:CC FLAGS_REG))])
20103    (set (match_dup 0) (match_dup 2))]
20104   "")
20105
20106 ;; Attempt to always use XOR for zeroing registers.
20107 (define_peephole2
20108   [(set (match_operand 0 "register_operand" "")
20109         (match_operand 1 "const0_operand" ""))]
20110   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20111    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20112    && GENERAL_REG_P (operands[0])
20113    && peep2_regno_dead_p (0, FLAGS_REG)"
20114   [(parallel [(set (match_dup 0) (const_int 0))
20115               (clobber (reg:CC FLAGS_REG))])]
20116 {
20117   operands[0] = gen_lowpart (word_mode, operands[0]);
20118 })
20119
20120 (define_peephole2
20121   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20122         (const_int 0))]
20123   "(GET_MODE (operands[0]) == QImode
20124     || GET_MODE (operands[0]) == HImode)
20125    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20126    && peep2_regno_dead_p (0, FLAGS_REG)"
20127   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20128               (clobber (reg:CC FLAGS_REG))])])
20129
20130 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20131 (define_peephole2
20132   [(set (match_operand 0 "register_operand" "")
20133         (const_int -1))]
20134   "(GET_MODE (operands[0]) == HImode
20135     || GET_MODE (operands[0]) == SImode
20136     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20137    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20138    && peep2_regno_dead_p (0, FLAGS_REG)"
20139   [(parallel [(set (match_dup 0) (const_int -1))
20140               (clobber (reg:CC FLAGS_REG))])]
20141   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20142                               operands[0]);")
20143
20144 ;; Attempt to convert simple leas to adds. These can be created by
20145 ;; move expanders.
20146 (define_peephole2
20147   [(set (match_operand:SI 0 "register_operand" "")
20148         (plus:SI (match_dup 0)
20149                  (match_operand:SI 1 "nonmemory_operand" "")))]
20150   "peep2_regno_dead_p (0, FLAGS_REG)"
20151   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20152               (clobber (reg:CC FLAGS_REG))])]
20153   "")
20154
20155 (define_peephole2
20156   [(set (match_operand:SI 0 "register_operand" "")
20157         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20158                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20159   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20160   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20161               (clobber (reg:CC FLAGS_REG))])]
20162   "operands[2] = gen_lowpart (SImode, operands[2]);")
20163
20164 (define_peephole2
20165   [(set (match_operand:DI 0 "register_operand" "")
20166         (plus:DI (match_dup 0)
20167                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20168   "peep2_regno_dead_p (0, FLAGS_REG)"
20169   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20170               (clobber (reg:CC FLAGS_REG))])]
20171   "")
20172
20173 (define_peephole2
20174   [(set (match_operand:SI 0 "register_operand" "")
20175         (mult:SI (match_dup 0)
20176                  (match_operand:SI 1 "const_int_operand" "")))]
20177   "exact_log2 (INTVAL (operands[1])) >= 0
20178    && peep2_regno_dead_p (0, FLAGS_REG)"
20179   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20180               (clobber (reg:CC FLAGS_REG))])]
20181   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20182
20183 (define_peephole2
20184   [(set (match_operand:DI 0 "register_operand" "")
20185         (mult:DI (match_dup 0)
20186                  (match_operand:DI 1 "const_int_operand" "")))]
20187   "exact_log2 (INTVAL (operands[1])) >= 0
20188    && peep2_regno_dead_p (0, FLAGS_REG)"
20189   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20190               (clobber (reg:CC FLAGS_REG))])]
20191   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20192
20193 (define_peephole2
20194   [(set (match_operand:SI 0 "register_operand" "")
20195         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20196                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20197   "exact_log2 (INTVAL (operands[2])) >= 0
20198    && REGNO (operands[0]) == REGNO (operands[1])
20199    && peep2_regno_dead_p (0, FLAGS_REG)"
20200   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20201               (clobber (reg:CC FLAGS_REG))])]
20202   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20203
20204 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20205 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20206 ;; many CPUs it is also faster, since special hardware to avoid esp
20207 ;; dependencies is present.
20208
20209 ;; While some of these conversions may be done using splitters, we use peepholes
20210 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20211
20212 ;; Convert prologue esp subtractions to push.
20213 ;; We need register to push.  In order to keep verify_flow_info happy we have
20214 ;; two choices
20215 ;; - use scratch and clobber it in order to avoid dependencies
20216 ;; - use already live register
20217 ;; We can't use the second way right now, since there is no reliable way how to
20218 ;; verify that given register is live.  First choice will also most likely in
20219 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20220 ;; call clobbered registers are dead.  We may want to use base pointer as an
20221 ;; alternative when no register is available later.
20222
20223 (define_peephole2
20224   [(match_scratch:SI 0 "r")
20225    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20226               (clobber (reg:CC FLAGS_REG))
20227               (clobber (mem:BLK (scratch)))])]
20228   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20229   [(clobber (match_dup 0))
20230    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20231               (clobber (mem:BLK (scratch)))])])
20232
20233 (define_peephole2
20234   [(match_scratch:SI 0 "r")
20235    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20236               (clobber (reg:CC FLAGS_REG))
20237               (clobber (mem:BLK (scratch)))])]
20238   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20239   [(clobber (match_dup 0))
20240    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20241    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20242               (clobber (mem:BLK (scratch)))])])
20243
20244 ;; Convert esp subtractions to push.
20245 (define_peephole2
20246   [(match_scratch:SI 0 "r")
20247    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20248               (clobber (reg:CC FLAGS_REG))])]
20249   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20250   [(clobber (match_dup 0))
20251    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20252
20253 (define_peephole2
20254   [(match_scratch:SI 0 "r")
20255    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20256               (clobber (reg:CC FLAGS_REG))])]
20257   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20258   [(clobber (match_dup 0))
20259    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20260    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20261
20262 ;; Convert epilogue deallocator to pop.
20263 (define_peephole2
20264   [(match_scratch:SI 0 "r")
20265    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20266               (clobber (reg:CC FLAGS_REG))
20267               (clobber (mem:BLK (scratch)))])]
20268   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20269   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20270               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20271               (clobber (mem:BLK (scratch)))])]
20272   "")
20273
20274 ;; Two pops case is tricky, since pop causes dependency on destination register.
20275 ;; We use two registers if available.
20276 (define_peephole2
20277   [(match_scratch:SI 0 "r")
20278    (match_scratch:SI 1 "r")
20279    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20280               (clobber (reg:CC FLAGS_REG))
20281               (clobber (mem:BLK (scratch)))])]
20282   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20283   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20284               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20285               (clobber (mem:BLK (scratch)))])
20286    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20287               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20288   "")
20289
20290 (define_peephole2
20291   [(match_scratch:SI 0 "r")
20292    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20293               (clobber (reg:CC FLAGS_REG))
20294               (clobber (mem:BLK (scratch)))])]
20295   "optimize_insn_for_size_p ()"
20296   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20297               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20298               (clobber (mem:BLK (scratch)))])
20299    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20300               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20301   "")
20302
20303 ;; Convert esp additions to pop.
20304 (define_peephole2
20305   [(match_scratch:SI 0 "r")
20306    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20307               (clobber (reg:CC FLAGS_REG))])]
20308   ""
20309   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20310               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20311   "")
20312
20313 ;; Two pops case is tricky, since pop causes dependency on destination register.
20314 ;; We use two registers if available.
20315 (define_peephole2
20316   [(match_scratch:SI 0 "r")
20317    (match_scratch:SI 1 "r")
20318    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20319               (clobber (reg:CC FLAGS_REG))])]
20320   ""
20321   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20322               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20323    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20324               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20325   "")
20326
20327 (define_peephole2
20328   [(match_scratch:SI 0 "r")
20329    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20330               (clobber (reg:CC FLAGS_REG))])]
20331   "optimize_insn_for_size_p ()"
20332   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20333               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20334    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20335               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20336   "")
20337 \f
20338 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20339 ;; required and register dies.  Similarly for 128 to -128.
20340 (define_peephole2
20341   [(set (match_operand 0 "flags_reg_operand" "")
20342         (match_operator 1 "compare_operator"
20343           [(match_operand 2 "register_operand" "")
20344            (match_operand 3 "const_int_operand" "")]))]
20345   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20346      && incdec_operand (operands[3], GET_MODE (operands[3])))
20347     || (!TARGET_FUSE_CMP_AND_BRANCH
20348         && INTVAL (operands[3]) == 128))
20349    && ix86_match_ccmode (insn, CCGCmode)
20350    && peep2_reg_dead_p (1, operands[2])"
20351   [(parallel [(set (match_dup 0)
20352                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20353               (clobber (match_dup 2))])]
20354   "")
20355 \f
20356 (define_peephole2
20357   [(match_scratch:DI 0 "r")
20358    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20359               (clobber (reg:CC FLAGS_REG))
20360               (clobber (mem:BLK (scratch)))])]
20361   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20362   [(clobber (match_dup 0))
20363    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20364               (clobber (mem:BLK (scratch)))])])
20365
20366 (define_peephole2
20367   [(match_scratch:DI 0 "r")
20368    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20369               (clobber (reg:CC FLAGS_REG))
20370               (clobber (mem:BLK (scratch)))])]
20371   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20372   [(clobber (match_dup 0))
20373    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20374    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20375               (clobber (mem:BLK (scratch)))])])
20376
20377 ;; Convert esp subtractions to push.
20378 (define_peephole2
20379   [(match_scratch:DI 0 "r")
20380    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20381               (clobber (reg:CC FLAGS_REG))])]
20382   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20383   [(clobber (match_dup 0))
20384    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20385
20386 (define_peephole2
20387   [(match_scratch:DI 0 "r")
20388    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20391   [(clobber (match_dup 0))
20392    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20393    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20394
20395 ;; Convert epilogue deallocator to pop.
20396 (define_peephole2
20397   [(match_scratch:DI 0 "r")
20398    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20399               (clobber (reg:CC FLAGS_REG))
20400               (clobber (mem:BLK (scratch)))])]
20401   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20402   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20403               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20404               (clobber (mem:BLK (scratch)))])]
20405   "")
20406
20407 ;; Two pops case is tricky, since pop causes dependency on destination register.
20408 ;; We use two registers if available.
20409 (define_peephole2
20410   [(match_scratch:DI 0 "r")
20411    (match_scratch:DI 1 "r")
20412    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20413               (clobber (reg:CC FLAGS_REG))
20414               (clobber (mem:BLK (scratch)))])]
20415   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20416   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20417               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20418               (clobber (mem:BLK (scratch)))])
20419    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20420               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20421   "")
20422
20423 (define_peephole2
20424   [(match_scratch:DI 0 "r")
20425    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20426               (clobber (reg:CC FLAGS_REG))
20427               (clobber (mem:BLK (scratch)))])]
20428   "optimize_insn_for_size_p ()"
20429   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20430               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20431               (clobber (mem:BLK (scratch)))])
20432    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20433               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20434   "")
20435
20436 ;; Convert esp additions to pop.
20437 (define_peephole2
20438   [(match_scratch:DI 0 "r")
20439    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20440               (clobber (reg:CC FLAGS_REG))])]
20441   ""
20442   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20443               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20444   "")
20445
20446 ;; Two pops case is tricky, since pop causes dependency on destination register.
20447 ;; We use two registers if available.
20448 (define_peephole2
20449   [(match_scratch:DI 0 "r")
20450    (match_scratch:DI 1 "r")
20451    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20452               (clobber (reg:CC FLAGS_REG))])]
20453   ""
20454   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20455               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20456    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20457               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20458   "")
20459
20460 (define_peephole2
20461   [(match_scratch:DI 0 "r")
20462    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20463               (clobber (reg:CC FLAGS_REG))])]
20464   "optimize_insn_for_size_p ()"
20465   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20466               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20467    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20468               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20469   "")
20470 \f
20471 ;; Convert imul by three, five and nine into lea
20472 (define_peephole2
20473   [(parallel
20474     [(set (match_operand:SI 0 "register_operand" "")
20475           (mult:SI (match_operand:SI 1 "register_operand" "")
20476                    (match_operand:SI 2 "const_int_operand" "")))
20477      (clobber (reg:CC FLAGS_REG))])]
20478   "INTVAL (operands[2]) == 3
20479    || INTVAL (operands[2]) == 5
20480    || INTVAL (operands[2]) == 9"
20481   [(set (match_dup 0)
20482         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20483                  (match_dup 1)))]
20484   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20485
20486 (define_peephole2
20487   [(parallel
20488     [(set (match_operand:SI 0 "register_operand" "")
20489           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20490                    (match_operand:SI 2 "const_int_operand" "")))
20491      (clobber (reg:CC FLAGS_REG))])]
20492   "optimize_insn_for_speed_p ()
20493    && (INTVAL (operands[2]) == 3
20494        || INTVAL (operands[2]) == 5
20495        || INTVAL (operands[2]) == 9)"
20496   [(set (match_dup 0) (match_dup 1))
20497    (set (match_dup 0)
20498         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20499                  (match_dup 0)))]
20500   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20501
20502 (define_peephole2
20503   [(parallel
20504     [(set (match_operand:DI 0 "register_operand" "")
20505           (mult:DI (match_operand:DI 1 "register_operand" "")
20506                    (match_operand:DI 2 "const_int_operand" "")))
20507      (clobber (reg:CC FLAGS_REG))])]
20508   "TARGET_64BIT
20509    && (INTVAL (operands[2]) == 3
20510        || INTVAL (operands[2]) == 5
20511        || INTVAL (operands[2]) == 9)"
20512   [(set (match_dup 0)
20513         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20514                  (match_dup 1)))]
20515   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20516
20517 (define_peephole2
20518   [(parallel
20519     [(set (match_operand:DI 0 "register_operand" "")
20520           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20521                    (match_operand:DI 2 "const_int_operand" "")))
20522      (clobber (reg:CC FLAGS_REG))])]
20523   "TARGET_64BIT
20524    && optimize_insn_for_speed_p ()
20525    && (INTVAL (operands[2]) == 3
20526        || INTVAL (operands[2]) == 5
20527        || INTVAL (operands[2]) == 9)"
20528   [(set (match_dup 0) (match_dup 1))
20529    (set (match_dup 0)
20530         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20531                  (match_dup 0)))]
20532   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20533
20534 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20535 ;; imul $32bit_imm, reg, reg is direct decoded.
20536 (define_peephole2
20537   [(match_scratch:DI 3 "r")
20538    (parallel [(set (match_operand:DI 0 "register_operand" "")
20539                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20540                             (match_operand:DI 2 "immediate_operand" "")))
20541               (clobber (reg:CC FLAGS_REG))])]
20542   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20543    && !satisfies_constraint_K (operands[2])"
20544   [(set (match_dup 3) (match_dup 1))
20545    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20546               (clobber (reg:CC FLAGS_REG))])]
20547 "")
20548
20549 (define_peephole2
20550   [(match_scratch:SI 3 "r")
20551    (parallel [(set (match_operand:SI 0 "register_operand" "")
20552                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20553                             (match_operand:SI 2 "immediate_operand" "")))
20554               (clobber (reg:CC FLAGS_REG))])]
20555   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20556    && !satisfies_constraint_K (operands[2])"
20557   [(set (match_dup 3) (match_dup 1))
20558    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20559               (clobber (reg:CC FLAGS_REG))])]
20560 "")
20561
20562 (define_peephole2
20563   [(match_scratch:SI 3 "r")
20564    (parallel [(set (match_operand:DI 0 "register_operand" "")
20565                    (zero_extend:DI
20566                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20567                               (match_operand:SI 2 "immediate_operand" ""))))
20568               (clobber (reg:CC FLAGS_REG))])]
20569   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20570    && !satisfies_constraint_K (operands[2])"
20571   [(set (match_dup 3) (match_dup 1))
20572    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20573               (clobber (reg:CC FLAGS_REG))])]
20574 "")
20575
20576 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20577 ;; Convert it into imul reg, reg
20578 ;; It would be better to force assembler to encode instruction using long
20579 ;; immediate, but there is apparently no way to do so.
20580 (define_peephole2
20581   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20582                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20583                             (match_operand:DI 2 "const_int_operand" "")))
20584               (clobber (reg:CC FLAGS_REG))])
20585    (match_scratch:DI 3 "r")]
20586   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20587    && satisfies_constraint_K (operands[2])"
20588   [(set (match_dup 3) (match_dup 2))
20589    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20590               (clobber (reg:CC FLAGS_REG))])]
20591 {
20592   if (!rtx_equal_p (operands[0], operands[1]))
20593     emit_move_insn (operands[0], operands[1]);
20594 })
20595
20596 (define_peephole2
20597   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20598                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20599                             (match_operand:SI 2 "const_int_operand" "")))
20600               (clobber (reg:CC FLAGS_REG))])
20601    (match_scratch:SI 3 "r")]
20602   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20603    && satisfies_constraint_K (operands[2])"
20604   [(set (match_dup 3) (match_dup 2))
20605    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20606               (clobber (reg:CC FLAGS_REG))])]
20607 {
20608   if (!rtx_equal_p (operands[0], operands[1]))
20609     emit_move_insn (operands[0], operands[1]);
20610 })
20611
20612 (define_peephole2
20613   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20614                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20615                             (match_operand:HI 2 "immediate_operand" "")))
20616               (clobber (reg:CC FLAGS_REG))])
20617    (match_scratch:HI 3 "r")]
20618   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20619   [(set (match_dup 3) (match_dup 2))
20620    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20621               (clobber (reg:CC FLAGS_REG))])]
20622 {
20623   if (!rtx_equal_p (operands[0], operands[1]))
20624     emit_move_insn (operands[0], operands[1]);
20625 })
20626
20627 ;; After splitting up read-modify operations, array accesses with memory
20628 ;; operands might end up in form:
20629 ;;  sall    $2, %eax
20630 ;;  movl    4(%esp), %edx
20631 ;;  addl    %edx, %eax
20632 ;; instead of pre-splitting:
20633 ;;  sall    $2, %eax
20634 ;;  addl    4(%esp), %eax
20635 ;; Turn it into:
20636 ;;  movl    4(%esp), %edx
20637 ;;  leal    (%edx,%eax,4), %eax
20638
20639 (define_peephole2
20640   [(parallel [(set (match_operand 0 "register_operand" "")
20641                    (ashift (match_operand 1 "register_operand" "")
20642                            (match_operand 2 "const_int_operand" "")))
20643                (clobber (reg:CC FLAGS_REG))])
20644    (set (match_operand 3 "register_operand")
20645         (match_operand 4 "x86_64_general_operand" ""))
20646    (parallel [(set (match_operand 5 "register_operand" "")
20647                    (plus (match_operand 6 "register_operand" "")
20648                          (match_operand 7 "register_operand" "")))
20649                    (clobber (reg:CC FLAGS_REG))])]
20650   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20651    /* Validate MODE for lea.  */
20652    && ((!TARGET_PARTIAL_REG_STALL
20653         && (GET_MODE (operands[0]) == QImode
20654             || GET_MODE (operands[0]) == HImode))
20655        || GET_MODE (operands[0]) == SImode
20656        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20657    /* We reorder load and the shift.  */
20658    && !rtx_equal_p (operands[1], operands[3])
20659    && !reg_overlap_mentioned_p (operands[0], operands[4])
20660    /* Last PLUS must consist of operand 0 and 3.  */
20661    && !rtx_equal_p (operands[0], operands[3])
20662    && (rtx_equal_p (operands[3], operands[6])
20663        || rtx_equal_p (operands[3], operands[7]))
20664    && (rtx_equal_p (operands[0], operands[6])
20665        || rtx_equal_p (operands[0], operands[7]))
20666    /* The intermediate operand 0 must die or be same as output.  */
20667    && (rtx_equal_p (operands[0], operands[5])
20668        || peep2_reg_dead_p (3, operands[0]))"
20669   [(set (match_dup 3) (match_dup 4))
20670    (set (match_dup 0) (match_dup 1))]
20671 {
20672   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20673   int scale = 1 << INTVAL (operands[2]);
20674   rtx index = gen_lowpart (Pmode, operands[1]);
20675   rtx base = gen_lowpart (Pmode, operands[3]);
20676   rtx dest = gen_lowpart (mode, operands[5]);
20677
20678   operands[1] = gen_rtx_PLUS (Pmode, base,
20679                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20680   if (mode != Pmode)
20681     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20682   operands[0] = dest;
20683 })
20684 \f
20685 ;; Call-value patterns last so that the wildcard operand does not
20686 ;; disrupt insn-recog's switch tables.
20687
20688 (define_insn "*call_value_pop_0"
20689   [(set (match_operand 0 "" "")
20690         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20691               (match_operand:SI 2 "" "")))
20692    (set (reg:SI SP_REG)
20693         (plus:SI (reg:SI SP_REG)
20694                  (match_operand:SI 3 "immediate_operand" "")))]
20695   "!TARGET_64BIT"
20696 {
20697   if (SIBLING_CALL_P (insn))
20698     return "jmp\t%P1";
20699   else
20700     return "call\t%P1";
20701 }
20702   [(set_attr "type" "callv")])
20703
20704 (define_insn "*call_value_pop_1"
20705   [(set (match_operand 0 "" "")
20706         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20707               (match_operand:SI 2 "" "")))
20708    (set (reg:SI SP_REG)
20709         (plus:SI (reg:SI SP_REG)
20710                  (match_operand:SI 3 "immediate_operand" "i")))]
20711   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20712 {
20713   if (constant_call_address_operand (operands[1], Pmode))
20714     return "call\t%P1";
20715   return "call\t%A1";
20716 }
20717   [(set_attr "type" "callv")])
20718
20719 (define_insn "*sibcall_value_pop_1"
20720   [(set (match_operand 0 "" "")
20721         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20722               (match_operand:SI 2 "" "")))
20723    (set (reg:SI SP_REG)
20724         (plus:SI (reg:SI SP_REG)
20725                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20726   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20727   "@
20728    jmp\t%P1
20729    jmp\t%A1"
20730   [(set_attr "type" "callv")])
20731
20732 (define_insn "*call_value_0"
20733   [(set (match_operand 0 "" "")
20734         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20735               (match_operand:SI 2 "" "")))]
20736   "!TARGET_64BIT"
20737 {
20738   if (SIBLING_CALL_P (insn))
20739     return "jmp\t%P1";
20740   else
20741     return "call\t%P1";
20742 }
20743   [(set_attr "type" "callv")])
20744
20745 (define_insn "*call_value_0_rex64"
20746   [(set (match_operand 0 "" "")
20747         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20748               (match_operand:DI 2 "const_int_operand" "")))]
20749   "TARGET_64BIT"
20750 {
20751   if (SIBLING_CALL_P (insn))
20752     return "jmp\t%P1";
20753   else
20754     return "call\t%P1";
20755 }
20756   [(set_attr "type" "callv")])
20757
20758 (define_insn "*call_value_0_rex64_ms_sysv"
20759   [(set (match_operand 0 "" "")
20760         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20761               (match_operand:DI 2 "const_int_operand" "")))
20762    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20763    (clobber (reg:TI XMM6_REG))
20764    (clobber (reg:TI XMM7_REG))
20765    (clobber (reg:TI XMM8_REG))
20766    (clobber (reg:TI XMM9_REG))
20767    (clobber (reg:TI XMM10_REG))
20768    (clobber (reg:TI XMM11_REG))
20769    (clobber (reg:TI XMM12_REG))
20770    (clobber (reg:TI XMM13_REG))
20771    (clobber (reg:TI XMM14_REG))
20772    (clobber (reg:TI XMM15_REG))
20773    (clobber (reg:DI SI_REG))
20774    (clobber (reg:DI DI_REG))]
20775   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20776 {
20777   if (SIBLING_CALL_P (insn))
20778     return "jmp\t%P1";
20779   else
20780     return "call\t%P1";
20781 }
20782   [(set_attr "type" "callv")])
20783
20784 (define_insn "*call_value_1"
20785   [(set (match_operand 0 "" "")
20786         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20787               (match_operand:SI 2 "" "")))]
20788   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20789 {
20790   if (constant_call_address_operand (operands[1], Pmode))
20791     return "call\t%P1";
20792   return "call\t%A1";
20793 }
20794   [(set_attr "type" "callv")])
20795
20796 (define_insn "*sibcall_value_1"
20797   [(set (match_operand 0 "" "")
20798         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20799               (match_operand:SI 2 "" "")))]
20800   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20801   "@
20802    jmp\t%P1
20803    jmp\t%A1"
20804   [(set_attr "type" "callv")])
20805
20806 (define_insn "*call_value_1_rex64"
20807   [(set (match_operand 0 "" "")
20808         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20809               (match_operand:DI 2 "" "")))]
20810   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20811    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20812 {
20813   if (constant_call_address_operand (operands[1], Pmode))
20814     return "call\t%P1";
20815   return "call\t%A1";
20816 }
20817   [(set_attr "type" "callv")])
20818
20819 (define_insn "*call_value_1_rex64_ms_sysv"
20820   [(set (match_operand 0 "" "")
20821         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20822               (match_operand:DI 2 "" "")))
20823    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20824    (clobber (reg:TI XMM6_REG))
20825    (clobber (reg:TI XMM7_REG))
20826    (clobber (reg:TI XMM8_REG))
20827    (clobber (reg:TI XMM9_REG))
20828    (clobber (reg:TI XMM10_REG))
20829    (clobber (reg:TI XMM11_REG))
20830    (clobber (reg:TI XMM12_REG))
20831    (clobber (reg:TI XMM13_REG))
20832    (clobber (reg:TI XMM14_REG))
20833    (clobber (reg:TI XMM15_REG))
20834    (clobber (reg:DI SI_REG))
20835    (clobber (reg:DI DI_REG))]
20836   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20837 {
20838   if (constant_call_address_operand (operands[1], Pmode))
20839     return "call\t%P1";
20840   return "call\t%A1";
20841 }
20842   [(set_attr "type" "callv")])
20843
20844 (define_insn "*call_value_1_rex64_large"
20845   [(set (match_operand 0 "" "")
20846         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20847               (match_operand:DI 2 "" "")))]
20848   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20849   "call\t%A1"
20850   [(set_attr "type" "callv")])
20851
20852 (define_insn "*sibcall_value_1_rex64"
20853   [(set (match_operand 0 "" "")
20854         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20855               (match_operand:DI 2 "" "")))]
20856   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20857   "@
20858    jmp\t%P1
20859    jmp\t%A1"
20860   [(set_attr "type" "callv")])
20861 \f
20862 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20863 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20864 ;; caught for use by garbage collectors and the like.  Using an insn that
20865 ;; maps to SIGILL makes it more likely the program will rightfully die.
20866 ;; Keeping with tradition, "6" is in honor of #UD.
20867 (define_insn "trap"
20868   [(trap_if (const_int 1) (const_int 6))]
20869   ""
20870   { return ASM_SHORT "0x0b0f"; }
20871   [(set_attr "length" "2")])
20872
20873 (define_expand "sse_prologue_save"
20874   [(parallel [(set (match_operand:BLK 0 "" "")
20875                    (unspec:BLK [(reg:DI XMM0_REG)
20876                                 (reg:DI XMM1_REG)
20877                                 (reg:DI XMM2_REG)
20878                                 (reg:DI XMM3_REG)
20879                                 (reg:DI XMM4_REG)
20880                                 (reg:DI XMM5_REG)
20881                                 (reg:DI XMM6_REG)
20882                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20883               (use (match_operand:DI 1 "register_operand" ""))
20884               (use (match_operand:DI 2 "immediate_operand" ""))
20885               (use (label_ref:DI (match_operand 3 "" "")))])]
20886   "TARGET_64BIT"
20887   "")
20888
20889 (define_insn "*sse_prologue_save_insn"
20890   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20891                           (match_operand:DI 4 "const_int_operand" "n")))
20892         (unspec:BLK [(reg:DI XMM0_REG)
20893                      (reg:DI XMM1_REG)
20894                      (reg:DI XMM2_REG)
20895                      (reg:DI XMM3_REG)
20896                      (reg:DI XMM4_REG)
20897                      (reg:DI XMM5_REG)
20898                      (reg:DI XMM6_REG)
20899                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20900    (use (match_operand:DI 1 "register_operand" "r"))
20901    (use (match_operand:DI 2 "const_int_operand" "i"))
20902    (use (label_ref:DI (match_operand 3 "" "X")))]
20903   "TARGET_64BIT
20904    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20905    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20906 {
20907   int i;
20908   operands[0] = gen_rtx_MEM (Pmode,
20909                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20910   /* VEX instruction with a REX prefix will #UD.  */
20911   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20912     gcc_unreachable ();
20913
20914   output_asm_insn ("jmp\t%A1", operands);
20915   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20916     {
20917       operands[4] = adjust_address (operands[0], DImode, i*16);
20918       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20919       PUT_MODE (operands[4], TImode);
20920       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20921         output_asm_insn ("rex", operands);
20922       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20923     }
20924   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20925                                      CODE_LABEL_NUMBER (operands[3]));
20926   return "";
20927 }
20928   [(set_attr "type" "other")
20929    (set_attr "length_immediate" "0")
20930    (set_attr "length_address" "0")
20931    (set (attr "length")
20932      (if_then_else
20933        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20934        (const_string "34")
20935        (const_string "42")))
20936    (set_attr "memory" "store")
20937    (set_attr "modrm" "0")
20938    (set_attr "prefix" "maybe_vex")
20939    (set_attr "mode" "DI")])
20940
20941 (define_expand "prefetch"
20942   [(prefetch (match_operand 0 "address_operand" "")
20943              (match_operand:SI 1 "const_int_operand" "")
20944              (match_operand:SI 2 "const_int_operand" ""))]
20945   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20946 {
20947   int rw = INTVAL (operands[1]);
20948   int locality = INTVAL (operands[2]);
20949
20950   gcc_assert (rw == 0 || rw == 1);
20951   gcc_assert (locality >= 0 && locality <= 3);
20952   gcc_assert (GET_MODE (operands[0]) == Pmode
20953               || GET_MODE (operands[0]) == VOIDmode);
20954
20955   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20956      supported by SSE counterpart or the SSE prefetch is not available
20957      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20958      of locality.  */
20959   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20960     operands[2] = GEN_INT (3);
20961   else
20962     operands[1] = const0_rtx;
20963 })
20964
20965 (define_insn "*prefetch_sse"
20966   [(prefetch (match_operand:SI 0 "address_operand" "p")
20967              (const_int 0)
20968              (match_operand:SI 1 "const_int_operand" ""))]
20969   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20970 {
20971   static const char * const patterns[4] = {
20972    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20973   };
20974
20975   int locality = INTVAL (operands[1]);
20976   gcc_assert (locality >= 0 && locality <= 3);
20977
20978   return patterns[locality];
20979 }
20980   [(set_attr "type" "sse")
20981    (set_attr "atom_sse_attr" "prefetch")
20982    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20983    (set_attr "memory" "none")])
20984
20985 (define_insn "*prefetch_sse_rex"
20986   [(prefetch (match_operand:DI 0 "address_operand" "p")
20987              (const_int 0)
20988              (match_operand:SI 1 "const_int_operand" ""))]
20989   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20990 {
20991   static const char * const patterns[4] = {
20992    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20993   };
20994
20995   int locality = INTVAL (operands[1]);
20996   gcc_assert (locality >= 0 && locality <= 3);
20997
20998   return patterns[locality];
20999 }
21000   [(set_attr "type" "sse")
21001    (set_attr "atom_sse_attr" "prefetch")
21002    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21003    (set_attr "memory" "none")])
21004
21005 (define_insn "*prefetch_3dnow"
21006   [(prefetch (match_operand:SI 0 "address_operand" "p")
21007              (match_operand:SI 1 "const_int_operand" "n")
21008              (const_int 3))]
21009   "TARGET_3DNOW && !TARGET_64BIT"
21010 {
21011   if (INTVAL (operands[1]) == 0)
21012     return "prefetch\t%a0";
21013   else
21014     return "prefetchw\t%a0";
21015 }
21016   [(set_attr "type" "mmx")
21017    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21018    (set_attr "memory" "none")])
21019
21020 (define_insn "*prefetch_3dnow_rex"
21021   [(prefetch (match_operand:DI 0 "address_operand" "p")
21022              (match_operand:SI 1 "const_int_operand" "n")
21023              (const_int 3))]
21024   "TARGET_3DNOW && TARGET_64BIT"
21025 {
21026   if (INTVAL (operands[1]) == 0)
21027     return "prefetch\t%a0";
21028   else
21029     return "prefetchw\t%a0";
21030 }
21031   [(set_attr "type" "mmx")
21032    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21033    (set_attr "memory" "none")])
21034
21035 (define_expand "stack_protect_set"
21036   [(match_operand 0 "memory_operand" "")
21037    (match_operand 1 "memory_operand" "")]
21038   ""
21039 {
21040 #ifdef TARGET_THREAD_SSP_OFFSET
21041   if (TARGET_64BIT)
21042     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21043                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21044   else
21045     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21046                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21047 #else
21048   if (TARGET_64BIT)
21049     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21050   else
21051     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21052 #endif
21053   DONE;
21054 })
21055
21056 (define_insn "stack_protect_set_si"
21057   [(set (match_operand:SI 0 "memory_operand" "=m")
21058         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21059    (set (match_scratch:SI 2 "=&r") (const_int 0))
21060    (clobber (reg:CC FLAGS_REG))]
21061   ""
21062   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21063   [(set_attr "type" "multi")])
21064
21065 (define_insn "stack_protect_set_di"
21066   [(set (match_operand:DI 0 "memory_operand" "=m")
21067         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21068    (set (match_scratch:DI 2 "=&r") (const_int 0))
21069    (clobber (reg:CC FLAGS_REG))]
21070   "TARGET_64BIT"
21071   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21072   [(set_attr "type" "multi")])
21073
21074 (define_insn "stack_tls_protect_set_si"
21075   [(set (match_operand:SI 0 "memory_operand" "=m")
21076         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21077    (set (match_scratch:SI 2 "=&r") (const_int 0))
21078    (clobber (reg:CC FLAGS_REG))]
21079   ""
21080   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21081   [(set_attr "type" "multi")])
21082
21083 (define_insn "stack_tls_protect_set_di"
21084   [(set (match_operand:DI 0 "memory_operand" "=m")
21085         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21086    (set (match_scratch:DI 2 "=&r") (const_int 0))
21087    (clobber (reg:CC FLAGS_REG))]
21088   "TARGET_64BIT"
21089   {
21090      /* The kernel uses a different segment register for performance reasons; a
21091         system call would not have to trash the userspace segment register,
21092         which would be expensive */
21093      if (ix86_cmodel != CM_KERNEL)
21094         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21095      else
21096         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21097   }
21098   [(set_attr "type" "multi")])
21099
21100 (define_expand "stack_protect_test"
21101   [(match_operand 0 "memory_operand" "")
21102    (match_operand 1 "memory_operand" "")
21103    (match_operand 2 "" "")]
21104   ""
21105 {
21106   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21107
21108 #ifdef TARGET_THREAD_SSP_OFFSET
21109   if (TARGET_64BIT)
21110     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21111                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21112   else
21113     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21114                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21115 #else
21116   if (TARGET_64BIT)
21117     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21118   else
21119     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21120 #endif
21121
21122   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21123                                   flags, const0_rtx, operands[2]));
21124   DONE;
21125 })
21126
21127 (define_insn "stack_protect_test_si"
21128   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21129         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21130                      (match_operand:SI 2 "memory_operand" "m")]
21131                     UNSPEC_SP_TEST))
21132    (clobber (match_scratch:SI 3 "=&r"))]
21133   ""
21134   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21135   [(set_attr "type" "multi")])
21136
21137 (define_insn "stack_protect_test_di"
21138   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21139         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21140                      (match_operand:DI 2 "memory_operand" "m")]
21141                     UNSPEC_SP_TEST))
21142    (clobber (match_scratch:DI 3 "=&r"))]
21143   "TARGET_64BIT"
21144   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21145   [(set_attr "type" "multi")])
21146
21147 (define_insn "stack_tls_protect_test_si"
21148   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21149         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21150                      (match_operand:SI 2 "const_int_operand" "i")]
21151                     UNSPEC_SP_TLS_TEST))
21152    (clobber (match_scratch:SI 3 "=r"))]
21153   ""
21154   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21155   [(set_attr "type" "multi")])
21156
21157 (define_insn "stack_tls_protect_test_di"
21158   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21159         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21160                      (match_operand:DI 2 "const_int_operand" "i")]
21161                     UNSPEC_SP_TLS_TEST))
21162    (clobber (match_scratch:DI 3 "=r"))]
21163   "TARGET_64BIT"
21164   {
21165      /* The kernel uses a different segment register for performance reasons; a
21166         system call would not have to trash the userspace segment register,
21167         which would be expensive */
21168      if (ix86_cmodel != CM_KERNEL)
21169         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21170      else
21171         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21172   }
21173   [(set_attr "type" "multi")])
21174
21175 (define_insn "sse4_2_crc32<mode>"
21176   [(set (match_operand:SI 0 "register_operand" "=r")
21177         (unspec:SI
21178           [(match_operand:SI 1 "register_operand" "0")
21179            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
21180           UNSPEC_CRC32))]
21181   "TARGET_SSE4_2 || TARGET_CRC32"
21182   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
21183   [(set_attr "type" "sselog1")
21184    (set_attr "prefix_rep" "1")
21185    (set_attr "prefix_extra" "1")
21186    (set (attr "prefix_data16")
21187      (if_then_else (match_operand:HI 2 "" "")
21188        (const_string "1")
21189        (const_string "*")))
21190    (set (attr "prefix_rex")
21191      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21192        (const_string "1")
21193        (const_string "*")))
21194    (set_attr "mode" "SI")])
21195
21196 (define_insn "sse4_2_crc32di"
21197   [(set (match_operand:DI 0 "register_operand" "=r")
21198         (unspec:DI
21199           [(match_operand:DI 1 "register_operand" "0")
21200            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21201           UNSPEC_CRC32))]
21202   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21203   "crc32{q}\t{%2, %0|%0, %2}"
21204   [(set_attr "type" "sselog1")
21205    (set_attr "prefix_rep" "1")
21206    (set_attr "prefix_extra" "1")
21207    (set_attr "mode" "DI")])
21208
21209 (define_expand "rdpmc"
21210   [(match_operand:DI 0 "register_operand" "")
21211    (match_operand:SI 1 "register_operand" "")]
21212   ""
21213 {
21214   rtx reg = gen_reg_rtx (DImode);
21215   rtx si;
21216
21217   /* Force operand 1 into ECX.  */
21218   rtx ecx = gen_rtx_REG (SImode, CX_REG);
21219   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21220   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21221                                 UNSPECV_RDPMC);
21222
21223   if (TARGET_64BIT)
21224     {
21225       rtvec vec = rtvec_alloc (2);
21226       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21227       rtx upper = gen_reg_rtx (DImode);
21228       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21229                                         gen_rtvec (1, const0_rtx),
21230                                         UNSPECV_RDPMC);
21231       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21232       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21233       emit_insn (load);
21234       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21235                                    NULL, 1, OPTAB_DIRECT);
21236       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21237                                  OPTAB_DIRECT);
21238     }
21239   else
21240     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21241   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21242   DONE;
21243 })
21244
21245 (define_insn "*rdpmc"
21246   [(set (match_operand:DI 0 "register_operand" "=A")
21247         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21248                             UNSPECV_RDPMC))]
21249   "!TARGET_64BIT"
21250   "rdpmc"
21251   [(set_attr "type" "other")
21252    (set_attr "length" "2")])
21253
21254 (define_insn "*rdpmc_rex64"
21255   [(set (match_operand:DI 0 "register_operand" "=a")
21256         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21257                             UNSPECV_RDPMC))
21258   (set (match_operand:DI 1 "register_operand" "=d")
21259        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21260   "TARGET_64BIT"
21261   "rdpmc"
21262   [(set_attr "type" "other")
21263    (set_attr "length" "2")])
21264
21265 (define_expand "rdtsc"
21266   [(set (match_operand:DI 0 "register_operand" "")
21267         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21268   ""
21269 {
21270   if (TARGET_64BIT)
21271     {
21272       rtvec vec = rtvec_alloc (2);
21273       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21274       rtx upper = gen_reg_rtx (DImode);
21275       rtx lower = gen_reg_rtx (DImode);
21276       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21277                                          gen_rtvec (1, const0_rtx),
21278                                          UNSPECV_RDTSC);
21279       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21280       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21281       emit_insn (load);
21282       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21283                                    NULL, 1, OPTAB_DIRECT);
21284       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21285                                    OPTAB_DIRECT);
21286       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21287       DONE;
21288     }
21289 })
21290
21291 (define_insn "*rdtsc"
21292   [(set (match_operand:DI 0 "register_operand" "=A")
21293         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21294   "!TARGET_64BIT"
21295   "rdtsc"
21296   [(set_attr "type" "other")
21297    (set_attr "length" "2")])
21298
21299 (define_insn "*rdtsc_rex64"
21300   [(set (match_operand:DI 0 "register_operand" "=a")
21301         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21302    (set (match_operand:DI 1 "register_operand" "=d")
21303         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21304   "TARGET_64BIT"
21305   "rdtsc"
21306   [(set_attr "type" "other")
21307    (set_attr "length" "2")])
21308
21309 (define_expand "rdtscp"
21310   [(match_operand:DI 0 "register_operand" "")
21311    (match_operand:SI 1 "memory_operand" "")]
21312   ""
21313 {
21314   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21315                                     gen_rtvec (1, const0_rtx),
21316                                     UNSPECV_RDTSCP);
21317   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21318                                     gen_rtvec (1, const0_rtx),
21319                                     UNSPECV_RDTSCP);
21320   rtx reg = gen_reg_rtx (DImode);
21321   rtx tmp = gen_reg_rtx (SImode);
21322
21323   if (TARGET_64BIT)
21324     {
21325       rtvec vec = rtvec_alloc (3);
21326       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21327       rtx upper = gen_reg_rtx (DImode);
21328       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21329       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21330       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21331       emit_insn (load);
21332       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21333                                    NULL, 1, OPTAB_DIRECT);
21334       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21335                                  OPTAB_DIRECT);
21336     }
21337   else
21338     {
21339       rtvec vec = rtvec_alloc (2);
21340       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21341       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21342       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21343       emit_insn (load);
21344     }
21345   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21346   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21347   DONE;
21348 })
21349
21350 (define_insn "*rdtscp"
21351   [(set (match_operand:DI 0 "register_operand" "=A")
21352         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21353    (set (match_operand:SI 1 "register_operand" "=c")
21354         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21355   "!TARGET_64BIT"
21356   "rdtscp"
21357   [(set_attr "type" "other")
21358    (set_attr "length" "3")])
21359
21360 (define_insn "*rdtscp_rex64"
21361   [(set (match_operand:DI 0 "register_operand" "=a")
21362         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21363    (set (match_operand:DI 1 "register_operand" "=d")
21364         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21365    (set (match_operand:SI 2 "register_operand" "=c")
21366         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21367   "TARGET_64BIT"
21368   "rdtscp"
21369   [(set_attr "type" "other")
21370    (set_attr "length" "3")])
21371
21372 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21373 ;;
21374 ;; LWP instructions
21375 ;;
21376 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21377
21378 (define_insn "lwp_llwpcbhi1"
21379   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21380            UNSPEC_LLWP_INTRINSIC)]
21381   "TARGET_LWP"
21382   "llwpcb\t%0"
21383   [(set_attr "type" "lwp")
21384    (set_attr "mode" "HI")])
21385
21386 (define_insn "lwp_llwpcbsi1"
21387   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21388            UNSPEC_LLWP_INTRINSIC)]
21389   "TARGET_LWP"
21390   "llwpcb\t%0"
21391   [(set_attr "type" "lwp")
21392    (set_attr "mode" "SI")])
21393
21394 (define_insn "lwp_llwpcbdi1"
21395   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21396            UNSPEC_LLWP_INTRINSIC)]
21397   "TARGET_LWP"
21398   "llwpcb\t%0"
21399   [(set_attr "type" "lwp")
21400    (set_attr "mode" "DI")])
21401
21402 (define_insn "lwp_slwpcbhi1"
21403   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21404            UNSPEC_SLWP_INTRINSIC)]
21405   "TARGET_LWP"
21406   "slwpcb\t%0"
21407   [(set_attr "type" "lwp")
21408    (set_attr "mode" "HI")])
21409
21410 (define_insn "lwp_slwpcbsi1"
21411   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21412            UNSPEC_SLWP_INTRINSIC)]
21413   "TARGET_LWP"
21414   "slwpcb\t%0"
21415   [(set_attr "type" "lwp")
21416    (set_attr "mode" "SI")])
21417
21418 (define_insn "lwp_slwpcbdi1"
21419   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21420            UNSPEC_SLWP_INTRINSIC)]
21421   "TARGET_LWP"
21422   "slwpcb\t%0"
21423   [(set_attr "type" "lwp")
21424    (set_attr "mode" "DI")])
21425
21426 (define_insn "lwp_lwpvalhi3"
21427   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21428                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21429                      (match_operand:HI 2 "const_int_operand" "")]
21430                     UNSPECV_LWPVAL_INTRINSIC)]
21431   "TARGET_LWP"
21432   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21433   [(set_attr "type" "lwp")
21434    (set_attr "mode" "HI")])
21435
21436 (define_insn "lwp_lwpvalsi3"
21437   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21438                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21439                      (match_operand:SI 2 "const_int_operand" "")]
21440                     UNSPECV_LWPVAL_INTRINSIC)]
21441   "TARGET_LWP"
21442   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21443   [(set_attr "type" "lwp")
21444    (set_attr "mode" "SI")])
21445
21446 (define_insn "lwp_lwpvaldi3"
21447   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21448                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21449                      (match_operand:SI 2 "const_int_operand" "")]
21450                     UNSPECV_LWPVAL_INTRINSIC)]
21451   "TARGET_LWP"
21452   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21453   [(set_attr "type" "lwp")
21454    (set_attr "mode" "DI")])
21455
21456 (define_insn "lwp_lwpinshi3"
21457   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21458                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21459                      (match_operand:HI 2 "const_int_operand" "")]
21460                     UNSPECV_LWPINS_INTRINSIC)]
21461   "TARGET_LWP"
21462   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21463   [(set_attr "type" "lwp")
21464    (set_attr "mode" "HI")])
21465
21466 (define_insn "lwp_lwpinssi3"
21467   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21468                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21469                      (match_operand:SI 2 "const_int_operand" "")]
21470                     UNSPECV_LWPINS_INTRINSIC)]
21471   "TARGET_LWP"
21472   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21473   [(set_attr "type" "lwp")
21474    (set_attr "mode" "SI")])
21475
21476 (define_insn "lwp_lwpinsdi3"
21477   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21478                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21479                      (match_operand:SI 2 "const_int_operand" "")]
21480                     UNSPECV_LWPINS_INTRINSIC)]
21481   "TARGET_LWP"
21482   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21483   [(set_attr "type" "lwp")
21484    (set_attr "mode" "DI")])
21485
21486 (include "mmx.md")
21487 (include "sse.md")
21488 (include "sync.md")