OSDN Git Service

* config/i386/i386.md (plusminus_carry_mnemonic): New code attribute.
[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 QImode.
751 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
752
753 ;; Single word integer modes without QImode and HImode.
754 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
755
756 ;; All math-dependant single and double word integer modes.
757 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
758                              (HI "TARGET_HIMODE_MATH")
759                              SI DI (TI "TARGET_64BIT")])
760
761 ;; Math-dependant single word integer modes.
762 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
763                             (HI "TARGET_HIMODE_MATH")
764                             SI (DI "TARGET_64BIT")])
765
766 ;; Math-dependant single word integer modes without QImode.
767 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
768                                SI (DI "TARGET_64BIT")])
769
770 ;; Half mode for double word integer modes.
771 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
772                             (DI "TARGET_64BIT")])
773
774 ;; Double word integer modes.
775 (define_mode_attr DWI [(SI "DI") (DI "TI")])
776 (define_mode_attr dwi [(SI "di") (DI "ti")])
777
778 ;; Instruction suffix for integer modes.
779 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
780
781 ;; Register class for integer modes.
782 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
783
784 ;; Immediate operand constraint for integer modes.
785 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
786
787 ;; General operand constraint for word modes.
788 (define_mode_attr g [(SI "g") (DI "rme")])
789
790 ;; Immediate operand constraint for double integer modes.
791 (define_mode_attr di [(SI "iF") (DI "e")])
792
793 ;; General operand predicate for integer modes.
794 (define_mode_attr general_operand
795         [(QI "general_operand")
796          (HI "general_operand")
797          (SI "general_operand")
798          (DI "x86_64_general_operand")
799          (TI "x86_64_general_operand")])
800
801 ;; SSE and x87 SFmode and DFmode floating point modes
802 (define_mode_iterator MODEF [SF DF])
803
804 ;; All x87 floating point modes
805 (define_mode_iterator X87MODEF [SF DF XF])
806
807 ;; All integer modes handled by x87 fisttp operator.
808 (define_mode_iterator X87MODEI [HI SI DI])
809
810 ;; All integer modes handled by integer x87 operators.
811 (define_mode_iterator X87MODEI12 [HI SI])
812
813 ;; All integer modes handled by SSE cvtts?2si* operators.
814 (define_mode_iterator SSEMODEI24 [SI DI])
815
816 ;; SSE asm suffix for floating point modes
817 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
818
819 ;; SSE vector mode corresponding to a scalar mode
820 (define_mode_attr ssevecmode
821   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
822
823 ;; Instruction suffix for REX 64bit operators.
824 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
825
826 ;; This mode iterator allows :P to be used for patterns that operate on
827 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
828 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
829 \f
830 ;; Scheduling descriptions
831
832 (include "pentium.md")
833 (include "ppro.md")
834 (include "k6.md")
835 (include "athlon.md")
836 (include "geode.md")
837 (include "atom.md")
838
839 \f
840 ;; Operand and operator predicates and constraints
841
842 (include "predicates.md")
843 (include "constraints.md")
844
845 \f
846 ;; Compare and branch/compare and store instructions.
847
848 (define_expand "cbranch<mode>4"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
851                     (match_operand:SDWIM 2 "<general_operand>" "")))
852    (set (pc) (if_then_else
853                (match_operator 0 "comparison_operator"
854                 [(reg:CC FLAGS_REG) (const_int 0)])
855                (label_ref (match_operand 3 "" ""))
856                (pc)))]
857   ""
858 {
859   if (MEM_P (operands[1]) && MEM_P (operands[2]))
860     operands[1] = force_reg (<MODE>mode, operands[1]);
861   ix86_compare_op0 = operands[1];
862   ix86_compare_op1 = operands[2];
863   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
864   DONE;
865 })
866
867 (define_expand "cstore<mode>4"
868   [(set (reg:CC FLAGS_REG)
869         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
870                     (match_operand:SWIM 3 "<general_operand>" "")))
871    (set (match_operand:QI 0 "register_operand" "")
872         (match_operator 1 "comparison_operator"
873           [(reg:CC FLAGS_REG) (const_int 0)]))]
874   ""
875 {
876   if (MEM_P (operands[2]) && MEM_P (operands[3]))
877     operands[2] = force_reg (<MODE>mode, operands[2]);
878   ix86_compare_op0 = operands[2];
879   ix86_compare_op1 = operands[3];
880   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
881   DONE;
882 })
883
884 (define_expand "cmp<mode>_1"
885   [(set (reg:CC FLAGS_REG)
886         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
887                     (match_operand:SWI48 1 "<general_operand>" "")))]
888   ""
889   "")
890
891 (define_insn "*cmp<mode>_ccno_1"
892   [(set (reg FLAGS_REG)
893         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
894                  (match_operand:SWI 1 "const0_operand" "")))]
895   "ix86_match_ccmode (insn, CCNOmode)"
896   "@
897    test{<imodesuffix>}\t%0, %0
898    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
899   [(set_attr "type" "test,icmp")
900    (set_attr "length_immediate" "0,1")
901    (set_attr "mode" "<MODE>")])
902
903 (define_insn "*cmp<mode>_1"
904   [(set (reg FLAGS_REG)
905         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
906                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
907   "ix86_match_ccmode (insn, CCmode)"
908   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
909   [(set_attr "type" "icmp")
910    (set_attr "mode" "<MODE>")])
911
912 (define_insn "*cmp<mode>_minus_1"
913   [(set (reg FLAGS_REG)
914         (compare
915           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
916                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
917           (const_int 0)))]
918   "ix86_match_ccmode (insn, CCGOCmode)"
919   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
920   [(set_attr "type" "icmp")
921    (set_attr "mode" "<MODE>")])
922
923 (define_insn "*cmpqi_ext_1"
924   [(set (reg FLAGS_REG)
925         (compare
926           (match_operand:QI 0 "general_operand" "Qm")
927           (subreg:QI
928             (zero_extract:SI
929               (match_operand 1 "ext_register_operand" "Q")
930               (const_int 8)
931               (const_int 8)) 0)))]
932   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
933   "cmp{b}\t{%h1, %0|%0, %h1}"
934   [(set_attr "type" "icmp")
935    (set_attr "mode" "QI")])
936
937 (define_insn "*cmpqi_ext_1_rex64"
938   [(set (reg FLAGS_REG)
939         (compare
940           (match_operand:QI 0 "register_operand" "Q")
941           (subreg:QI
942             (zero_extract:SI
943               (match_operand 1 "ext_register_operand" "Q")
944               (const_int 8)
945               (const_int 8)) 0)))]
946   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
947   "cmp{b}\t{%h1, %0|%0, %h1}"
948   [(set_attr "type" "icmp")
949    (set_attr "mode" "QI")])
950
951 (define_insn "*cmpqi_ext_2"
952   [(set (reg FLAGS_REG)
953         (compare
954           (subreg:QI
955             (zero_extract:SI
956               (match_operand 0 "ext_register_operand" "Q")
957               (const_int 8)
958               (const_int 8)) 0)
959           (match_operand:QI 1 "const0_operand" "")))]
960   "ix86_match_ccmode (insn, CCNOmode)"
961   "test{b}\t%h0, %h0"
962   [(set_attr "type" "test")
963    (set_attr "length_immediate" "0")
964    (set_attr "mode" "QI")])
965
966 (define_expand "cmpqi_ext_3"
967   [(set (reg:CC FLAGS_REG)
968         (compare:CC
969           (subreg:QI
970             (zero_extract:SI
971               (match_operand 0 "ext_register_operand" "")
972               (const_int 8)
973               (const_int 8)) 0)
974           (match_operand:QI 1 "immediate_operand" "")))]
975   ""
976   "")
977
978 (define_insn "*cmpqi_ext_3_insn"
979   [(set (reg FLAGS_REG)
980         (compare
981           (subreg:QI
982             (zero_extract:SI
983               (match_operand 0 "ext_register_operand" "Q")
984               (const_int 8)
985               (const_int 8)) 0)
986           (match_operand:QI 1 "general_operand" "Qmn")))]
987   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
988   "cmp{b}\t{%1, %h0|%h0, %1}"
989   [(set_attr "type" "icmp")
990    (set_attr "modrm" "1")
991    (set_attr "mode" "QI")])
992
993 (define_insn "*cmpqi_ext_3_insn_rex64"
994   [(set (reg FLAGS_REG)
995         (compare
996           (subreg:QI
997             (zero_extract:SI
998               (match_operand 0 "ext_register_operand" "Q")
999               (const_int 8)
1000               (const_int 8)) 0)
1001           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1002   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1003   "cmp{b}\t{%1, %h0|%h0, %1}"
1004   [(set_attr "type" "icmp")
1005    (set_attr "modrm" "1")
1006    (set_attr "mode" "QI")])
1007
1008 (define_insn "*cmpqi_ext_4"
1009   [(set (reg FLAGS_REG)
1010         (compare
1011           (subreg:QI
1012             (zero_extract:SI
1013               (match_operand 0 "ext_register_operand" "Q")
1014               (const_int 8)
1015               (const_int 8)) 0)
1016           (subreg:QI
1017             (zero_extract:SI
1018               (match_operand 1 "ext_register_operand" "Q")
1019               (const_int 8)
1020               (const_int 8)) 0)))]
1021   "ix86_match_ccmode (insn, CCmode)"
1022   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1023   [(set_attr "type" "icmp")
1024    (set_attr "mode" "QI")])
1025
1026 ;; These implement float point compares.
1027 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1028 ;; which would allow mix and match FP modes on the compares.  Which is what
1029 ;; the old patterns did, but with many more of them.
1030
1031 (define_expand "cbranchxf4"
1032   [(set (reg:CC FLAGS_REG)
1033         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1034                     (match_operand:XF 2 "nonmemory_operand" "")))
1035    (set (pc) (if_then_else
1036               (match_operator 0 "ix86_fp_comparison_operator"
1037                [(reg:CC FLAGS_REG)
1038                 (const_int 0)])
1039               (label_ref (match_operand 3 "" ""))
1040               (pc)))]
1041   "TARGET_80387"
1042 {
1043   ix86_compare_op0 = operands[1];
1044   ix86_compare_op1 = operands[2];
1045   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1046   DONE;
1047 })
1048
1049 (define_expand "cstorexf4"
1050   [(set (reg:CC FLAGS_REG)
1051         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1052                     (match_operand:XF 3 "nonmemory_operand" "")))
1053    (set (match_operand:QI 0 "register_operand" "")
1054               (match_operator 1 "ix86_fp_comparison_operator"
1055                [(reg:CC FLAGS_REG)
1056                 (const_int 0)]))]
1057   "TARGET_80387"
1058 {
1059   ix86_compare_op0 = operands[2];
1060   ix86_compare_op1 = operands[3];
1061   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1062   DONE;
1063 })
1064
1065 (define_expand "cbranch<mode>4"
1066   [(set (reg:CC FLAGS_REG)
1067         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1068                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1069    (set (pc) (if_then_else
1070               (match_operator 0 "ix86_fp_comparison_operator"
1071                [(reg:CC FLAGS_REG)
1072                 (const_int 0)])
1073               (label_ref (match_operand 3 "" ""))
1074               (pc)))]
1075   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1076 {
1077   ix86_compare_op0 = operands[1];
1078   ix86_compare_op1 = operands[2];
1079   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1080   DONE;
1081 })
1082
1083 (define_expand "cstore<mode>4"
1084   [(set (reg:CC FLAGS_REG)
1085         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1086                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1087    (set (match_operand:QI 0 "register_operand" "")
1088               (match_operator 1 "ix86_fp_comparison_operator"
1089                [(reg:CC FLAGS_REG)
1090                 (const_int 0)]))]
1091   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1092 {
1093   ix86_compare_op0 = operands[2];
1094   ix86_compare_op1 = operands[3];
1095   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1096   DONE;
1097 })
1098
1099 (define_expand "cbranchcc4"
1100   [(set (pc) (if_then_else
1101               (match_operator 0 "comparison_operator"
1102                [(match_operand 1 "flags_reg_operand" "")
1103                 (match_operand 2 "const0_operand" "")])
1104               (label_ref (match_operand 3 "" ""))
1105               (pc)))]
1106   ""
1107 {
1108   ix86_compare_op0 = operands[1];
1109   ix86_compare_op1 = operands[2];
1110   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1111   DONE;
1112 })
1113
1114 (define_expand "cstorecc4"
1115   [(set (match_operand:QI 0 "register_operand" "")
1116               (match_operator 1 "comparison_operator"
1117                [(match_operand 2 "flags_reg_operand" "")
1118                 (match_operand 3 "const0_operand" "")]))]
1119   ""
1120 {
1121   ix86_compare_op0 = operands[2];
1122   ix86_compare_op1 = operands[3];
1123   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1124   DONE;
1125 })
1126
1127
1128 ;; FP compares, step 1:
1129 ;; Set the FP condition codes.
1130 ;;
1131 ;; CCFPmode     compare with exceptions
1132 ;; CCFPUmode    compare with no exceptions
1133
1134 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1135 ;; used to manage the reg stack popping would not be preserved.
1136
1137 (define_insn "*cmpfp_0"
1138   [(set (match_operand:HI 0 "register_operand" "=a")
1139         (unspec:HI
1140           [(compare:CCFP
1141              (match_operand 1 "register_operand" "f")
1142              (match_operand 2 "const0_operand" ""))]
1143         UNSPEC_FNSTSW))]
1144   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1145    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1146   "* return output_fp_compare (insn, operands, 0, 0);"
1147   [(set_attr "type" "multi")
1148    (set_attr "unit" "i387")
1149    (set (attr "mode")
1150      (cond [(match_operand:SF 1 "" "")
1151               (const_string "SF")
1152             (match_operand:DF 1 "" "")
1153               (const_string "DF")
1154            ]
1155            (const_string "XF")))])
1156
1157 (define_insn_and_split "*cmpfp_0_cc"
1158   [(set (reg:CCFP FLAGS_REG)
1159         (compare:CCFP
1160           (match_operand 1 "register_operand" "f")
1161           (match_operand 2 "const0_operand" "")))
1162    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1163   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1164    && TARGET_SAHF && !TARGET_CMOVE
1165    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1166   "#"
1167   "&& reload_completed"
1168   [(set (match_dup 0)
1169         (unspec:HI
1170           [(compare:CCFP (match_dup 1)(match_dup 2))]
1171         UNSPEC_FNSTSW))
1172    (set (reg:CC FLAGS_REG)
1173         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1174   ""
1175   [(set_attr "type" "multi")
1176    (set_attr "unit" "i387")
1177    (set (attr "mode")
1178      (cond [(match_operand:SF 1 "" "")
1179               (const_string "SF")
1180             (match_operand:DF 1 "" "")
1181               (const_string "DF")
1182            ]
1183            (const_string "XF")))])
1184
1185 (define_insn "*cmpfp_xf"
1186   [(set (match_operand:HI 0 "register_operand" "=a")
1187         (unspec:HI
1188           [(compare:CCFP
1189              (match_operand:XF 1 "register_operand" "f")
1190              (match_operand:XF 2 "register_operand" "f"))]
1191           UNSPEC_FNSTSW))]
1192   "TARGET_80387"
1193   "* return output_fp_compare (insn, operands, 0, 0);"
1194   [(set_attr "type" "multi")
1195    (set_attr "unit" "i387")
1196    (set_attr "mode" "XF")])
1197
1198 (define_insn_and_split "*cmpfp_xf_cc"
1199   [(set (reg:CCFP FLAGS_REG)
1200         (compare:CCFP
1201           (match_operand:XF 1 "register_operand" "f")
1202           (match_operand:XF 2 "register_operand" "f")))
1203    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1204   "TARGET_80387
1205    && TARGET_SAHF && !TARGET_CMOVE"
1206   "#"
1207   "&& reload_completed"
1208   [(set (match_dup 0)
1209         (unspec:HI
1210           [(compare:CCFP (match_dup 1)(match_dup 2))]
1211         UNSPEC_FNSTSW))
1212    (set (reg:CC FLAGS_REG)
1213         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1214   ""
1215   [(set_attr "type" "multi")
1216    (set_attr "unit" "i387")
1217    (set_attr "mode" "XF")])
1218
1219 (define_insn "*cmpfp_<mode>"
1220   [(set (match_operand:HI 0 "register_operand" "=a")
1221         (unspec:HI
1222           [(compare:CCFP
1223              (match_operand:MODEF 1 "register_operand" "f")
1224              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1225           UNSPEC_FNSTSW))]
1226   "TARGET_80387"
1227   "* return output_fp_compare (insn, operands, 0, 0);"
1228   [(set_attr "type" "multi")
1229    (set_attr "unit" "i387")
1230    (set_attr "mode" "<MODE>")])
1231
1232 (define_insn_and_split "*cmpfp_<mode>_cc"
1233   [(set (reg:CCFP FLAGS_REG)
1234         (compare:CCFP
1235           (match_operand:MODEF 1 "register_operand" "f")
1236           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1237    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1238   "TARGET_80387
1239    && TARGET_SAHF && !TARGET_CMOVE"
1240   "#"
1241   "&& reload_completed"
1242   [(set (match_dup 0)
1243         (unspec:HI
1244           [(compare:CCFP (match_dup 1)(match_dup 2))]
1245         UNSPEC_FNSTSW))
1246    (set (reg:CC FLAGS_REG)
1247         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1248   ""
1249   [(set_attr "type" "multi")
1250    (set_attr "unit" "i387")
1251    (set_attr "mode" "<MODE>")])
1252
1253 (define_insn "*cmpfp_u"
1254   [(set (match_operand:HI 0 "register_operand" "=a")
1255         (unspec:HI
1256           [(compare:CCFPU
1257              (match_operand 1 "register_operand" "f")
1258              (match_operand 2 "register_operand" "f"))]
1259           UNSPEC_FNSTSW))]
1260   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1262   "* return output_fp_compare (insn, operands, 0, 1);"
1263   [(set_attr "type" "multi")
1264    (set_attr "unit" "i387")
1265    (set (attr "mode")
1266      (cond [(match_operand:SF 1 "" "")
1267               (const_string "SF")
1268             (match_operand:DF 1 "" "")
1269               (const_string "DF")
1270            ]
1271            (const_string "XF")))])
1272
1273 (define_insn_and_split "*cmpfp_u_cc"
1274   [(set (reg:CCFPU FLAGS_REG)
1275         (compare:CCFPU
1276           (match_operand 1 "register_operand" "f")
1277           (match_operand 2 "register_operand" "f")))
1278    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1279   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1280    && TARGET_SAHF && !TARGET_CMOVE
1281    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1282   "#"
1283   "&& reload_completed"
1284   [(set (match_dup 0)
1285         (unspec:HI
1286           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1287         UNSPEC_FNSTSW))
1288    (set (reg:CC FLAGS_REG)
1289         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290   ""
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set (attr "mode")
1294      (cond [(match_operand:SF 1 "" "")
1295               (const_string "SF")
1296             (match_operand:DF 1 "" "")
1297               (const_string "DF")
1298            ]
1299            (const_string "XF")))])
1300
1301 (define_insn "*cmpfp_<mode>"
1302   [(set (match_operand:HI 0 "register_operand" "=a")
1303         (unspec:HI
1304           [(compare:CCFP
1305              (match_operand 1 "register_operand" "f")
1306              (match_operator 3 "float_operator"
1307                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1308           UNSPEC_FNSTSW))]
1309   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1310    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1311    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1312   "* return output_fp_compare (insn, operands, 0, 0);"
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "fp_int_src" "true")
1316    (set_attr "mode" "<MODE>")])
1317
1318 (define_insn_and_split "*cmpfp_<mode>_cc"
1319   [(set (reg:CCFP FLAGS_REG)
1320         (compare:CCFP
1321           (match_operand 1 "register_operand" "f")
1322           (match_operator 3 "float_operator"
1323             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1324    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1326    && TARGET_SAHF && !TARGET_CMOVE
1327    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1328    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1329   "#"
1330   "&& reload_completed"
1331   [(set (match_dup 0)
1332         (unspec:HI
1333           [(compare:CCFP
1334              (match_dup 1)
1335              (match_op_dup 3 [(match_dup 2)]))]
1336         UNSPEC_FNSTSW))
1337    (set (reg:CC FLAGS_REG)
1338         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1339   ""
1340   [(set_attr "type" "multi")
1341    (set_attr "unit" "i387")
1342    (set_attr "fp_int_src" "true")
1343    (set_attr "mode" "<MODE>")])
1344
1345 ;; FP compares, step 2
1346 ;; Move the fpsw to ax.
1347
1348 (define_insn "x86_fnstsw_1"
1349   [(set (match_operand:HI 0 "register_operand" "=a")
1350         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1351   "TARGET_80387"
1352   "fnstsw\t%0"
1353   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1354    (set_attr "mode" "SI")
1355    (set_attr "unit" "i387")])
1356
1357 ;; FP compares, step 3
1358 ;; Get ax into flags, general case.
1359
1360 (define_insn "x86_sahf_1"
1361   [(set (reg:CC FLAGS_REG)
1362         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1363                    UNSPEC_SAHF))]
1364   "TARGET_SAHF"
1365 {
1366 #ifdef HAVE_AS_IX86_SAHF
1367   return "sahf";
1368 #else
1369   return ASM_BYTE "0x9e";
1370 #endif
1371 }
1372   [(set_attr "length" "1")
1373    (set_attr "athlon_decode" "vector")
1374    (set_attr "amdfam10_decode" "direct")
1375    (set_attr "mode" "SI")])
1376
1377 ;; Pentium Pro can do steps 1 through 3 in one go.
1378 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1379 (define_insn "*cmpfp_i_mixed"
1380   [(set (reg:CCFP FLAGS_REG)
1381         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1382                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1383   "TARGET_MIX_SSE_I387
1384    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1385    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1386   "* return output_fp_compare (insn, operands, 1, 0);"
1387   [(set_attr "type" "fcmp,ssecomi")
1388    (set_attr "prefix" "orig,maybe_vex")
1389    (set (attr "mode")
1390      (if_then_else (match_operand:SF 1 "" "")
1391         (const_string "SF")
1392         (const_string "DF")))
1393    (set (attr "prefix_rep")
1394         (if_then_else (eq_attr "type" "ssecomi")
1395                       (const_string "0")
1396                       (const_string "*")))
1397    (set (attr "prefix_data16")
1398         (cond [(eq_attr "type" "fcmp")
1399                  (const_string "*")
1400                (eq_attr "mode" "DF")
1401                  (const_string "1")
1402               ]
1403               (const_string "0")))
1404    (set_attr "athlon_decode" "vector")
1405    (set_attr "amdfam10_decode" "direct")])
1406
1407 (define_insn "*cmpfp_i_sse"
1408   [(set (reg:CCFP FLAGS_REG)
1409         (compare:CCFP (match_operand 0 "register_operand" "x")
1410                       (match_operand 1 "nonimmediate_operand" "xm")))]
1411   "TARGET_SSE_MATH
1412    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1413    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1414   "* return output_fp_compare (insn, operands, 1, 0);"
1415   [(set_attr "type" "ssecomi")
1416    (set_attr "prefix" "maybe_vex")
1417    (set (attr "mode")
1418      (if_then_else (match_operand:SF 1 "" "")
1419         (const_string "SF")
1420         (const_string "DF")))
1421    (set_attr "prefix_rep" "0")
1422    (set (attr "prefix_data16")
1423         (if_then_else (eq_attr "mode" "DF")
1424                       (const_string "1")
1425                       (const_string "0")))
1426    (set_attr "athlon_decode" "vector")
1427    (set_attr "amdfam10_decode" "direct")])
1428
1429 (define_insn "*cmpfp_i_i387"
1430   [(set (reg:CCFP FLAGS_REG)
1431         (compare:CCFP (match_operand 0 "register_operand" "f")
1432                       (match_operand 1 "register_operand" "f")))]
1433   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1434    && TARGET_CMOVE
1435    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1436    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1437   "* return output_fp_compare (insn, operands, 1, 0);"
1438   [(set_attr "type" "fcmp")
1439    (set (attr "mode")
1440      (cond [(match_operand:SF 1 "" "")
1441               (const_string "SF")
1442             (match_operand:DF 1 "" "")
1443               (const_string "DF")
1444            ]
1445            (const_string "XF")))
1446    (set_attr "athlon_decode" "vector")
1447    (set_attr "amdfam10_decode" "direct")])
1448
1449 (define_insn "*cmpfp_iu_mixed"
1450   [(set (reg:CCFPU FLAGS_REG)
1451         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1452                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1453   "TARGET_MIX_SSE_I387
1454    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1455    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1456   "* return output_fp_compare (insn, operands, 1, 1);"
1457   [(set_attr "type" "fcmp,ssecomi")
1458    (set_attr "prefix" "orig,maybe_vex")
1459    (set (attr "mode")
1460      (if_then_else (match_operand:SF 1 "" "")
1461         (const_string "SF")
1462         (const_string "DF")))
1463    (set (attr "prefix_rep")
1464         (if_then_else (eq_attr "type" "ssecomi")
1465                       (const_string "0")
1466                       (const_string "*")))
1467    (set (attr "prefix_data16")
1468         (cond [(eq_attr "type" "fcmp")
1469                  (const_string "*")
1470                (eq_attr "mode" "DF")
1471                  (const_string "1")
1472               ]
1473               (const_string "0")))
1474    (set_attr "athlon_decode" "vector")
1475    (set_attr "amdfam10_decode" "direct")])
1476
1477 (define_insn "*cmpfp_iu_sse"
1478   [(set (reg:CCFPU FLAGS_REG)
1479         (compare:CCFPU (match_operand 0 "register_operand" "x")
1480                        (match_operand 1 "nonimmediate_operand" "xm")))]
1481   "TARGET_SSE_MATH
1482    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1483    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1484   "* return output_fp_compare (insn, operands, 1, 1);"
1485   [(set_attr "type" "ssecomi")
1486    (set_attr "prefix" "maybe_vex")
1487    (set (attr "mode")
1488      (if_then_else (match_operand:SF 1 "" "")
1489         (const_string "SF")
1490         (const_string "DF")))
1491    (set_attr "prefix_rep" "0")
1492    (set (attr "prefix_data16")
1493         (if_then_else (eq_attr "mode" "DF")
1494                       (const_string "1")
1495                       (const_string "0")))
1496    (set_attr "athlon_decode" "vector")
1497    (set_attr "amdfam10_decode" "direct")])
1498
1499 (define_insn "*cmpfp_iu_387"
1500   [(set (reg:CCFPU FLAGS_REG)
1501         (compare:CCFPU (match_operand 0 "register_operand" "f")
1502                        (match_operand 1 "register_operand" "f")))]
1503   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1504    && TARGET_CMOVE
1505    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1506    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507   "* return output_fp_compare (insn, operands, 1, 1);"
1508   [(set_attr "type" "fcmp")
1509    (set (attr "mode")
1510      (cond [(match_operand:SF 1 "" "")
1511               (const_string "SF")
1512             (match_operand:DF 1 "" "")
1513               (const_string "DF")
1514            ]
1515            (const_string "XF")))
1516    (set_attr "athlon_decode" "vector")
1517    (set_attr "amdfam10_decode" "direct")])
1518 \f
1519 ;; Move instructions.
1520
1521 ;; General case of fullword move.
1522
1523 (define_expand "movsi"
1524   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1525         (match_operand:SI 1 "general_operand" ""))]
1526   ""
1527   "ix86_expand_move (SImode, operands); DONE;")
1528
1529 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1530 ;; general_operand.
1531 ;;
1532 ;; %%% We don't use a post-inc memory reference because x86 is not a
1533 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1534 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1535 ;; targets without our curiosities, and it is just as easy to represent
1536 ;; this differently.
1537
1538 (define_insn "*pushsi2"
1539   [(set (match_operand:SI 0 "push_operand" "=<")
1540         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1541   "!TARGET_64BIT"
1542   "push{l}\t%1"
1543   [(set_attr "type" "push")
1544    (set_attr "mode" "SI")])
1545
1546 ;; For 64BIT abi we always round up to 8 bytes.
1547 (define_insn "*pushsi2_rex64"
1548   [(set (match_operand:SI 0 "push_operand" "=X")
1549         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1550   "TARGET_64BIT"
1551   "push{q}\t%q1"
1552   [(set_attr "type" "push")
1553    (set_attr "mode" "SI")])
1554
1555 (define_insn "*pushsi2_prologue"
1556   [(set (match_operand:SI 0 "push_operand" "=<")
1557         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1558    (clobber (mem:BLK (scratch)))]
1559   "!TARGET_64BIT"
1560   "push{l}\t%1"
1561   [(set_attr "type" "push")
1562    (set_attr "mode" "SI")])
1563
1564 (define_insn "*popsi1_epilogue"
1565   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1566         (mem:SI (reg:SI SP_REG)))
1567    (set (reg:SI SP_REG)
1568         (plus:SI (reg:SI SP_REG) (const_int 4)))
1569    (clobber (mem:BLK (scratch)))]
1570   "!TARGET_64BIT"
1571   "pop{l}\t%0"
1572   [(set_attr "type" "pop")
1573    (set_attr "mode" "SI")])
1574
1575 (define_insn "popsi1"
1576   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1577         (mem:SI (reg:SI SP_REG)))
1578    (set (reg:SI SP_REG)
1579         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1580   "!TARGET_64BIT"
1581   "pop{l}\t%0"
1582   [(set_attr "type" "pop")
1583    (set_attr "mode" "SI")])
1584
1585 (define_insn "*movsi_xor"
1586   [(set (match_operand:SI 0 "register_operand" "=r")
1587         (match_operand:SI 1 "const0_operand" ""))
1588    (clobber (reg:CC FLAGS_REG))]
1589   "reload_completed"
1590   "xor{l}\t%0, %0"
1591   [(set_attr "type" "alu1")
1592    (set_attr "mode" "SI")
1593    (set_attr "length_immediate" "0")])
1594
1595 (define_insn "*movsi_or"
1596   [(set (match_operand:SI 0 "register_operand" "=r")
1597         (match_operand:SI 1 "immediate_operand" "i"))
1598    (clobber (reg:CC FLAGS_REG))]
1599   "reload_completed
1600    && operands[1] == constm1_rtx"
1601 {
1602   operands[1] = constm1_rtx;
1603   return "or{l}\t{%1, %0|%0, %1}";
1604 }
1605   [(set_attr "type" "alu1")
1606    (set_attr "mode" "SI")
1607    (set_attr "length_immediate" "1")])
1608
1609 (define_insn "*movsi_1"
1610   [(set (match_operand:SI 0 "nonimmediate_operand"
1611                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1612         (match_operand:SI 1 "general_operand"
1613                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1614   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1615 {
1616   switch (get_attr_type (insn))
1617     {
1618     case TYPE_SSELOG1:
1619       if (get_attr_mode (insn) == MODE_TI)
1620         return "%vpxor\t%0, %d0";
1621       return "%vxorps\t%0, %d0";
1622
1623     case TYPE_SSEMOV:
1624       switch (get_attr_mode (insn))
1625         {
1626         case MODE_TI:
1627           return "%vmovdqa\t{%1, %0|%0, %1}";
1628         case MODE_V4SF:
1629           return "%vmovaps\t{%1, %0|%0, %1}";
1630         case MODE_SI:
1631           return "%vmovd\t{%1, %0|%0, %1}";
1632         case MODE_SF:
1633           return "%vmovss\t{%1, %0|%0, %1}";
1634         default:
1635           gcc_unreachable ();
1636         }
1637
1638     case TYPE_MMX:
1639       return "pxor\t%0, %0";
1640
1641     case TYPE_MMXMOV:
1642       if (get_attr_mode (insn) == MODE_DI)
1643         return "movq\t{%1, %0|%0, %1}";
1644       return "movd\t{%1, %0|%0, %1}";
1645
1646     case TYPE_LEA:
1647       return "lea{l}\t{%1, %0|%0, %1}";
1648
1649     default:
1650       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1651       return "mov{l}\t{%1, %0|%0, %1}";
1652     }
1653 }
1654   [(set (attr "type")
1655      (cond [(eq_attr "alternative" "2")
1656               (const_string "mmx")
1657             (eq_attr "alternative" "3,4,5")
1658               (const_string "mmxmov")
1659             (eq_attr "alternative" "6")
1660               (const_string "sselog1")
1661             (eq_attr "alternative" "7,8,9,10,11")
1662               (const_string "ssemov")
1663             (match_operand:DI 1 "pic_32bit_operand" "")
1664               (const_string "lea")
1665            ]
1666            (const_string "imov")))
1667    (set (attr "prefix")
1668      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1669        (const_string "orig")
1670        (const_string "maybe_vex")))
1671    (set (attr "prefix_data16")
1672      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1673        (const_string "1")
1674        (const_string "*")))
1675    (set (attr "mode")
1676      (cond [(eq_attr "alternative" "2,3")
1677               (const_string "DI")
1678             (eq_attr "alternative" "6,7")
1679               (if_then_else
1680                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1681                 (const_string "V4SF")
1682                 (const_string "TI"))
1683             (and (eq_attr "alternative" "8,9,10,11")
1684                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1685               (const_string "SF")
1686            ]
1687            (const_string "SI")))])
1688
1689 ;; Stores and loads of ax to arbitrary constant address.
1690 ;; We fake an second form of instruction to force reload to load address
1691 ;; into register when rax is not available
1692 (define_insn "*movabssi_1_rex64"
1693   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1694         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1695   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1696   "@
1697    movabs{l}\t{%1, %P0|%P0, %1}
1698    mov{l}\t{%1, %a0|%a0, %1}"
1699   [(set_attr "type" "imov")
1700    (set_attr "modrm" "0,*")
1701    (set_attr "length_address" "8,0")
1702    (set_attr "length_immediate" "0,*")
1703    (set_attr "memory" "store")
1704    (set_attr "mode" "SI")])
1705
1706 (define_insn "*movabssi_2_rex64"
1707   [(set (match_operand:SI 0 "register_operand" "=a,r")
1708         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1709   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1710   "@
1711    movabs{l}\t{%P1, %0|%0, %P1}
1712    mov{l}\t{%a1, %0|%0, %a1}"
1713   [(set_attr "type" "imov")
1714    (set_attr "modrm" "0,*")
1715    (set_attr "length_address" "8,0")
1716    (set_attr "length_immediate" "0")
1717    (set_attr "memory" "load")
1718    (set_attr "mode" "SI")])
1719
1720 (define_insn "*swapsi"
1721   [(set (match_operand:SI 0 "register_operand" "+r")
1722         (match_operand:SI 1 "register_operand" "+r"))
1723    (set (match_dup 1)
1724         (match_dup 0))]
1725   ""
1726   "xchg{l}\t%1, %0"
1727   [(set_attr "type" "imov")
1728    (set_attr "mode" "SI")
1729    (set_attr "pent_pair" "np")
1730    (set_attr "athlon_decode" "vector")
1731    (set_attr "amdfam10_decode" "double")])
1732
1733 (define_expand "movhi"
1734   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1735         (match_operand:HI 1 "general_operand" ""))]
1736   ""
1737   "ix86_expand_move (HImode, operands); DONE;")
1738
1739 (define_insn "*pushhi2"
1740   [(set (match_operand:HI 0 "push_operand" "=X")
1741         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1742   "!TARGET_64BIT"
1743   "push{l}\t%k1"
1744   [(set_attr "type" "push")
1745    (set_attr "mode" "SI")])
1746
1747 ;; For 64BIT abi we always round up to 8 bytes.
1748 (define_insn "*pushhi2_rex64"
1749   [(set (match_operand:HI 0 "push_operand" "=X")
1750         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1751   "TARGET_64BIT"
1752   "push{q}\t%q1"
1753   [(set_attr "type" "push")
1754    (set_attr "mode" "DI")])
1755
1756 (define_insn "*movhi_1"
1757   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1758         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1759   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1760 {
1761   switch (get_attr_type (insn))
1762     {
1763     case TYPE_IMOVX:
1764       /* movzwl is faster than movw on p2 due to partial word stalls,
1765          though not as fast as an aligned movl.  */
1766       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1767     default:
1768       if (get_attr_mode (insn) == MODE_SI)
1769         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1770       else
1771         return "mov{w}\t{%1, %0|%0, %1}";
1772     }
1773 }
1774   [(set (attr "type")
1775      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1776               (const_string "imov")
1777             (and (eq_attr "alternative" "0")
1778                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1779                           (const_int 0))
1780                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1781                           (const_int 0))))
1782               (const_string "imov")
1783             (and (eq_attr "alternative" "1,2")
1784                  (match_operand:HI 1 "aligned_operand" ""))
1785               (const_string "imov")
1786             (and (ne (symbol_ref "TARGET_MOVX")
1787                      (const_int 0))
1788                  (eq_attr "alternative" "0,2"))
1789               (const_string "imovx")
1790            ]
1791            (const_string "imov")))
1792     (set (attr "mode")
1793       (cond [(eq_attr "type" "imovx")
1794                (const_string "SI")
1795              (and (eq_attr "alternative" "1,2")
1796                   (match_operand:HI 1 "aligned_operand" ""))
1797                (const_string "SI")
1798              (and (eq_attr "alternative" "0")
1799                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1800                            (const_int 0))
1801                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1802                            (const_int 0))))
1803                (const_string "SI")
1804             ]
1805             (const_string "HI")))])
1806
1807 ;; Stores and loads of ax to arbitrary constant address.
1808 ;; We fake an second form of instruction to force reload to load address
1809 ;; into register when rax is not available
1810 (define_insn "*movabshi_1_rex64"
1811   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1812         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1813   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1814   "@
1815    movabs{w}\t{%1, %P0|%P0, %1}
1816    mov{w}\t{%1, %a0|%a0, %1}"
1817   [(set_attr "type" "imov")
1818    (set_attr "modrm" "0,*")
1819    (set_attr "length_address" "8,0")
1820    (set_attr "length_immediate" "0,*")
1821    (set_attr "memory" "store")
1822    (set_attr "mode" "HI")])
1823
1824 (define_insn "*movabshi_2_rex64"
1825   [(set (match_operand:HI 0 "register_operand" "=a,r")
1826         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1827   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1828   "@
1829    movabs{w}\t{%P1, %0|%0, %P1}
1830    mov{w}\t{%a1, %0|%0, %a1}"
1831   [(set_attr "type" "imov")
1832    (set_attr "modrm" "0,*")
1833    (set_attr "length_address" "8,0")
1834    (set_attr "length_immediate" "0")
1835    (set_attr "memory" "load")
1836    (set_attr "mode" "HI")])
1837
1838 (define_insn "*swaphi_1"
1839   [(set (match_operand:HI 0 "register_operand" "+r")
1840         (match_operand:HI 1 "register_operand" "+r"))
1841    (set (match_dup 1)
1842         (match_dup 0))]
1843   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1844   "xchg{l}\t%k1, %k0"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "SI")
1847    (set_attr "pent_pair" "np")
1848    (set_attr "athlon_decode" "vector")
1849    (set_attr "amdfam10_decode" "double")])
1850
1851 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1852 (define_insn "*swaphi_2"
1853   [(set (match_operand:HI 0 "register_operand" "+r")
1854         (match_operand:HI 1 "register_operand" "+r"))
1855    (set (match_dup 1)
1856         (match_dup 0))]
1857   "TARGET_PARTIAL_REG_STALL"
1858   "xchg{w}\t%1, %0"
1859   [(set_attr "type" "imov")
1860    (set_attr "mode" "HI")
1861    (set_attr "pent_pair" "np")
1862    (set_attr "athlon_decode" "vector")])
1863
1864 (define_expand "movstricthi"
1865   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1866         (match_operand:HI 1 "general_operand" ""))]
1867   ""
1868 {
1869   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1870     FAIL;
1871   /* Don't generate memory->memory moves, go through a register */
1872   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1873     operands[1] = force_reg (HImode, operands[1]);
1874 })
1875
1876 (define_insn "*movstricthi_1"
1877   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1878         (match_operand:HI 1 "general_operand" "rn,m"))]
1879   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1880    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1881   "mov{w}\t{%1, %0|%0, %1}"
1882   [(set_attr "type" "imov")
1883    (set_attr "mode" "HI")])
1884
1885 (define_insn "*movstricthi_xor"
1886   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1887         (match_operand:HI 1 "const0_operand" ""))
1888    (clobber (reg:CC FLAGS_REG))]
1889   "reload_completed"
1890   "xor{w}\t%0, %0"
1891   [(set_attr "type" "alu1")
1892    (set_attr "mode" "HI")
1893    (set_attr "length_immediate" "0")])
1894
1895 (define_expand "movqi"
1896   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1897         (match_operand:QI 1 "general_operand" ""))]
1898   ""
1899   "ix86_expand_move (QImode, operands); DONE;")
1900
1901 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1902 ;; "push a byte".  But actually we use pushl, which has the effect
1903 ;; of rounding the amount pushed up to a word.
1904
1905 (define_insn "*pushqi2"
1906   [(set (match_operand:QI 0 "push_operand" "=X")
1907         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1908   "!TARGET_64BIT"
1909   "push{l}\t%k1"
1910   [(set_attr "type" "push")
1911    (set_attr "mode" "SI")])
1912
1913 ;; For 64BIT abi we always round up to 8 bytes.
1914 (define_insn "*pushqi2_rex64"
1915   [(set (match_operand:QI 0 "push_operand" "=X")
1916         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1917   "TARGET_64BIT"
1918   "push{q}\t%q1"
1919   [(set_attr "type" "push")
1920    (set_attr "mode" "DI")])
1921
1922 ;; Situation is quite tricky about when to choose full sized (SImode) move
1923 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1924 ;; partial register dependency machines (such as AMD Athlon), where QImode
1925 ;; moves issue extra dependency and for partial register stalls machines
1926 ;; that don't use QImode patterns (and QImode move cause stall on the next
1927 ;; instruction).
1928 ;;
1929 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1930 ;; register stall machines with, where we use QImode instructions, since
1931 ;; partial register stall can be caused there.  Then we use movzx.
1932 (define_insn "*movqi_1"
1933   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1934         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1935   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1936 {
1937   switch (get_attr_type (insn))
1938     {
1939     case TYPE_IMOVX:
1940       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1941       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1942     default:
1943       if (get_attr_mode (insn) == MODE_SI)
1944         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1945       else
1946         return "mov{b}\t{%1, %0|%0, %1}";
1947     }
1948 }
1949   [(set (attr "type")
1950      (cond [(and (eq_attr "alternative" "5")
1951                  (not (match_operand:QI 1 "aligned_operand" "")))
1952               (const_string "imovx")
1953             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1954               (const_string "imov")
1955             (and (eq_attr "alternative" "3")
1956                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1957                           (const_int 0))
1958                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1959                           (const_int 0))))
1960               (const_string "imov")
1961             (eq_attr "alternative" "3,5")
1962               (const_string "imovx")
1963             (and (ne (symbol_ref "TARGET_MOVX")
1964                      (const_int 0))
1965                  (eq_attr "alternative" "2"))
1966               (const_string "imovx")
1967            ]
1968            (const_string "imov")))
1969    (set (attr "mode")
1970       (cond [(eq_attr "alternative" "3,4,5")
1971                (const_string "SI")
1972              (eq_attr "alternative" "6")
1973                (const_string "QI")
1974              (eq_attr "type" "imovx")
1975                (const_string "SI")
1976              (and (eq_attr "type" "imov")
1977                   (and (eq_attr "alternative" "0,1")
1978                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1979                                 (const_int 0))
1980                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1981                                      (const_int 0))
1982                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1983                                      (const_int 0))))))
1984                (const_string "SI")
1985              ;; Avoid partial register stalls when not using QImode arithmetic
1986              (and (eq_attr "type" "imov")
1987                   (and (eq_attr "alternative" "0,1")
1988                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1989                                 (const_int 0))
1990                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1991                                 (const_int 0)))))
1992                (const_string "SI")
1993            ]
1994            (const_string "QI")))])
1995
1996 (define_insn "*swapqi_1"
1997   [(set (match_operand:QI 0 "register_operand" "+r")
1998         (match_operand:QI 1 "register_operand" "+r"))
1999    (set (match_dup 1)
2000         (match_dup 0))]
2001   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2002   "xchg{l}\t%k1, %k0"
2003   [(set_attr "type" "imov")
2004    (set_attr "mode" "SI")
2005    (set_attr "pent_pair" "np")
2006    (set_attr "athlon_decode" "vector")
2007    (set_attr "amdfam10_decode" "vector")])
2008
2009 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2010 (define_insn "*swapqi_2"
2011   [(set (match_operand:QI 0 "register_operand" "+q")
2012         (match_operand:QI 1 "register_operand" "+q"))
2013    (set (match_dup 1)
2014         (match_dup 0))]
2015   "TARGET_PARTIAL_REG_STALL"
2016   "xchg{b}\t%1, %0"
2017   [(set_attr "type" "imov")
2018    (set_attr "mode" "QI")
2019    (set_attr "pent_pair" "np")
2020    (set_attr "athlon_decode" "vector")])
2021
2022 (define_expand "movstrictqi"
2023   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2024         (match_operand:QI 1 "general_operand" ""))]
2025   ""
2026 {
2027   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2028     FAIL;
2029   /* Don't generate memory->memory moves, go through a register.  */
2030   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2031     operands[1] = force_reg (QImode, operands[1]);
2032 })
2033
2034 (define_insn "*movstrictqi_1"
2035   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2036         (match_operand:QI 1 "general_operand" "*qn,m"))]
2037   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2038    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2039   "mov{b}\t{%1, %0|%0, %1}"
2040   [(set_attr "type" "imov")
2041    (set_attr "mode" "QI")])
2042
2043 (define_insn "*movstrictqi_xor"
2044   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2045         (match_operand:QI 1 "const0_operand" ""))
2046    (clobber (reg:CC FLAGS_REG))]
2047   "reload_completed"
2048   "xor{b}\t%0, %0"
2049   [(set_attr "type" "alu1")
2050    (set_attr "mode" "QI")
2051    (set_attr "length_immediate" "0")])
2052
2053 (define_insn "*movsi_extv_1"
2054   [(set (match_operand:SI 0 "register_operand" "=R")
2055         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2056                          (const_int 8)
2057                          (const_int 8)))]
2058   ""
2059   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2060   [(set_attr "type" "imovx")
2061    (set_attr "mode" "SI")])
2062
2063 (define_insn "*movhi_extv_1"
2064   [(set (match_operand:HI 0 "register_operand" "=R")
2065         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2066                          (const_int 8)
2067                          (const_int 8)))]
2068   ""
2069   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2070   [(set_attr "type" "imovx")
2071    (set_attr "mode" "SI")])
2072
2073 (define_insn "*movqi_extv_1"
2074   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2075         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2076                          (const_int 8)
2077                          (const_int 8)))]
2078   "!TARGET_64BIT"
2079 {
2080   switch (get_attr_type (insn))
2081     {
2082     case TYPE_IMOVX:
2083       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2084     default:
2085       return "mov{b}\t{%h1, %0|%0, %h1}";
2086     }
2087 }
2088   [(set (attr "type")
2089      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2090                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2091                              (ne (symbol_ref "TARGET_MOVX")
2092                                  (const_int 0))))
2093         (const_string "imovx")
2094         (const_string "imov")))
2095    (set (attr "mode")
2096      (if_then_else (eq_attr "type" "imovx")
2097         (const_string "SI")
2098         (const_string "QI")))])
2099
2100 (define_insn "*movqi_extv_1_rex64"
2101   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2102         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2103                          (const_int 8)
2104                          (const_int 8)))]
2105   "TARGET_64BIT"
2106 {
2107   switch (get_attr_type (insn))
2108     {
2109     case TYPE_IMOVX:
2110       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2111     default:
2112       return "mov{b}\t{%h1, %0|%0, %h1}";
2113     }
2114 }
2115   [(set (attr "type")
2116      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2117                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118                              (ne (symbol_ref "TARGET_MOVX")
2119                                  (const_int 0))))
2120         (const_string "imovx")
2121         (const_string "imov")))
2122    (set (attr "mode")
2123      (if_then_else (eq_attr "type" "imovx")
2124         (const_string "SI")
2125         (const_string "QI")))])
2126
2127 ;; Stores and loads of ax to arbitrary constant address.
2128 ;; We fake an second form of instruction to force reload to load address
2129 ;; into register when rax is not available
2130 (define_insn "*movabsqi_1_rex64"
2131   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2132         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2133   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2134   "@
2135    movabs{b}\t{%1, %P0|%P0, %1}
2136    mov{b}\t{%1, %a0|%a0, %1}"
2137   [(set_attr "type" "imov")
2138    (set_attr "modrm" "0,*")
2139    (set_attr "length_address" "8,0")
2140    (set_attr "length_immediate" "0,*")
2141    (set_attr "memory" "store")
2142    (set_attr "mode" "QI")])
2143
2144 (define_insn "*movabsqi_2_rex64"
2145   [(set (match_operand:QI 0 "register_operand" "=a,r")
2146         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2147   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2148   "@
2149    movabs{b}\t{%P1, %0|%0, %P1}
2150    mov{b}\t{%a1, %0|%0, %a1}"
2151   [(set_attr "type" "imov")
2152    (set_attr "modrm" "0,*")
2153    (set_attr "length_address" "8,0")
2154    (set_attr "length_immediate" "0")
2155    (set_attr "memory" "load")
2156    (set_attr "mode" "QI")])
2157
2158 (define_insn "*movdi_extzv_1"
2159   [(set (match_operand:DI 0 "register_operand" "=R")
2160         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2161                          (const_int 8)
2162                          (const_int 8)))]
2163   "TARGET_64BIT"
2164   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2165   [(set_attr "type" "imovx")
2166    (set_attr "mode" "SI")])
2167
2168 (define_insn "*movsi_extzv_1"
2169   [(set (match_operand:SI 0 "register_operand" "=R")
2170         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2171                          (const_int 8)
2172                          (const_int 8)))]
2173   ""
2174   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2175   [(set_attr "type" "imovx")
2176    (set_attr "mode" "SI")])
2177
2178 (define_insn "*movqi_extzv_2"
2179   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2180         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2181                                     (const_int 8)
2182                                     (const_int 8)) 0))]
2183   "!TARGET_64BIT"
2184 {
2185   switch (get_attr_type (insn))
2186     {
2187     case TYPE_IMOVX:
2188       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2189     default:
2190       return "mov{b}\t{%h1, %0|%0, %h1}";
2191     }
2192 }
2193   [(set (attr "type")
2194      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2195                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2196                              (ne (symbol_ref "TARGET_MOVX")
2197                                  (const_int 0))))
2198         (const_string "imovx")
2199         (const_string "imov")))
2200    (set (attr "mode")
2201      (if_then_else (eq_attr "type" "imovx")
2202         (const_string "SI")
2203         (const_string "QI")))])
2204
2205 (define_insn "*movqi_extzv_2_rex64"
2206   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2207         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2208                                     (const_int 8)
2209                                     (const_int 8)) 0))]
2210   "TARGET_64BIT"
2211 {
2212   switch (get_attr_type (insn))
2213     {
2214     case TYPE_IMOVX:
2215       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2216     default:
2217       return "mov{b}\t{%h1, %0|%0, %h1}";
2218     }
2219 }
2220   [(set (attr "type")
2221      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2222                         (ne (symbol_ref "TARGET_MOVX")
2223                             (const_int 0)))
2224         (const_string "imovx")
2225         (const_string "imov")))
2226    (set (attr "mode")
2227      (if_then_else (eq_attr "type" "imovx")
2228         (const_string "SI")
2229         (const_string "QI")))])
2230
2231 (define_insn "movsi_insv_1"
2232   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2233                          (const_int 8)
2234                          (const_int 8))
2235         (match_operand:SI 1 "general_operand" "Qmn"))]
2236   "!TARGET_64BIT"
2237   "mov{b}\t{%b1, %h0|%h0, %b1}"
2238   [(set_attr "type" "imov")
2239    (set_attr "mode" "QI")])
2240
2241 (define_insn "*movsi_insv_1_rex64"
2242   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2243                          (const_int 8)
2244                          (const_int 8))
2245         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2246   "TARGET_64BIT"
2247   "mov{b}\t{%b1, %h0|%h0, %b1}"
2248   [(set_attr "type" "imov")
2249    (set_attr "mode" "QI")])
2250
2251 (define_insn "movdi_insv_1_rex64"
2252   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2253                          (const_int 8)
2254                          (const_int 8))
2255         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2256   "TARGET_64BIT"
2257   "mov{b}\t{%b1, %h0|%h0, %b1}"
2258   [(set_attr "type" "imov")
2259    (set_attr "mode" "QI")])
2260
2261 (define_insn "*movqi_insv_2"
2262   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2263                          (const_int 8)
2264                          (const_int 8))
2265         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2266                      (const_int 8)))]
2267   ""
2268   "mov{b}\t{%h1, %h0|%h0, %h1}"
2269   [(set_attr "type" "imov")
2270    (set_attr "mode" "QI")])
2271
2272 (define_expand "movdi"
2273   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2274         (match_operand:DI 1 "general_operand" ""))]
2275   ""
2276   "ix86_expand_move (DImode, operands); DONE;")
2277
2278 (define_insn "*pushdi"
2279   [(set (match_operand:DI 0 "push_operand" "=<")
2280         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2281   "!TARGET_64BIT"
2282   "#")
2283
2284 (define_insn "*pushdi2_rex64"
2285   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2286         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2287   "TARGET_64BIT"
2288   "@
2289    push{q}\t%1
2290    #"
2291   [(set_attr "type" "push,multi")
2292    (set_attr "mode" "DI")])
2293
2294 ;; Convert impossible pushes of immediate to existing instructions.
2295 ;; First try to get scratch register and go through it.  In case this
2296 ;; fails, push sign extended lower part first and then overwrite
2297 ;; upper part by 32bit move.
2298 (define_peephole2
2299   [(match_scratch:DI 2 "r")
2300    (set (match_operand:DI 0 "push_operand" "")
2301         (match_operand:DI 1 "immediate_operand" ""))]
2302   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2303    && !x86_64_immediate_operand (operands[1], DImode)"
2304   [(set (match_dup 2) (match_dup 1))
2305    (set (match_dup 0) (match_dup 2))]
2306   "")
2307
2308 ;; We need to define this as both peepholer and splitter for case
2309 ;; peephole2 pass is not run.
2310 ;; "&& 1" is needed to keep it from matching the previous pattern.
2311 (define_peephole2
2312   [(set (match_operand:DI 0 "push_operand" "")
2313         (match_operand:DI 1 "immediate_operand" ""))]
2314   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2315    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2316   [(set (match_dup 0) (match_dup 1))
2317    (set (match_dup 2) (match_dup 3))]
2318   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2319    operands[1] = gen_lowpart (DImode, operands[2]);
2320    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2321                                                     GEN_INT (4)));
2322   ")
2323
2324 (define_split
2325   [(set (match_operand:DI 0 "push_operand" "")
2326         (match_operand:DI 1 "immediate_operand" ""))]
2327   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2328                     ? epilogue_completed : reload_completed)
2329    && !symbolic_operand (operands[1], DImode)
2330    && !x86_64_immediate_operand (operands[1], DImode)"
2331   [(set (match_dup 0) (match_dup 1))
2332    (set (match_dup 2) (match_dup 3))]
2333   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2334    operands[1] = gen_lowpart (DImode, operands[2]);
2335    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2336                                                     GEN_INT (4)));
2337   ")
2338
2339 (define_insn "*pushdi2_prologue_rex64"
2340   [(set (match_operand:DI 0 "push_operand" "=<")
2341         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2342    (clobber (mem:BLK (scratch)))]
2343   "TARGET_64BIT"
2344   "push{q}\t%1"
2345   [(set_attr "type" "push")
2346    (set_attr "mode" "DI")])
2347
2348 (define_insn "*popdi1_epilogue_rex64"
2349   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2350         (mem:DI (reg:DI SP_REG)))
2351    (set (reg:DI SP_REG)
2352         (plus:DI (reg:DI SP_REG) (const_int 8)))
2353    (clobber (mem:BLK (scratch)))]
2354   "TARGET_64BIT"
2355   "pop{q}\t%0"
2356   [(set_attr "type" "pop")
2357    (set_attr "mode" "DI")])
2358
2359 (define_insn "popdi1"
2360   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2361         (mem:DI (reg:DI SP_REG)))
2362    (set (reg:DI SP_REG)
2363         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2364   "TARGET_64BIT"
2365   "pop{q}\t%0"
2366   [(set_attr "type" "pop")
2367    (set_attr "mode" "DI")])
2368
2369 (define_insn "*movdi_xor_rex64"
2370   [(set (match_operand:DI 0 "register_operand" "=r")
2371         (match_operand:DI 1 "const0_operand" ""))
2372    (clobber (reg:CC FLAGS_REG))]
2373   "TARGET_64BIT
2374    && reload_completed"
2375   "xor{l}\t%k0, %k0";
2376   [(set_attr "type" "alu1")
2377    (set_attr "mode" "SI")
2378    (set_attr "length_immediate" "0")])
2379
2380 (define_insn "*movdi_or_rex64"
2381   [(set (match_operand:DI 0 "register_operand" "=r")
2382         (match_operand:DI 1 "const_int_operand" "i"))
2383    (clobber (reg:CC FLAGS_REG))]
2384   "TARGET_64BIT
2385    && reload_completed
2386    && operands[1] == constm1_rtx"
2387 {
2388   operands[1] = constm1_rtx;
2389   return "or{q}\t{%1, %0|%0, %1}";
2390 }
2391   [(set_attr "type" "alu1")
2392    (set_attr "mode" "DI")
2393    (set_attr "length_immediate" "1")])
2394
2395 (define_insn "*movdi_2"
2396   [(set (match_operand:DI 0 "nonimmediate_operand"
2397                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2398         (match_operand:DI 1 "general_operand"
2399                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2400   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2401   "@
2402    #
2403    #
2404    pxor\t%0, %0
2405    movq\t{%1, %0|%0, %1}
2406    movq\t{%1, %0|%0, %1}
2407    %vpxor\t%0, %d0
2408    %vmovq\t{%1, %0|%0, %1}
2409    %vmovdqa\t{%1, %0|%0, %1}
2410    %vmovq\t{%1, %0|%0, %1}
2411    xorps\t%0, %0
2412    movlps\t{%1, %0|%0, %1}
2413    movaps\t{%1, %0|%0, %1}
2414    movlps\t{%1, %0|%0, %1}"
2415   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2416    (set (attr "prefix")
2417      (if_then_else (eq_attr "alternative" "5,6,7,8")
2418        (const_string "vex")
2419        (const_string "orig")))
2420    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2421
2422 (define_split
2423   [(set (match_operand:DI 0 "push_operand" "")
2424         (match_operand:DI 1 "general_operand" ""))]
2425   "!TARGET_64BIT && reload_completed
2426    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2427   [(const_int 0)]
2428   "ix86_split_long_move (operands); DONE;")
2429
2430 ;; %%% This multiword shite has got to go.
2431 (define_split
2432   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2433         (match_operand:DI 1 "general_operand" ""))]
2434   "!TARGET_64BIT && reload_completed
2435    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2436    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2437   [(const_int 0)]
2438   "ix86_split_long_move (operands); DONE;")
2439
2440 (define_insn "*movdi_1_rex64"
2441   [(set (match_operand:DI 0 "nonimmediate_operand"
2442           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2443         (match_operand:DI 1 "general_operand"
2444           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2445   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2446 {
2447   switch (get_attr_type (insn))
2448     {
2449     case TYPE_SSECVT:
2450       if (SSE_REG_P (operands[0]))
2451         return "movq2dq\t{%1, %0|%0, %1}";
2452       else
2453         return "movdq2q\t{%1, %0|%0, %1}";
2454
2455     case TYPE_SSEMOV:
2456       if (TARGET_AVX)
2457         {
2458           if (get_attr_mode (insn) == MODE_TI)
2459             return "vmovdqa\t{%1, %0|%0, %1}";
2460           else
2461             return "vmovq\t{%1, %0|%0, %1}";
2462         }
2463
2464       if (get_attr_mode (insn) == MODE_TI)
2465         return "movdqa\t{%1, %0|%0, %1}";
2466       /* FALLTHRU */
2467
2468     case TYPE_MMXMOV:
2469       /* Moves from and into integer register is done using movd
2470          opcode with REX prefix.  */
2471       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2472         return "movd\t{%1, %0|%0, %1}";
2473       return "movq\t{%1, %0|%0, %1}";
2474
2475     case TYPE_SSELOG1:
2476       return "%vpxor\t%0, %d0";
2477
2478     case TYPE_MMX:
2479       return "pxor\t%0, %0";
2480
2481     case TYPE_MULTI:
2482       return "#";
2483
2484     case TYPE_LEA:
2485       return "lea{q}\t{%a1, %0|%0, %a1}";
2486
2487     default:
2488       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2489       if (get_attr_mode (insn) == MODE_SI)
2490         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2491       else if (which_alternative == 2)
2492         return "movabs{q}\t{%1, %0|%0, %1}";
2493       else
2494         return "mov{q}\t{%1, %0|%0, %1}";
2495     }
2496 }
2497   [(set (attr "type")
2498      (cond [(eq_attr "alternative" "5")
2499               (const_string "mmx")
2500             (eq_attr "alternative" "6,7,8,9,10")
2501               (const_string "mmxmov")
2502             (eq_attr "alternative" "11")
2503               (const_string "sselog1")
2504             (eq_attr "alternative" "12,13,14,15,16")
2505               (const_string "ssemov")
2506             (eq_attr "alternative" "17,18")
2507               (const_string "ssecvt")
2508             (eq_attr "alternative" "4")
2509               (const_string "multi")
2510             (match_operand:DI 1 "pic_32bit_operand" "")
2511               (const_string "lea")
2512            ]
2513            (const_string "imov")))
2514    (set (attr "modrm")
2515      (if_then_else
2516        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2517          (const_string "0")
2518          (const_string "*")))
2519    (set (attr "length_immediate")
2520      (if_then_else
2521        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2522          (const_string "8")
2523          (const_string "*")))
2524    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2525    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2526    (set (attr "prefix")
2527      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2528        (const_string "maybe_vex")
2529        (const_string "orig")))
2530    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2531
2532 ;; Stores and loads of ax to arbitrary constant address.
2533 ;; We fake an second form of instruction to force reload to load address
2534 ;; into register when rax is not available
2535 (define_insn "*movabsdi_1_rex64"
2536   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2537         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2538   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2539   "@
2540    movabs{q}\t{%1, %P0|%P0, %1}
2541    mov{q}\t{%1, %a0|%a0, %1}"
2542   [(set_attr "type" "imov")
2543    (set_attr "modrm" "0,*")
2544    (set_attr "length_address" "8,0")
2545    (set_attr "length_immediate" "0,*")
2546    (set_attr "memory" "store")
2547    (set_attr "mode" "DI")])
2548
2549 (define_insn "*movabsdi_2_rex64"
2550   [(set (match_operand:DI 0 "register_operand" "=a,r")
2551         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2552   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2553   "@
2554    movabs{q}\t{%P1, %0|%0, %P1}
2555    mov{q}\t{%a1, %0|%0, %a1}"
2556   [(set_attr "type" "imov")
2557    (set_attr "modrm" "0,*")
2558    (set_attr "length_address" "8,0")
2559    (set_attr "length_immediate" "0")
2560    (set_attr "memory" "load")
2561    (set_attr "mode" "DI")])
2562
2563 ;; Convert impossible stores of immediate to existing instructions.
2564 ;; First try to get scratch register and go through it.  In case this
2565 ;; fails, move by 32bit parts.
2566 (define_peephole2
2567   [(match_scratch:DI 2 "r")
2568    (set (match_operand:DI 0 "memory_operand" "")
2569         (match_operand:DI 1 "immediate_operand" ""))]
2570   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2571    && !x86_64_immediate_operand (operands[1], DImode)"
2572   [(set (match_dup 2) (match_dup 1))
2573    (set (match_dup 0) (match_dup 2))]
2574   "")
2575
2576 ;; We need to define this as both peepholer and splitter for case
2577 ;; peephole2 pass is not run.
2578 ;; "&& 1" is needed to keep it from matching the previous pattern.
2579 (define_peephole2
2580   [(set (match_operand:DI 0 "memory_operand" "")
2581         (match_operand:DI 1 "immediate_operand" ""))]
2582   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2583    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2584   [(set (match_dup 2) (match_dup 3))
2585    (set (match_dup 4) (match_dup 5))]
2586   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2587
2588 (define_split
2589   [(set (match_operand:DI 0 "memory_operand" "")
2590         (match_operand:DI 1 "immediate_operand" ""))]
2591   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2592                     ? epilogue_completed : reload_completed)
2593    && !symbolic_operand (operands[1], DImode)
2594    && !x86_64_immediate_operand (operands[1], DImode)"
2595   [(set (match_dup 2) (match_dup 3))
2596    (set (match_dup 4) (match_dup 5))]
2597   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2598
2599 (define_insn "*swapdi_rex64"
2600   [(set (match_operand:DI 0 "register_operand" "+r")
2601         (match_operand:DI 1 "register_operand" "+r"))
2602    (set (match_dup 1)
2603         (match_dup 0))]
2604   "TARGET_64BIT"
2605   "xchg{q}\t%1, %0"
2606   [(set_attr "type" "imov")
2607    (set_attr "mode" "DI")
2608    (set_attr "pent_pair" "np")
2609    (set_attr "athlon_decode" "vector")
2610    (set_attr "amdfam10_decode" "double")])
2611
2612 (define_expand "movoi"
2613   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2614         (match_operand:OI 1 "general_operand" ""))]
2615   "TARGET_AVX"
2616   "ix86_expand_move (OImode, operands); DONE;")
2617
2618 (define_insn "*movoi_internal"
2619   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2620         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2621   "TARGET_AVX
2622    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2623 {
2624   switch (which_alternative)
2625     {
2626     case 0:
2627       return "vxorps\t%0, %0, %0";
2628     case 1:
2629     case 2:
2630       if (misaligned_operand (operands[0], OImode)
2631           || misaligned_operand (operands[1], OImode))
2632         return "vmovdqu\t{%1, %0|%0, %1}";
2633       else
2634         return "vmovdqa\t{%1, %0|%0, %1}";
2635     default:
2636       gcc_unreachable ();
2637     }
2638 }
2639   [(set_attr "type" "sselog1,ssemov,ssemov")
2640    (set_attr "prefix" "vex")
2641    (set_attr "mode" "OI")])
2642
2643 (define_expand "movti"
2644   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2645         (match_operand:TI 1 "nonimmediate_operand" ""))]
2646   "TARGET_SSE || TARGET_64BIT"
2647 {
2648   if (TARGET_64BIT)
2649     ix86_expand_move (TImode, operands);
2650   else if (push_operand (operands[0], TImode))
2651     ix86_expand_push (TImode, operands[1]);
2652   else
2653     ix86_expand_vector_move (TImode, operands);
2654   DONE;
2655 })
2656
2657 (define_insn "*movti_internal"
2658   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2659         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2660   "TARGET_SSE && !TARGET_64BIT
2661    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2662 {
2663   switch (which_alternative)
2664     {
2665     case 0:
2666       if (get_attr_mode (insn) == MODE_V4SF)
2667         return "%vxorps\t%0, %d0";
2668       else
2669         return "%vpxor\t%0, %d0";
2670     case 1:
2671     case 2:
2672       /* TDmode values are passed as TImode on the stack.  Moving them
2673          to stack may result in unaligned memory access.  */
2674       if (misaligned_operand (operands[0], TImode)
2675           || misaligned_operand (operands[1], TImode))
2676         {
2677           if (get_attr_mode (insn) == MODE_V4SF)
2678             return "%vmovups\t{%1, %0|%0, %1}";
2679          else
2680            return "%vmovdqu\t{%1, %0|%0, %1}";
2681         }
2682       else
2683         {
2684           if (get_attr_mode (insn) == MODE_V4SF)
2685             return "%vmovaps\t{%1, %0|%0, %1}";
2686          else
2687            return "%vmovdqa\t{%1, %0|%0, %1}";
2688         }
2689     default:
2690       gcc_unreachable ();
2691     }
2692 }
2693   [(set_attr "type" "sselog1,ssemov,ssemov")
2694    (set_attr "prefix" "maybe_vex")
2695    (set (attr "mode")
2696         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2697                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2698                  (const_string "V4SF")
2699                (and (eq_attr "alternative" "2")
2700                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2701                         (const_int 0)))
2702                  (const_string "V4SF")]
2703               (const_string "TI")))])
2704
2705 (define_insn "*movti_rex64"
2706   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2707         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2708   "TARGET_64BIT
2709    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2710 {
2711   switch (which_alternative)
2712     {
2713     case 0:
2714     case 1:
2715       return "#";
2716     case 2:
2717       if (get_attr_mode (insn) == MODE_V4SF)
2718         return "%vxorps\t%0, %d0";
2719       else
2720         return "%vpxor\t%0, %d0";
2721     case 3:
2722     case 4:
2723       /* TDmode values are passed as TImode on the stack.  Moving them
2724          to stack may result in unaligned memory access.  */
2725       if (misaligned_operand (operands[0], TImode)
2726           || misaligned_operand (operands[1], TImode))
2727         {
2728           if (get_attr_mode (insn) == MODE_V4SF)
2729             return "%vmovups\t{%1, %0|%0, %1}";
2730          else
2731            return "%vmovdqu\t{%1, %0|%0, %1}";
2732         }
2733       else
2734         {
2735           if (get_attr_mode (insn) == MODE_V4SF)
2736             return "%vmovaps\t{%1, %0|%0, %1}";
2737          else
2738            return "%vmovdqa\t{%1, %0|%0, %1}";
2739         }
2740     default:
2741       gcc_unreachable ();
2742     }
2743 }
2744   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2745    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2746    (set (attr "mode")
2747         (cond [(eq_attr "alternative" "2,3")
2748                  (if_then_else
2749                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2750                        (const_int 0))
2751                    (const_string "V4SF")
2752                    (const_string "TI"))
2753                (eq_attr "alternative" "4")
2754                  (if_then_else
2755                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2756                             (const_int 0))
2757                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2758                             (const_int 0)))
2759                    (const_string "V4SF")
2760                    (const_string "TI"))]
2761                (const_string "DI")))])
2762
2763 (define_split
2764   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2765         (match_operand:TI 1 "general_operand" ""))]
2766   "reload_completed && !SSE_REG_P (operands[0])
2767    && !SSE_REG_P (operands[1])"
2768   [(const_int 0)]
2769   "ix86_split_long_move (operands); DONE;")
2770
2771 ;; This expands to what emit_move_complex would generate if we didn't
2772 ;; have a movti pattern.  Having this avoids problems with reload on
2773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2774 ;; to have around all the time.
2775 (define_expand "movcdi"
2776   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2777         (match_operand:CDI 1 "general_operand" ""))]
2778   ""
2779 {
2780   if (push_operand (operands[0], CDImode))
2781     emit_move_complex_push (CDImode, operands[0], operands[1]);
2782   else
2783     emit_move_complex_parts (operands[0], operands[1]);
2784   DONE;
2785 })
2786
2787 (define_expand "movsf"
2788   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2789         (match_operand:SF 1 "general_operand" ""))]
2790   ""
2791   "ix86_expand_move (SFmode, operands); DONE;")
2792
2793 (define_insn "*pushsf"
2794   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2795         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2796   "!TARGET_64BIT"
2797 {
2798   /* Anything else should be already split before reg-stack.  */
2799   gcc_assert (which_alternative == 1);
2800   return "push{l}\t%1";
2801 }
2802   [(set_attr "type" "multi,push,multi")
2803    (set_attr "unit" "i387,*,*")
2804    (set_attr "mode" "SF,SI,SF")])
2805
2806 (define_insn "*pushsf_rex64"
2807   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2808         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2809   "TARGET_64BIT"
2810 {
2811   /* Anything else should be already split before reg-stack.  */
2812   gcc_assert (which_alternative == 1);
2813   return "push{q}\t%q1";
2814 }
2815   [(set_attr "type" "multi,push,multi")
2816    (set_attr "unit" "i387,*,*")
2817    (set_attr "mode" "SF,DI,SF")])
2818
2819 (define_split
2820   [(set (match_operand:SF 0 "push_operand" "")
2821         (match_operand:SF 1 "memory_operand" ""))]
2822   "reload_completed
2823    && MEM_P (operands[1])
2824    && (operands[2] = find_constant_src (insn))"
2825   [(set (match_dup 0)
2826         (match_dup 2))])
2827
2828 ;; %%% Kill this when call knows how to work this out.
2829 (define_split
2830   [(set (match_operand:SF 0 "push_operand" "")
2831         (match_operand:SF 1 "any_fp_register_operand" ""))]
2832   "!TARGET_64BIT"
2833   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2834    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2835
2836 (define_split
2837   [(set (match_operand:SF 0 "push_operand" "")
2838         (match_operand:SF 1 "any_fp_register_operand" ""))]
2839   "TARGET_64BIT"
2840   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2841    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2842
2843 (define_insn "*movsf_1"
2844   [(set (match_operand:SF 0 "nonimmediate_operand"
2845           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2846         (match_operand:SF 1 "general_operand"
2847           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2848   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2849    && (reload_in_progress || reload_completed
2850        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2851        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2852            && standard_80387_constant_p (operands[1]))
2853        || GET_CODE (operands[1]) != CONST_DOUBLE
2854        || memory_operand (operands[0], SFmode))"
2855 {
2856   switch (which_alternative)
2857     {
2858     case 0:
2859     case 1:
2860       return output_387_reg_move (insn, operands);
2861
2862     case 2:
2863       return standard_80387_constant_opcode (operands[1]);
2864
2865     case 3:
2866     case 4:
2867       return "mov{l}\t{%1, %0|%0, %1}";
2868     case 5:
2869       if (get_attr_mode (insn) == MODE_TI)
2870         return "%vpxor\t%0, %d0";
2871       else
2872         return "%vxorps\t%0, %d0";
2873     case 6:
2874       if (get_attr_mode (insn) == MODE_V4SF)
2875         return "%vmovaps\t{%1, %0|%0, %1}";
2876       else
2877         return "%vmovss\t{%1, %d0|%d0, %1}";
2878     case 7:
2879       if (TARGET_AVX)
2880         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2881                                    : "vmovss\t{%1, %0|%0, %1}";
2882       else
2883         return "movss\t{%1, %0|%0, %1}";
2884     case 8:
2885       return "%vmovss\t{%1, %0|%0, %1}";
2886
2887     case 9: case 10: case 14: case 15:
2888       return "movd\t{%1, %0|%0, %1}";
2889     case 12: case 13:
2890       return "%vmovd\t{%1, %0|%0, %1}";
2891
2892     case 11:
2893       return "movq\t{%1, %0|%0, %1}";
2894
2895     default:
2896       gcc_unreachable ();
2897     }
2898 }
2899   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2900    (set (attr "prefix")
2901      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2902        (const_string "maybe_vex")
2903        (const_string "orig")))
2904    (set (attr "mode")
2905         (cond [(eq_attr "alternative" "3,4,9,10")
2906                  (const_string "SI")
2907                (eq_attr "alternative" "5")
2908                  (if_then_else
2909                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2910                                  (const_int 0))
2911                              (ne (symbol_ref "TARGET_SSE2")
2912                                  (const_int 0)))
2913                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2914                             (const_int 0)))
2915                    (const_string "TI")
2916                    (const_string "V4SF"))
2917                /* For architectures resolving dependencies on
2918                   whole SSE registers use APS move to break dependency
2919                   chains, otherwise use short move to avoid extra work.
2920
2921                   Do the same for architectures resolving dependencies on
2922                   the parts.  While in DF mode it is better to always handle
2923                   just register parts, the SF mode is different due to lack
2924                   of instructions to load just part of the register.  It is
2925                   better to maintain the whole registers in single format
2926                   to avoid problems on using packed logical operations.  */
2927                (eq_attr "alternative" "6")
2928                  (if_then_else
2929                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2930                             (const_int 0))
2931                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2932                             (const_int 0)))
2933                    (const_string "V4SF")
2934                    (const_string "SF"))
2935                (eq_attr "alternative" "11")
2936                  (const_string "DI")]
2937                (const_string "SF")))])
2938
2939 (define_insn "*swapsf"
2940   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2941         (match_operand:SF 1 "fp_register_operand" "+f"))
2942    (set (match_dup 1)
2943         (match_dup 0))]
2944   "reload_completed || TARGET_80387"
2945 {
2946   if (STACK_TOP_P (operands[0]))
2947     return "fxch\t%1";
2948   else
2949     return "fxch\t%0";
2950 }
2951   [(set_attr "type" "fxch")
2952    (set_attr "mode" "SF")])
2953
2954 (define_expand "movdf"
2955   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2956         (match_operand:DF 1 "general_operand" ""))]
2957   ""
2958   "ix86_expand_move (DFmode, operands); DONE;")
2959
2960 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2961 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2962 ;; On the average, pushdf using integers can be still shorter.  Allow this
2963 ;; pattern for optimize_size too.
2964
2965 (define_insn "*pushdf_nointeger"
2966   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2967         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2968   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2969 {
2970   /* This insn should be already split before reg-stack.  */
2971   gcc_unreachable ();
2972 }
2973   [(set_attr "type" "multi")
2974    (set_attr "unit" "i387,*,*,*")
2975    (set_attr "mode" "DF,SI,SI,DF")])
2976
2977 (define_insn "*pushdf_integer"
2978   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2979         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2980   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2981 {
2982   /* This insn should be already split before reg-stack.  */
2983   gcc_unreachable ();
2984 }
2985   [(set_attr "type" "multi")
2986    (set_attr "unit" "i387,*,*")
2987    (set_attr "mode" "DF,SI,DF")])
2988
2989 ;; %%% Kill this when call knows how to work this out.
2990 (define_split
2991   [(set (match_operand:DF 0 "push_operand" "")
2992         (match_operand:DF 1 "any_fp_register_operand" ""))]
2993   "reload_completed"
2994   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2995    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2996   "")
2997
2998 (define_split
2999   [(set (match_operand:DF 0 "push_operand" "")
3000         (match_operand:DF 1 "general_operand" ""))]
3001   "reload_completed"
3002   [(const_int 0)]
3003   "ix86_split_long_move (operands); DONE;")
3004
3005 ;; Moving is usually shorter when only FP registers are used. This separate
3006 ;; movdf pattern avoids the use of integer registers for FP operations
3007 ;; when optimizing for size.
3008
3009 (define_insn "*movdf_nointeger"
3010   [(set (match_operand:DF 0 "nonimmediate_operand"
3011                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3012         (match_operand:DF 1 "general_operand"
3013                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3014   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3015    && ((optimize_function_for_size_p (cfun)
3016        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3017    && (reload_in_progress || reload_completed
3018        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3019        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3020            && optimize_function_for_size_p (cfun)
3021            && !memory_operand (operands[0], DFmode)
3022            && standard_80387_constant_p (operands[1]))
3023        || GET_CODE (operands[1]) != CONST_DOUBLE
3024        || ((optimize_function_for_size_p (cfun)
3025             || !TARGET_MEMORY_MISMATCH_STALL
3026             || reload_in_progress || reload_completed)
3027            && memory_operand (operands[0], DFmode)))"
3028 {
3029   switch (which_alternative)
3030     {
3031     case 0:
3032     case 1:
3033       return output_387_reg_move (insn, operands);
3034
3035     case 2:
3036       return standard_80387_constant_opcode (operands[1]);
3037
3038     case 3:
3039     case 4:
3040       return "#";
3041     case 5:
3042       switch (get_attr_mode (insn))
3043         {
3044         case MODE_V4SF:
3045           return "%vxorps\t%0, %d0";
3046         case MODE_V2DF:
3047           return "%vxorpd\t%0, %d0";
3048         case MODE_TI:
3049           return "%vpxor\t%0, %d0";
3050         default:
3051           gcc_unreachable ();
3052         }
3053     case 6:
3054     case 7:
3055     case 8:
3056       switch (get_attr_mode (insn))
3057         {
3058         case MODE_V4SF:
3059           return "%vmovaps\t{%1, %0|%0, %1}";
3060         case MODE_V2DF:
3061           return "%vmovapd\t{%1, %0|%0, %1}";
3062         case MODE_TI:
3063           return "%vmovdqa\t{%1, %0|%0, %1}";
3064         case MODE_DI:
3065           return "%vmovq\t{%1, %0|%0, %1}";
3066         case MODE_DF:
3067           if (TARGET_AVX)
3068             {
3069               if (REG_P (operands[0]) && REG_P (operands[1]))
3070                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3071               else
3072                 return "vmovsd\t{%1, %0|%0, %1}";
3073             }
3074           else
3075             return "movsd\t{%1, %0|%0, %1}";
3076         case MODE_V1DF:
3077           if (TARGET_AVX)
3078             {
3079               if (REG_P (operands[0]))
3080                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3081               else
3082                 return "vmovlpd\t{%1, %0|%0, %1}";
3083             }
3084           else
3085             return "movlpd\t{%1, %0|%0, %1}";
3086         case MODE_V2SF:
3087           if (TARGET_AVX)
3088             {
3089               if (REG_P (operands[0]))
3090                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3091               else
3092                 return "vmovlps\t{%1, %0|%0, %1}";
3093             }
3094           else
3095             return "movlps\t{%1, %0|%0, %1}";
3096         default:
3097           gcc_unreachable ();
3098         }
3099
3100     default:
3101       gcc_unreachable ();
3102     }
3103 }
3104   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3105    (set (attr "prefix")
3106      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3107        (const_string "orig")
3108        (const_string "maybe_vex")))
3109    (set (attr "prefix_data16")
3110      (if_then_else (eq_attr "mode" "V1DF")
3111        (const_string "1")
3112        (const_string "*")))
3113    (set (attr "mode")
3114         (cond [(eq_attr "alternative" "0,1,2")
3115                  (const_string "DF")
3116                (eq_attr "alternative" "3,4")
3117                  (const_string "SI")
3118
3119                /* For SSE1, we have many fewer alternatives.  */
3120                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3121                  (cond [(eq_attr "alternative" "5,6")
3122                           (const_string "V4SF")
3123                        ]
3124                    (const_string "V2SF"))
3125
3126                /* xorps is one byte shorter.  */
3127                (eq_attr "alternative" "5")
3128                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3129                             (const_int 0))
3130                           (const_string "V4SF")
3131                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3132                             (const_int 0))
3133                           (const_string "TI")
3134                        ]
3135                        (const_string "V2DF"))
3136
3137                /* For architectures resolving dependencies on
3138                   whole SSE registers use APD move to break dependency
3139                   chains, otherwise use short move to avoid extra work.
3140
3141                   movaps encodes one byte shorter.  */
3142                (eq_attr "alternative" "6")
3143                  (cond
3144                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3145                         (const_int 0))
3146                       (const_string "V4SF")
3147                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3148                         (const_int 0))
3149                       (const_string "V2DF")
3150                    ]
3151                    (const_string "DF"))
3152                /* For architectures resolving dependencies on register
3153                   parts we may avoid extra work to zero out upper part
3154                   of register.  */
3155                (eq_attr "alternative" "7")
3156                  (if_then_else
3157                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3158                        (const_int 0))
3159                    (const_string "V1DF")
3160                    (const_string "DF"))
3161               ]
3162               (const_string "DF")))])
3163
3164 (define_insn "*movdf_integer_rex64"
3165   [(set (match_operand:DF 0 "nonimmediate_operand"
3166                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3167         (match_operand:DF 1 "general_operand"
3168                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3169   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3170    && (reload_in_progress || reload_completed
3171        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3172        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3173            && optimize_function_for_size_p (cfun)
3174            && standard_80387_constant_p (operands[1]))
3175        || GET_CODE (operands[1]) != CONST_DOUBLE
3176        || memory_operand (operands[0], DFmode))"
3177 {
3178   switch (which_alternative)
3179     {
3180     case 0:
3181     case 1:
3182       return output_387_reg_move (insn, operands);
3183
3184     case 2:
3185       return standard_80387_constant_opcode (operands[1]);
3186
3187     case 3:
3188     case 4:
3189       return "#";
3190
3191     case 5:
3192       switch (get_attr_mode (insn))
3193         {
3194         case MODE_V4SF:
3195           return "%vxorps\t%0, %d0";
3196         case MODE_V2DF:
3197           return "%vxorpd\t%0, %d0";
3198         case MODE_TI:
3199           return "%vpxor\t%0, %d0";
3200         default:
3201           gcc_unreachable ();
3202         }
3203     case 6:
3204     case 7:
3205     case 8:
3206       switch (get_attr_mode (insn))
3207         {
3208         case MODE_V4SF:
3209           return "%vmovaps\t{%1, %0|%0, %1}";
3210         case MODE_V2DF:
3211           return "%vmovapd\t{%1, %0|%0, %1}";
3212         case MODE_TI:
3213           return "%vmovdqa\t{%1, %0|%0, %1}";
3214         case MODE_DI:
3215           return "%vmovq\t{%1, %0|%0, %1}";
3216         case MODE_DF:
3217           if (TARGET_AVX)
3218             {
3219               if (REG_P (operands[0]) && REG_P (operands[1]))
3220                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3221               else
3222                 return "vmovsd\t{%1, %0|%0, %1}";
3223             }
3224           else
3225             return "movsd\t{%1, %0|%0, %1}";
3226         case MODE_V1DF:
3227           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3228         case MODE_V2SF:
3229           return "%vmovlps\t{%1, %d0|%d0, %1}";
3230         default:
3231           gcc_unreachable ();
3232         }
3233
3234     case 9:
3235     case 10:
3236     return "%vmovd\t{%1, %0|%0, %1}";
3237
3238     default:
3239       gcc_unreachable();
3240     }
3241 }
3242   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3243    (set (attr "prefix")
3244      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3245        (const_string "orig")
3246        (const_string "maybe_vex")))
3247    (set (attr "prefix_data16")
3248      (if_then_else (eq_attr "mode" "V1DF")
3249        (const_string "1")
3250        (const_string "*")))
3251    (set (attr "mode")
3252         (cond [(eq_attr "alternative" "0,1,2")
3253                  (const_string "DF")
3254                (eq_attr "alternative" "3,4,9,10")
3255                  (const_string "DI")
3256
3257                /* For SSE1, we have many fewer alternatives.  */
3258                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3259                  (cond [(eq_attr "alternative" "5,6")
3260                           (const_string "V4SF")
3261                        ]
3262                    (const_string "V2SF"))
3263
3264                /* xorps is one byte shorter.  */
3265                (eq_attr "alternative" "5")
3266                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3267                             (const_int 0))
3268                           (const_string "V4SF")
3269                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3270                             (const_int 0))
3271                           (const_string "TI")
3272                        ]
3273                        (const_string "V2DF"))
3274
3275                /* For architectures resolving dependencies on
3276                   whole SSE registers use APD move to break dependency
3277                   chains, otherwise use short move to avoid extra work.
3278
3279                   movaps encodes one byte shorter.  */
3280                (eq_attr "alternative" "6")
3281                  (cond
3282                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3283                         (const_int 0))
3284                       (const_string "V4SF")
3285                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3286                         (const_int 0))
3287                       (const_string "V2DF")
3288                    ]
3289                    (const_string "DF"))
3290                /* For architectures resolving dependencies on register
3291                   parts we may avoid extra work to zero out upper part
3292                   of register.  */
3293                (eq_attr "alternative" "7")
3294                  (if_then_else
3295                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3296                        (const_int 0))
3297                    (const_string "V1DF")
3298                    (const_string "DF"))
3299               ]
3300               (const_string "DF")))])
3301
3302 (define_insn "*movdf_integer"
3303   [(set (match_operand:DF 0 "nonimmediate_operand"
3304                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3305         (match_operand:DF 1 "general_operand"
3306                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3307   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3308    && optimize_function_for_speed_p (cfun)
3309    && TARGET_INTEGER_DFMODE_MOVES
3310    && (reload_in_progress || reload_completed
3311        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3312        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3313            && optimize_function_for_size_p (cfun)
3314            && standard_80387_constant_p (operands[1]))
3315        || GET_CODE (operands[1]) != CONST_DOUBLE
3316        || memory_operand (operands[0], DFmode))"
3317 {
3318   switch (which_alternative)
3319     {
3320     case 0:
3321     case 1:
3322       return output_387_reg_move (insn, operands);
3323
3324     case 2:
3325       return standard_80387_constant_opcode (operands[1]);
3326
3327     case 3:
3328     case 4:
3329       return "#";
3330
3331     case 5:
3332       switch (get_attr_mode (insn))
3333         {
3334         case MODE_V4SF:
3335           return "xorps\t%0, %0";
3336         case MODE_V2DF:
3337           return "xorpd\t%0, %0";
3338         case MODE_TI:
3339           return "pxor\t%0, %0";
3340         default:
3341           gcc_unreachable ();
3342         }
3343     case 6:
3344     case 7:
3345     case 8:
3346       switch (get_attr_mode (insn))
3347         {
3348         case MODE_V4SF:
3349           return "movaps\t{%1, %0|%0, %1}";
3350         case MODE_V2DF:
3351           return "movapd\t{%1, %0|%0, %1}";
3352         case MODE_TI:
3353           return "movdqa\t{%1, %0|%0, %1}";
3354         case MODE_DI:
3355           return "movq\t{%1, %0|%0, %1}";
3356         case MODE_DF:
3357           return "movsd\t{%1, %0|%0, %1}";
3358         case MODE_V1DF:
3359           return "movlpd\t{%1, %0|%0, %1}";
3360         case MODE_V2SF:
3361           return "movlps\t{%1, %0|%0, %1}";
3362         default:
3363           gcc_unreachable ();
3364         }
3365
3366     default:
3367       gcc_unreachable();
3368     }
3369 }
3370   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3371    (set (attr "prefix_data16")
3372      (if_then_else (eq_attr "mode" "V1DF")
3373        (const_string "1")
3374        (const_string "*")))
3375    (set (attr "mode")
3376         (cond [(eq_attr "alternative" "0,1,2")
3377                  (const_string "DF")
3378                (eq_attr "alternative" "3,4")
3379                  (const_string "SI")
3380
3381                /* For SSE1, we have many fewer alternatives.  */
3382                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3383                  (cond [(eq_attr "alternative" "5,6")
3384                           (const_string "V4SF")
3385                        ]
3386                    (const_string "V2SF"))
3387
3388                /* xorps is one byte shorter.  */
3389                (eq_attr "alternative" "5")
3390                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3391                             (const_int 0))
3392                           (const_string "V4SF")
3393                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3394                             (const_int 0))
3395                           (const_string "TI")
3396                        ]
3397                        (const_string "V2DF"))
3398
3399                /* For architectures resolving dependencies on
3400                   whole SSE registers use APD move to break dependency
3401                   chains, otherwise use short move to avoid extra work.
3402
3403                   movaps encodes one byte shorter.  */
3404                (eq_attr "alternative" "6")
3405                  (cond
3406                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3407                         (const_int 0))
3408                       (const_string "V4SF")
3409                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3410                         (const_int 0))
3411                       (const_string "V2DF")
3412                    ]
3413                    (const_string "DF"))
3414                /* For architectures resolving dependencies on register
3415                   parts we may avoid extra work to zero out upper part
3416                   of register.  */
3417                (eq_attr "alternative" "7")
3418                  (if_then_else
3419                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3420                        (const_int 0))
3421                    (const_string "V1DF")
3422                    (const_string "DF"))
3423               ]
3424               (const_string "DF")))])
3425
3426 (define_split
3427   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3428         (match_operand:DF 1 "general_operand" ""))]
3429   "reload_completed
3430    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3431    && ! (ANY_FP_REG_P (operands[0]) ||
3432          (GET_CODE (operands[0]) == SUBREG
3433           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3434    && ! (ANY_FP_REG_P (operands[1]) ||
3435          (GET_CODE (operands[1]) == SUBREG
3436           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3437   [(const_int 0)]
3438   "ix86_split_long_move (operands); DONE;")
3439
3440 (define_insn "*swapdf"
3441   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3442         (match_operand:DF 1 "fp_register_operand" "+f"))
3443    (set (match_dup 1)
3444         (match_dup 0))]
3445   "reload_completed || TARGET_80387"
3446 {
3447   if (STACK_TOP_P (operands[0]))
3448     return "fxch\t%1";
3449   else
3450     return "fxch\t%0";
3451 }
3452   [(set_attr "type" "fxch")
3453    (set_attr "mode" "DF")])
3454
3455 (define_expand "movxf"
3456   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3457         (match_operand:XF 1 "general_operand" ""))]
3458   ""
3459   "ix86_expand_move (XFmode, operands); DONE;")
3460
3461 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3462 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3463 ;; Pushing using integer instructions is longer except for constants
3464 ;; and direct memory references.
3465 ;; (assuming that any given constant is pushed only once, but this ought to be
3466 ;;  handled elsewhere).
3467
3468 (define_insn "*pushxf_nointeger"
3469   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3470         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3471   "optimize_function_for_size_p (cfun)"
3472 {
3473   /* This insn should be already split before reg-stack.  */
3474   gcc_unreachable ();
3475 }
3476   [(set_attr "type" "multi")
3477    (set_attr "unit" "i387,*,*")
3478    (set_attr "mode" "XF,SI,SI")])
3479
3480 (define_insn "*pushxf_integer"
3481   [(set (match_operand:XF 0 "push_operand" "=<,<")
3482         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3483   "optimize_function_for_speed_p (cfun)"
3484 {
3485   /* This insn should be already split before reg-stack.  */
3486   gcc_unreachable ();
3487 }
3488   [(set_attr "type" "multi")
3489    (set_attr "unit" "i387,*")
3490    (set_attr "mode" "XF,SI")])
3491
3492 (define_split
3493   [(set (match_operand 0 "push_operand" "")
3494         (match_operand 1 "general_operand" ""))]
3495   "reload_completed
3496    && (GET_MODE (operands[0]) == XFmode
3497        || GET_MODE (operands[0]) == DFmode)
3498    && !ANY_FP_REG_P (operands[1])"
3499   [(const_int 0)]
3500   "ix86_split_long_move (operands); DONE;")
3501
3502 (define_split
3503   [(set (match_operand:XF 0 "push_operand" "")
3504         (match_operand:XF 1 "any_fp_register_operand" ""))]
3505   ""
3506   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3507    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3508   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509
3510 ;; Do not use integer registers when optimizing for size
3511 (define_insn "*movxf_nointeger"
3512   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3513         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3514   "optimize_function_for_size_p (cfun)
3515    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3516    && (reload_in_progress || reload_completed
3517        || standard_80387_constant_p (operands[1])
3518        || GET_CODE (operands[1]) != CONST_DOUBLE
3519        || memory_operand (operands[0], XFmode))"
3520 {
3521   switch (which_alternative)
3522     {
3523     case 0:
3524     case 1:
3525       return output_387_reg_move (insn, operands);
3526
3527     case 2:
3528       return standard_80387_constant_opcode (operands[1]);
3529
3530     case 3: case 4:
3531       return "#";
3532     default:
3533       gcc_unreachable ();
3534     }
3535 }
3536   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3537    (set_attr "mode" "XF,XF,XF,SI,SI")])
3538
3539 (define_insn "*movxf_integer"
3540   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3541         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3542   "optimize_function_for_speed_p (cfun)
3543    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3544    && (reload_in_progress || reload_completed
3545        || GET_CODE (operands[1]) != CONST_DOUBLE
3546        || memory_operand (operands[0], XFmode))"
3547 {
3548   switch (which_alternative)
3549     {
3550     case 0:
3551     case 1:
3552       return output_387_reg_move (insn, operands);
3553
3554     case 2:
3555       return standard_80387_constant_opcode (operands[1]);
3556
3557     case 3: case 4:
3558       return "#";
3559
3560     default:
3561       gcc_unreachable ();
3562     }
3563 }
3564   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3565    (set_attr "mode" "XF,XF,XF,SI,SI")])
3566
3567 (define_expand "movtf"
3568   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3569         (match_operand:TF 1 "nonimmediate_operand" ""))]
3570   "TARGET_SSE2"
3571 {
3572   ix86_expand_move (TFmode, operands);
3573   DONE;
3574 })
3575
3576 (define_insn "*movtf_internal"
3577   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3578         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3579   "TARGET_SSE2
3580    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3581 {
3582   switch (which_alternative)
3583     {
3584     case 0:
3585     case 1:
3586       if (get_attr_mode (insn) == MODE_V4SF)
3587         return "%vmovaps\t{%1, %0|%0, %1}";
3588       else
3589         return "%vmovdqa\t{%1, %0|%0, %1}";
3590     case 2:
3591       if (get_attr_mode (insn) == MODE_V4SF)
3592         return "%vxorps\t%0, %d0";
3593       else
3594         return "%vpxor\t%0, %d0";
3595     case 3:
3596     case 4:
3597         return "#";
3598     default:
3599       gcc_unreachable ();
3600     }
3601 }
3602   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3603    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3604    (set (attr "mode")
3605         (cond [(eq_attr "alternative" "0,2")
3606                  (if_then_else
3607                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3608                        (const_int 0))
3609                    (const_string "V4SF")
3610                    (const_string "TI"))
3611                (eq_attr "alternative" "1")
3612                  (if_then_else
3613                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3614                             (const_int 0))
3615                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3616                             (const_int 0)))
3617                    (const_string "V4SF")
3618                    (const_string "TI"))]
3619                (const_string "DI")))])
3620
3621 (define_insn "*pushtf_sse"
3622   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3623         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3624   "TARGET_SSE2"
3625 {
3626   /* This insn should be already split before reg-stack.  */
3627   gcc_unreachable ();
3628 }
3629   [(set_attr "type" "multi")
3630    (set_attr "unit" "sse,*,*")
3631    (set_attr "mode" "TF,SI,SI")])
3632
3633 (define_split
3634   [(set (match_operand:TF 0 "push_operand" "")
3635         (match_operand:TF 1 "general_operand" ""))]
3636   "TARGET_SSE2 && reload_completed
3637    && !SSE_REG_P (operands[1])"
3638   [(const_int 0)]
3639   "ix86_split_long_move (operands); DONE;")
3640
3641 (define_split
3642   [(set (match_operand:TF 0 "push_operand" "")
3643         (match_operand:TF 1 "any_fp_register_operand" ""))]
3644   "TARGET_SSE2"
3645   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3646    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3647   "")
3648
3649 (define_split
3650   [(set (match_operand 0 "nonimmediate_operand" "")
3651         (match_operand 1 "general_operand" ""))]
3652   "reload_completed
3653    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3654    && GET_MODE (operands[0]) == XFmode
3655    && ! (ANY_FP_REG_P (operands[0]) ||
3656          (GET_CODE (operands[0]) == SUBREG
3657           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3658    && ! (ANY_FP_REG_P (operands[1]) ||
3659          (GET_CODE (operands[1]) == SUBREG
3660           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3661   [(const_int 0)]
3662   "ix86_split_long_move (operands); DONE;")
3663
3664 (define_split
3665   [(set (match_operand 0 "register_operand" "")
3666         (match_operand 1 "memory_operand" ""))]
3667   "reload_completed
3668    && MEM_P (operands[1])
3669    && (GET_MODE (operands[0]) == TFmode
3670        || GET_MODE (operands[0]) == XFmode
3671        || GET_MODE (operands[0]) == SFmode
3672        || GET_MODE (operands[0]) == DFmode)
3673    && (operands[2] = find_constant_src (insn))"
3674   [(set (match_dup 0) (match_dup 2))]
3675 {
3676   rtx c = operands[2];
3677   rtx r = operands[0];
3678
3679   if (GET_CODE (r) == SUBREG)
3680     r = SUBREG_REG (r);
3681
3682   if (SSE_REG_P (r))
3683     {
3684       if (!standard_sse_constant_p (c))
3685         FAIL;
3686     }
3687   else if (FP_REG_P (r))
3688     {
3689       if (!standard_80387_constant_p (c))
3690         FAIL;
3691     }
3692   else if (MMX_REG_P (r))
3693     FAIL;
3694 })
3695
3696 (define_split
3697   [(set (match_operand 0 "register_operand" "")
3698         (float_extend (match_operand 1 "memory_operand" "")))]
3699   "reload_completed
3700    && MEM_P (operands[1])
3701    && (GET_MODE (operands[0]) == TFmode
3702        || GET_MODE (operands[0]) == XFmode
3703        || GET_MODE (operands[0]) == SFmode
3704        || GET_MODE (operands[0]) == DFmode)
3705    && (operands[2] = find_constant_src (insn))"
3706   [(set (match_dup 0) (match_dup 2))]
3707 {
3708   rtx c = operands[2];
3709   rtx r = operands[0];
3710
3711   if (GET_CODE (r) == SUBREG)
3712     r = SUBREG_REG (r);
3713
3714   if (SSE_REG_P (r))
3715     {
3716       if (!standard_sse_constant_p (c))
3717         FAIL;
3718     }
3719   else if (FP_REG_P (r))
3720     {
3721       if (!standard_80387_constant_p (c))
3722         FAIL;
3723     }
3724   else if (MMX_REG_P (r))
3725     FAIL;
3726 })
3727
3728 (define_insn "swapxf"
3729   [(set (match_operand:XF 0 "register_operand" "+f")
3730         (match_operand:XF 1 "register_operand" "+f"))
3731    (set (match_dup 1)
3732         (match_dup 0))]
3733   "TARGET_80387"
3734 {
3735   if (STACK_TOP_P (operands[0]))
3736     return "fxch\t%1";
3737   else
3738     return "fxch\t%0";
3739 }
3740   [(set_attr "type" "fxch")
3741    (set_attr "mode" "XF")])
3742
3743 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3744 (define_split
3745   [(set (match_operand:X87MODEF 0 "register_operand" "")
3746         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3747   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3748    && (standard_80387_constant_p (operands[1]) == 8
3749        || standard_80387_constant_p (operands[1]) == 9)"
3750   [(set (match_dup 0)(match_dup 1))
3751    (set (match_dup 0)
3752         (neg:X87MODEF (match_dup 0)))]
3753 {
3754   REAL_VALUE_TYPE r;
3755
3756   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3757   if (real_isnegzero (&r))
3758     operands[1] = CONST0_RTX (<MODE>mode);
3759   else
3760     operands[1] = CONST1_RTX (<MODE>mode);
3761 })
3762
3763 (define_split
3764   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3765         (match_operand:TF 1 "general_operand" ""))]
3766   "reload_completed
3767    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3768   [(const_int 0)]
3769   "ix86_split_long_move (operands); DONE;")
3770 \f
3771 ;; Zero extension instructions
3772
3773 (define_expand "zero_extendhisi2"
3774   [(set (match_operand:SI 0 "register_operand" "")
3775      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3776   ""
3777 {
3778   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3779     {
3780       operands[1] = force_reg (HImode, operands[1]);
3781       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3782       DONE;
3783     }
3784 })
3785
3786 (define_insn "zero_extendhisi2_and"
3787   [(set (match_operand:SI 0 "register_operand" "=r")
3788      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3789    (clobber (reg:CC FLAGS_REG))]
3790   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3791   "#"
3792   [(set_attr "type" "alu1")
3793    (set_attr "mode" "SI")])
3794
3795 (define_split
3796   [(set (match_operand:SI 0 "register_operand" "")
3797         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3798    (clobber (reg:CC FLAGS_REG))]
3799   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3800    && optimize_function_for_speed_p (cfun)"
3801   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3802               (clobber (reg:CC FLAGS_REG))])]
3803   "")
3804
3805 (define_insn "*zero_extendhisi2_movzwl"
3806   [(set (match_operand:SI 0 "register_operand" "=r")
3807      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3808   "!TARGET_ZERO_EXTEND_WITH_AND
3809    || optimize_function_for_size_p (cfun)"
3810   "movz{wl|x}\t{%1, %0|%0, %1}"
3811   [(set_attr "type" "imovx")
3812    (set_attr "mode" "SI")])
3813
3814 (define_expand "zero_extendqihi2"
3815   [(parallel
3816     [(set (match_operand:HI 0 "register_operand" "")
3817        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3818      (clobber (reg:CC FLAGS_REG))])]
3819   ""
3820   "")
3821
3822 (define_insn "*zero_extendqihi2_and"
3823   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3824      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3825    (clobber (reg:CC FLAGS_REG))]
3826   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3827   "#"
3828   [(set_attr "type" "alu1")
3829    (set_attr "mode" "HI")])
3830
3831 (define_insn "*zero_extendqihi2_movzbw_and"
3832   [(set (match_operand:HI 0 "register_operand" "=r,r")
3833      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3834    (clobber (reg:CC FLAGS_REG))]
3835   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3836   "#"
3837   [(set_attr "type" "imovx,alu1")
3838    (set_attr "mode" "HI")])
3839
3840 ; zero extend to SImode here to avoid partial register stalls
3841 (define_insn "*zero_extendqihi2_movzbl"
3842   [(set (match_operand:HI 0 "register_operand" "=r")
3843      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3844   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3845    && reload_completed"
3846   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3847   [(set_attr "type" "imovx")
3848    (set_attr "mode" "SI")])
3849
3850 ;; For the movzbw case strip only the clobber
3851 (define_split
3852   [(set (match_operand:HI 0 "register_operand" "")
3853         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3854    (clobber (reg:CC FLAGS_REG))]
3855   "reload_completed
3856    && (!TARGET_ZERO_EXTEND_WITH_AND
3857        || optimize_function_for_size_p (cfun))
3858    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3859   [(set (match_operand:HI 0 "register_operand" "")
3860         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3861
3862 ;; When source and destination does not overlap, clear destination
3863 ;; first and then do the movb
3864 (define_split
3865   [(set (match_operand:HI 0 "register_operand" "")
3866         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3867    (clobber (reg:CC FLAGS_REG))]
3868   "reload_completed
3869    && ANY_QI_REG_P (operands[0])
3870    && (TARGET_ZERO_EXTEND_WITH_AND
3871        && optimize_function_for_speed_p (cfun))
3872    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3873   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3874 {
3875   operands[2] = gen_lowpart (QImode, operands[0]);
3876   ix86_expand_clear (operands[0]);
3877 })
3878
3879 ;; Rest is handled by single and.
3880 (define_split
3881   [(set (match_operand:HI 0 "register_operand" "")
3882         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3883    (clobber (reg:CC FLAGS_REG))]
3884   "reload_completed
3885    && true_regnum (operands[0]) == true_regnum (operands[1])"
3886   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3887               (clobber (reg:CC FLAGS_REG))])]
3888   "")
3889
3890 (define_expand "zero_extendqisi2"
3891   [(parallel
3892     [(set (match_operand:SI 0 "register_operand" "")
3893        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3894      (clobber (reg:CC FLAGS_REG))])]
3895   ""
3896   "")
3897
3898 (define_insn "*zero_extendqisi2_and"
3899   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3900      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3901    (clobber (reg:CC FLAGS_REG))]
3902   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3903   "#"
3904   [(set_attr "type" "alu1")
3905    (set_attr "mode" "SI")])
3906
3907 (define_insn "*zero_extendqisi2_movzbl_and"
3908   [(set (match_operand:SI 0 "register_operand" "=r,r")
3909      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3910    (clobber (reg:CC FLAGS_REG))]
3911   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3912   "#"
3913   [(set_attr "type" "imovx,alu1")
3914    (set_attr "mode" "SI")])
3915
3916 (define_insn "*zero_extendqisi2_movzbl"
3917   [(set (match_operand:SI 0 "register_operand" "=r")
3918      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3919   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3920    && reload_completed"
3921   "movz{bl|x}\t{%1, %0|%0, %1}"
3922   [(set_attr "type" "imovx")
3923    (set_attr "mode" "SI")])
3924
3925 ;; For the movzbl case strip only the clobber
3926 (define_split
3927   [(set (match_operand:SI 0 "register_operand" "")
3928         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3929    (clobber (reg:CC FLAGS_REG))]
3930   "reload_completed
3931    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3932    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3933   [(set (match_dup 0)
3934         (zero_extend:SI (match_dup 1)))])
3935
3936 ;; When source and destination does not overlap, clear destination
3937 ;; first and then do the movb
3938 (define_split
3939   [(set (match_operand:SI 0 "register_operand" "")
3940         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3941    (clobber (reg:CC FLAGS_REG))]
3942   "reload_completed
3943    && ANY_QI_REG_P (operands[0])
3944    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3945    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3946    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3947   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3948 {
3949   operands[2] = gen_lowpart (QImode, operands[0]);
3950   ix86_expand_clear (operands[0]);
3951 })
3952
3953 ;; Rest is handled by single and.
3954 (define_split
3955   [(set (match_operand:SI 0 "register_operand" "")
3956         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3957    (clobber (reg:CC FLAGS_REG))]
3958   "reload_completed
3959    && true_regnum (operands[0]) == true_regnum (operands[1])"
3960   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3961               (clobber (reg:CC FLAGS_REG))])]
3962   "")
3963
3964 ;; %%% Kill me once multi-word ops are sane.
3965 (define_expand "zero_extendsidi2"
3966   [(set (match_operand:DI 0 "register_operand" "")
3967      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3968   ""
3969 {
3970   if (!TARGET_64BIT)
3971     {
3972       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3973       DONE;
3974     }
3975 })
3976
3977 (define_insn "zero_extendsidi2_32"
3978   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3979         (zero_extend:DI
3980          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3981    (clobber (reg:CC FLAGS_REG))]
3982   "!TARGET_64BIT"
3983   "@
3984    #
3985    #
3986    #
3987    movd\t{%1, %0|%0, %1}
3988    movd\t{%1, %0|%0, %1}
3989    %vmovd\t{%1, %0|%0, %1}
3990    %vmovd\t{%1, %0|%0, %1}"
3991   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3992    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3993    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3994
3995 (define_insn "zero_extendsidi2_rex64"
3996   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3997      (zero_extend:DI
3998        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3999   "TARGET_64BIT"
4000   "@
4001    mov\t{%k1, %k0|%k0, %k1}
4002    #
4003    movd\t{%1, %0|%0, %1}
4004    movd\t{%1, %0|%0, %1}
4005    %vmovd\t{%1, %0|%0, %1}
4006    %vmovd\t{%1, %0|%0, %1}"
4007   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4008    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4009    (set_attr "prefix_0f" "0,*,*,*,*,*")
4010    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4011
4012 (define_split
4013   [(set (match_operand:DI 0 "memory_operand" "")
4014      (zero_extend:DI (match_dup 0)))]
4015   "TARGET_64BIT"
4016   [(set (match_dup 4) (const_int 0))]
4017   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4018
4019 (define_split
4020   [(set (match_operand:DI 0 "register_operand" "")
4021         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4022    (clobber (reg:CC FLAGS_REG))]
4023   "!TARGET_64BIT && reload_completed
4024    && true_regnum (operands[0]) == true_regnum (operands[1])"
4025   [(set (match_dup 4) (const_int 0))]
4026   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4027
4028 (define_split
4029   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4030         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4031    (clobber (reg:CC FLAGS_REG))]
4032   "!TARGET_64BIT && reload_completed
4033    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4034   [(set (match_dup 3) (match_dup 1))
4035    (set (match_dup 4) (const_int 0))]
4036   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4037
4038 (define_insn "zero_extendhidi2"
4039   [(set (match_operand:DI 0 "register_operand" "=r")
4040      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4041   "TARGET_64BIT"
4042   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4043   [(set_attr "type" "imovx")
4044    (set_attr "mode" "SI")])
4045
4046 (define_insn "zero_extendqidi2"
4047   [(set (match_operand:DI 0 "register_operand" "=r")
4048      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4049   "TARGET_64BIT"
4050   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4051   [(set_attr "type" "imovx")
4052    (set_attr "mode" "SI")])
4053 \f
4054 ;; Sign extension instructions
4055
4056 (define_expand "extendsidi2"
4057   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4058                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4059               (clobber (reg:CC FLAGS_REG))
4060               (clobber (match_scratch:SI 2 ""))])]
4061   ""
4062 {
4063   if (TARGET_64BIT)
4064     {
4065       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4066       DONE;
4067     }
4068 })
4069
4070 (define_insn "*extendsidi2_1"
4071   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4072         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4073    (clobber (reg:CC FLAGS_REG))
4074    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4075   "!TARGET_64BIT"
4076   "#")
4077
4078 (define_insn "extendsidi2_rex64"
4079   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4080         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4081   "TARGET_64BIT"
4082   "@
4083    {cltq|cdqe}
4084    movs{lq|x}\t{%1, %0|%0, %1}"
4085   [(set_attr "type" "imovx")
4086    (set_attr "mode" "DI")
4087    (set_attr "prefix_0f" "0")
4088    (set_attr "modrm" "0,1")])
4089
4090 (define_insn "extendhidi2"
4091   [(set (match_operand:DI 0 "register_operand" "=r")
4092         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4093   "TARGET_64BIT"
4094   "movs{wq|x}\t{%1, %0|%0, %1}"
4095   [(set_attr "type" "imovx")
4096    (set_attr "mode" "DI")])
4097
4098 (define_insn "extendqidi2"
4099   [(set (match_operand:DI 0 "register_operand" "=r")
4100         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4101   "TARGET_64BIT"
4102   "movs{bq|x}\t{%1, %0|%0, %1}"
4103    [(set_attr "type" "imovx")
4104     (set_attr "mode" "DI")])
4105
4106 ;; Extend to memory case when source register does die.
4107 (define_split
4108   [(set (match_operand:DI 0 "memory_operand" "")
4109         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4110    (clobber (reg:CC FLAGS_REG))
4111    (clobber (match_operand:SI 2 "register_operand" ""))]
4112   "(reload_completed
4113     && dead_or_set_p (insn, operands[1])
4114     && !reg_mentioned_p (operands[1], operands[0]))"
4115   [(set (match_dup 3) (match_dup 1))
4116    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4117               (clobber (reg:CC FLAGS_REG))])
4118    (set (match_dup 4) (match_dup 1))]
4119   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4120
4121 ;; Extend to memory case when source register does not die.
4122 (define_split
4123   [(set (match_operand:DI 0 "memory_operand" "")
4124         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4125    (clobber (reg:CC FLAGS_REG))
4126    (clobber (match_operand:SI 2 "register_operand" ""))]
4127   "reload_completed"
4128   [(const_int 0)]
4129 {
4130   split_di (&operands[0], 1, &operands[3], &operands[4]);
4131
4132   emit_move_insn (operands[3], operands[1]);
4133
4134   /* Generate a cltd if possible and doing so it profitable.  */
4135   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4136       && true_regnum (operands[1]) == AX_REG
4137       && true_regnum (operands[2]) == DX_REG)
4138     {
4139       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4140     }
4141   else
4142     {
4143       emit_move_insn (operands[2], operands[1]);
4144       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4145     }
4146   emit_move_insn (operands[4], operands[2]);
4147   DONE;
4148 })
4149
4150 ;; Extend to register case.  Optimize case where source and destination
4151 ;; registers match and cases where we can use cltd.
4152 (define_split
4153   [(set (match_operand:DI 0 "register_operand" "")
4154         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4155    (clobber (reg:CC FLAGS_REG))
4156    (clobber (match_scratch:SI 2 ""))]
4157   "reload_completed"
4158   [(const_int 0)]
4159 {
4160   split_di (&operands[0], 1, &operands[3], &operands[4]);
4161
4162   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4163     emit_move_insn (operands[3], operands[1]);
4164
4165   /* Generate a cltd if possible and doing so it profitable.  */
4166   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4167       && true_regnum (operands[3]) == AX_REG)
4168     {
4169       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4170       DONE;
4171     }
4172
4173   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4174     emit_move_insn (operands[4], operands[1]);
4175
4176   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4177   DONE;
4178 })
4179
4180 (define_insn "extendhisi2"
4181   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4182         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4183   ""
4184 {
4185   switch (get_attr_prefix_0f (insn))
4186     {
4187     case 0:
4188       return "{cwtl|cwde}";
4189     default:
4190       return "movs{wl|x}\t{%1, %0|%0, %1}";
4191     }
4192 }
4193   [(set_attr "type" "imovx")
4194    (set_attr "mode" "SI")
4195    (set (attr "prefix_0f")
4196      ;; movsx is short decodable while cwtl is vector decoded.
4197      (if_then_else (and (eq_attr "cpu" "!k6")
4198                         (eq_attr "alternative" "0"))
4199         (const_string "0")
4200         (const_string "1")))
4201    (set (attr "modrm")
4202      (if_then_else (eq_attr "prefix_0f" "0")
4203         (const_string "0")
4204         (const_string "1")))])
4205
4206 (define_insn "*extendhisi2_zext"
4207   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4208         (zero_extend:DI
4209           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4210   "TARGET_64BIT"
4211 {
4212   switch (get_attr_prefix_0f (insn))
4213     {
4214     case 0:
4215       return "{cwtl|cwde}";
4216     default:
4217       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4218     }
4219 }
4220   [(set_attr "type" "imovx")
4221    (set_attr "mode" "SI")
4222    (set (attr "prefix_0f")
4223      ;; movsx is short decodable while cwtl is vector decoded.
4224      (if_then_else (and (eq_attr "cpu" "!k6")
4225                         (eq_attr "alternative" "0"))
4226         (const_string "0")
4227         (const_string "1")))
4228    (set (attr "modrm")
4229      (if_then_else (eq_attr "prefix_0f" "0")
4230         (const_string "0")
4231         (const_string "1")))])
4232
4233 (define_insn "extendqihi2"
4234   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4235         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4236   ""
4237 {
4238   switch (get_attr_prefix_0f (insn))
4239     {
4240     case 0:
4241       return "{cbtw|cbw}";
4242     default:
4243       return "movs{bw|x}\t{%1, %0|%0, %1}";
4244     }
4245 }
4246   [(set_attr "type" "imovx")
4247    (set_attr "mode" "HI")
4248    (set (attr "prefix_0f")
4249      ;; movsx is short decodable while cwtl is vector decoded.
4250      (if_then_else (and (eq_attr "cpu" "!k6")
4251                         (eq_attr "alternative" "0"))
4252         (const_string "0")
4253         (const_string "1")))
4254    (set (attr "modrm")
4255      (if_then_else (eq_attr "prefix_0f" "0")
4256         (const_string "0")
4257         (const_string "1")))])
4258
4259 (define_insn "extendqisi2"
4260   [(set (match_operand:SI 0 "register_operand" "=r")
4261         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4262   ""
4263   "movs{bl|x}\t{%1, %0|%0, %1}"
4264    [(set_attr "type" "imovx")
4265     (set_attr "mode" "SI")])
4266
4267 (define_insn "*extendqisi2_zext"
4268   [(set (match_operand:DI 0 "register_operand" "=r")
4269         (zero_extend:DI
4270           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4271   "TARGET_64BIT"
4272   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4273    [(set_attr "type" "imovx")
4274     (set_attr "mode" "SI")])
4275 \f
4276 ;; Conversions between float and double.
4277
4278 ;; These are all no-ops in the model used for the 80387.  So just
4279 ;; emit moves.
4280
4281 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4282 (define_insn "*dummy_extendsfdf2"
4283   [(set (match_operand:DF 0 "push_operand" "=<")
4284         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4285   "0"
4286   "#")
4287
4288 (define_split
4289   [(set (match_operand:DF 0 "push_operand" "")
4290         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4291   ""
4292   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4293    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4294
4295 (define_insn "*dummy_extendsfxf2"
4296   [(set (match_operand:XF 0 "push_operand" "=<")
4297         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4298   "0"
4299   "#")
4300
4301 (define_split
4302   [(set (match_operand:XF 0 "push_operand" "")
4303         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4304   ""
4305   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4306    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4307   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4308
4309 (define_split
4310   [(set (match_operand:XF 0 "push_operand" "")
4311         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4312   ""
4313   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4314    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4315   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4316
4317 (define_expand "extendsfdf2"
4318   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4319         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4320   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4321 {
4322   /* ??? Needed for compress_float_constant since all fp constants
4323      are LEGITIMATE_CONSTANT_P.  */
4324   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4325     {
4326       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4327           && standard_80387_constant_p (operands[1]) > 0)
4328         {
4329           operands[1] = simplify_const_unary_operation
4330             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4331           emit_move_insn_1 (operands[0], operands[1]);
4332           DONE;
4333         }
4334       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4335     }
4336 })
4337
4338 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4339    cvtss2sd:
4340       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4341       cvtps2pd xmm2,xmm1
4342    We do the conversion post reload to avoid producing of 128bit spills
4343    that might lead to ICE on 32bit target.  The sequence unlikely combine
4344    anyway.  */
4345 (define_split
4346   [(set (match_operand:DF 0 "register_operand" "")
4347         (float_extend:DF
4348           (match_operand:SF 1 "nonimmediate_operand" "")))]
4349   "TARGET_USE_VECTOR_FP_CONVERTS
4350    && optimize_insn_for_speed_p ()
4351    && reload_completed && SSE_REG_P (operands[0])"
4352    [(set (match_dup 2)
4353          (float_extend:V2DF
4354            (vec_select:V2SF
4355              (match_dup 3)
4356              (parallel [(const_int 0) (const_int 1)]))))]
4357 {
4358   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4359   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4360   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4361      Try to avoid move when unpacking can be done in source.  */
4362   if (REG_P (operands[1]))
4363     {
4364       /* If it is unsafe to overwrite upper half of source, we need
4365          to move to destination and unpack there.  */
4366       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4367            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4368           && true_regnum (operands[0]) != true_regnum (operands[1]))
4369         {
4370           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4371           emit_move_insn (tmp, operands[1]);
4372         }
4373       else
4374         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4375       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4376     }
4377   else
4378     emit_insn (gen_vec_setv4sf_0 (operands[3],
4379                                   CONST0_RTX (V4SFmode), operands[1]));
4380 })
4381
4382 (define_insn "*extendsfdf2_mixed"
4383   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4384         (float_extend:DF
4385           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4386   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4387 {
4388   switch (which_alternative)
4389     {
4390     case 0:
4391     case 1:
4392       return output_387_reg_move (insn, operands);
4393
4394     case 2:
4395       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4396
4397     default:
4398       gcc_unreachable ();
4399     }
4400 }
4401   [(set_attr "type" "fmov,fmov,ssecvt")
4402    (set_attr "prefix" "orig,orig,maybe_vex")
4403    (set_attr "mode" "SF,XF,DF")])
4404
4405 (define_insn "*extendsfdf2_sse"
4406   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4407         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4408   "TARGET_SSE2 && TARGET_SSE_MATH"
4409   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4410   [(set_attr "type" "ssecvt")
4411    (set_attr "prefix" "maybe_vex")
4412    (set_attr "mode" "DF")])
4413
4414 (define_insn "*extendsfdf2_i387"
4415   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4416         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4417   "TARGET_80387"
4418   "* return output_387_reg_move (insn, operands);"
4419   [(set_attr "type" "fmov")
4420    (set_attr "mode" "SF,XF")])
4421
4422 (define_expand "extend<mode>xf2"
4423   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4424         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4425   "TARGET_80387"
4426 {
4427   /* ??? Needed for compress_float_constant since all fp constants
4428      are LEGITIMATE_CONSTANT_P.  */
4429   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4430     {
4431       if (standard_80387_constant_p (operands[1]) > 0)
4432         {
4433           operands[1] = simplify_const_unary_operation
4434             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4435           emit_move_insn_1 (operands[0], operands[1]);
4436           DONE;
4437         }
4438       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4439     }
4440 })
4441
4442 (define_insn "*extend<mode>xf2_i387"
4443   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4444         (float_extend:XF
4445           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4446   "TARGET_80387"
4447   "* return output_387_reg_move (insn, operands);"
4448   [(set_attr "type" "fmov")
4449    (set_attr "mode" "<MODE>,XF")])
4450
4451 ;; %%% This seems bad bad news.
4452 ;; This cannot output into an f-reg because there is no way to be sure
4453 ;; of truncating in that case.  Otherwise this is just like a simple move
4454 ;; insn.  So we pretend we can output to a reg in order to get better
4455 ;; register preferencing, but we really use a stack slot.
4456
4457 ;; Conversion from DFmode to SFmode.
4458
4459 (define_expand "truncdfsf2"
4460   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4461         (float_truncate:SF
4462           (match_operand:DF 1 "nonimmediate_operand" "")))]
4463   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4464 {
4465   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4466     ;
4467   else if (flag_unsafe_math_optimizations)
4468     ;
4469   else
4470     {
4471       enum ix86_stack_slot slot = (virtuals_instantiated
4472                                    ? SLOT_TEMP
4473                                    : SLOT_VIRTUAL);
4474       rtx temp = assign_386_stack_local (SFmode, slot);
4475       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4476       DONE;
4477     }
4478 })
4479
4480 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4481    cvtsd2ss:
4482       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4483       cvtpd2ps xmm2,xmm1
4484    We do the conversion post reload to avoid producing of 128bit spills
4485    that might lead to ICE on 32bit target.  The sequence unlikely combine
4486    anyway.  */
4487 (define_split
4488   [(set (match_operand:SF 0 "register_operand" "")
4489         (float_truncate:SF
4490           (match_operand:DF 1 "nonimmediate_operand" "")))]
4491   "TARGET_USE_VECTOR_FP_CONVERTS
4492    && optimize_insn_for_speed_p ()
4493    && reload_completed && SSE_REG_P (operands[0])"
4494    [(set (match_dup 2)
4495          (vec_concat:V4SF
4496            (float_truncate:V2SF
4497              (match_dup 4))
4498            (match_dup 3)))]
4499 {
4500   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4501   operands[3] = CONST0_RTX (V2SFmode);
4502   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4503   /* Use movsd for loading from memory, unpcklpd for registers.
4504      Try to avoid move when unpacking can be done in source, or SSE3
4505      movddup is available.  */
4506   if (REG_P (operands[1]))
4507     {
4508       if (!TARGET_SSE3
4509           && true_regnum (operands[0]) != true_regnum (operands[1])
4510           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4511               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4512         {
4513           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4514           emit_move_insn (tmp, operands[1]);
4515           operands[1] = tmp;
4516         }
4517       else if (!TARGET_SSE3)
4518         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4519       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4520     }
4521   else
4522     emit_insn (gen_sse2_loadlpd (operands[4],
4523                                  CONST0_RTX (V2DFmode), operands[1]));
4524 })
4525
4526 (define_expand "truncdfsf2_with_temp"
4527   [(parallel [(set (match_operand:SF 0 "" "")
4528                    (float_truncate:SF (match_operand:DF 1 "" "")))
4529               (clobber (match_operand:SF 2 "" ""))])]
4530   "")
4531
4532 (define_insn "*truncdfsf_fast_mixed"
4533   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4534         (float_truncate:SF
4535           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4536   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4537 {
4538   switch (which_alternative)
4539     {
4540     case 0:
4541       return output_387_reg_move (insn, operands);
4542     case 1:
4543       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4544     default:
4545       gcc_unreachable ();
4546     }
4547 }
4548   [(set_attr "type" "fmov,ssecvt")
4549    (set_attr "prefix" "orig,maybe_vex")
4550    (set_attr "mode" "SF")])
4551
4552 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4553 ;; because nothing we do here is unsafe.
4554 (define_insn "*truncdfsf_fast_sse"
4555   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4556         (float_truncate:SF
4557           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4558   "TARGET_SSE2 && TARGET_SSE_MATH"
4559   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4560   [(set_attr "type" "ssecvt")
4561    (set_attr "prefix" "maybe_vex")
4562    (set_attr "mode" "SF")])
4563
4564 (define_insn "*truncdfsf_fast_i387"
4565   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4566         (float_truncate:SF
4567           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4568   "TARGET_80387 && flag_unsafe_math_optimizations"
4569   "* return output_387_reg_move (insn, operands);"
4570   [(set_attr "type" "fmov")
4571    (set_attr "mode" "SF")])
4572
4573 (define_insn "*truncdfsf_mixed"
4574   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4575         (float_truncate:SF
4576           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4577    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4578   "TARGET_MIX_SSE_I387"
4579 {
4580   switch (which_alternative)
4581     {
4582     case 0:
4583       return output_387_reg_move (insn, operands);
4584     case 1:
4585       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4586
4587     default:
4588       return "#";
4589     }
4590 }
4591   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4592    (set_attr "unit" "*,*,i387,i387,i387")
4593    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4594    (set_attr "mode" "SF")])
4595
4596 (define_insn "*truncdfsf_i387"
4597   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4598         (float_truncate:SF
4599           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4600    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4601   "TARGET_80387"
4602 {
4603   switch (which_alternative)
4604     {
4605     case 0:
4606       return output_387_reg_move (insn, operands);
4607
4608     default:
4609       return "#";
4610     }
4611 }
4612   [(set_attr "type" "fmov,multi,multi,multi")
4613    (set_attr "unit" "*,i387,i387,i387")
4614    (set_attr "mode" "SF")])
4615
4616 (define_insn "*truncdfsf2_i387_1"
4617   [(set (match_operand:SF 0 "memory_operand" "=m")
4618         (float_truncate:SF
4619           (match_operand:DF 1 "register_operand" "f")))]
4620   "TARGET_80387
4621    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4622    && !TARGET_MIX_SSE_I387"
4623   "* return output_387_reg_move (insn, operands);"
4624   [(set_attr "type" "fmov")
4625    (set_attr "mode" "SF")])
4626
4627 (define_split
4628   [(set (match_operand:SF 0 "register_operand" "")
4629         (float_truncate:SF
4630          (match_operand:DF 1 "fp_register_operand" "")))
4631    (clobber (match_operand 2 "" ""))]
4632   "reload_completed"
4633   [(set (match_dup 2) (match_dup 1))
4634    (set (match_dup 0) (match_dup 2))]
4635 {
4636   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4637 })
4638
4639 ;; Conversion from XFmode to {SF,DF}mode
4640
4641 (define_expand "truncxf<mode>2"
4642   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4643                    (float_truncate:MODEF
4644                      (match_operand:XF 1 "register_operand" "")))
4645               (clobber (match_dup 2))])]
4646   "TARGET_80387"
4647 {
4648   if (flag_unsafe_math_optimizations)
4649     {
4650       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4651       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4652       if (reg != operands[0])
4653         emit_move_insn (operands[0], reg);
4654       DONE;
4655     }
4656   else
4657     {
4658      enum ix86_stack_slot slot = (virtuals_instantiated
4659                                   ? SLOT_TEMP
4660                                   : SLOT_VIRTUAL);
4661       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4662     }
4663 })
4664
4665 (define_insn "*truncxfsf2_mixed"
4666   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4667         (float_truncate:SF
4668           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4669    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4670   "TARGET_80387"
4671 {
4672   gcc_assert (!which_alternative);
4673   return output_387_reg_move (insn, operands);
4674 }
4675   [(set_attr "type" "fmov,multi,multi,multi")
4676    (set_attr "unit" "*,i387,i387,i387")
4677    (set_attr "mode" "SF")])
4678
4679 (define_insn "*truncxfdf2_mixed"
4680   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4681         (float_truncate:DF
4682           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4683    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4684   "TARGET_80387"
4685 {
4686   gcc_assert (!which_alternative);
4687   return output_387_reg_move (insn, operands);
4688 }
4689   [(set_attr "type" "fmov,multi,multi,multi")
4690    (set_attr "unit" "*,i387,i387,i387")
4691    (set_attr "mode" "DF")])
4692
4693 (define_insn "truncxf<mode>2_i387_noop"
4694   [(set (match_operand:MODEF 0 "register_operand" "=f")
4695         (float_truncate:MODEF
4696           (match_operand:XF 1 "register_operand" "f")))]
4697   "TARGET_80387 && flag_unsafe_math_optimizations"
4698   "* return output_387_reg_move (insn, operands);"
4699   [(set_attr "type" "fmov")
4700    (set_attr "mode" "<MODE>")])
4701
4702 (define_insn "*truncxf<mode>2_i387"
4703   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4704         (float_truncate:MODEF
4705           (match_operand:XF 1 "register_operand" "f")))]
4706   "TARGET_80387"
4707   "* return output_387_reg_move (insn, operands);"
4708   [(set_attr "type" "fmov")
4709    (set_attr "mode" "<MODE>")])
4710
4711 (define_split
4712   [(set (match_operand:MODEF 0 "register_operand" "")
4713         (float_truncate:MODEF
4714           (match_operand:XF 1 "register_operand" "")))
4715    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4716   "TARGET_80387 && reload_completed"
4717   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4718    (set (match_dup 0) (match_dup 2))]
4719   "")
4720
4721 (define_split
4722   [(set (match_operand:MODEF 0 "memory_operand" "")
4723         (float_truncate:MODEF
4724           (match_operand:XF 1 "register_operand" "")))
4725    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4726   "TARGET_80387"
4727   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4728   "")
4729 \f
4730 ;; Signed conversion to DImode.
4731
4732 (define_expand "fix_truncxfdi2"
4733   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4734                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4735               (clobber (reg:CC FLAGS_REG))])]
4736   "TARGET_80387"
4737 {
4738   if (TARGET_FISTTP)
4739    {
4740      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4741      DONE;
4742    }
4743 })
4744
4745 (define_expand "fix_trunc<mode>di2"
4746   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4748               (clobber (reg:CC FLAGS_REG))])]
4749   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4750 {
4751   if (TARGET_FISTTP
4752       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4753    {
4754      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4755      DONE;
4756    }
4757   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4758    {
4759      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4760      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4761      if (out != operands[0])
4762         emit_move_insn (operands[0], out);
4763      DONE;
4764    }
4765 })
4766
4767 ;; Signed conversion to SImode.
4768
4769 (define_expand "fix_truncxfsi2"
4770   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4771                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4772               (clobber (reg:CC FLAGS_REG))])]
4773   "TARGET_80387"
4774 {
4775   if (TARGET_FISTTP)
4776    {
4777      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4778      DONE;
4779    }
4780 })
4781
4782 (define_expand "fix_trunc<mode>si2"
4783   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4784                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4785               (clobber (reg:CC FLAGS_REG))])]
4786   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4787 {
4788   if (TARGET_FISTTP
4789       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4790    {
4791      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4792      DONE;
4793    }
4794   if (SSE_FLOAT_MODE_P (<MODE>mode))
4795    {
4796      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4797      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4798      if (out != operands[0])
4799         emit_move_insn (operands[0], out);
4800      DONE;
4801    }
4802 })
4803
4804 ;; Signed conversion to HImode.
4805
4806 (define_expand "fix_trunc<mode>hi2"
4807   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4808                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4809               (clobber (reg:CC FLAGS_REG))])]
4810   "TARGET_80387
4811    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4812 {
4813   if (TARGET_FISTTP)
4814    {
4815      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4816      DONE;
4817    }
4818 })
4819
4820 ;; Unsigned conversion to SImode.
4821
4822 (define_expand "fixuns_trunc<mode>si2"
4823   [(parallel
4824     [(set (match_operand:SI 0 "register_operand" "")
4825           (unsigned_fix:SI
4826             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4827      (use (match_dup 2))
4828      (clobber (match_scratch:<ssevecmode> 3 ""))
4829      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4830   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4831 {
4832   enum machine_mode mode = <MODE>mode;
4833   enum machine_mode vecmode = <ssevecmode>mode;
4834   REAL_VALUE_TYPE TWO31r;
4835   rtx two31;
4836
4837   if (optimize_insn_for_size_p ())
4838     FAIL;
4839
4840   real_ldexp (&TWO31r, &dconst1, 31);
4841   two31 = const_double_from_real_value (TWO31r, mode);
4842   two31 = ix86_build_const_vector (mode, true, two31);
4843   operands[2] = force_reg (vecmode, two31);
4844 })
4845
4846 (define_insn_and_split "*fixuns_trunc<mode>_1"
4847   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4848         (unsigned_fix:SI
4849           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4850    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4851    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4852    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4853   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4854    && optimize_function_for_speed_p (cfun)"
4855   "#"
4856   "&& reload_completed"
4857   [(const_int 0)]
4858 {
4859   ix86_split_convert_uns_si_sse (operands);
4860   DONE;
4861 })
4862
4863 ;; Unsigned conversion to HImode.
4864 ;; Without these patterns, we'll try the unsigned SI conversion which
4865 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4866
4867 (define_expand "fixuns_trunc<mode>hi2"
4868   [(set (match_dup 2)
4869         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4870    (set (match_operand:HI 0 "nonimmediate_operand" "")
4871         (subreg:HI (match_dup 2) 0))]
4872   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4873   "operands[2] = gen_reg_rtx (SImode);")
4874
4875 ;; When SSE is available, it is always faster to use it!
4876 (define_insn "fix_trunc<mode>di_sse"
4877   [(set (match_operand:DI 0 "register_operand" "=r,r")
4878         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4879   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4880    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4881   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4882   [(set_attr "type" "sseicvt")
4883    (set_attr "prefix" "maybe_vex")
4884    (set_attr "prefix_rex" "1")
4885    (set_attr "mode" "<MODE>")
4886    (set_attr "athlon_decode" "double,vector")
4887    (set_attr "amdfam10_decode" "double,double")])
4888
4889 (define_insn "fix_trunc<mode>si_sse"
4890   [(set (match_operand:SI 0 "register_operand" "=r,r")
4891         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4892   "SSE_FLOAT_MODE_P (<MODE>mode)
4893    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4894   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4895   [(set_attr "type" "sseicvt")
4896    (set_attr "prefix" "maybe_vex")
4897    (set_attr "mode" "<MODE>")
4898    (set_attr "athlon_decode" "double,vector")
4899    (set_attr "amdfam10_decode" "double,double")])
4900
4901 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4902 (define_peephole2
4903   [(set (match_operand:MODEF 0 "register_operand" "")
4904         (match_operand:MODEF 1 "memory_operand" ""))
4905    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4906         (fix:SSEMODEI24 (match_dup 0)))]
4907   "TARGET_SHORTEN_X87_SSE
4908    && peep2_reg_dead_p (2, operands[0])"
4909   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4910   "")
4911
4912 ;; Avoid vector decoded forms of the instruction.
4913 (define_peephole2
4914   [(match_scratch:DF 2 "Y2")
4915    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4916         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4917   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4918   [(set (match_dup 2) (match_dup 1))
4919    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4920   "")
4921
4922 (define_peephole2
4923   [(match_scratch:SF 2 "x")
4924    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4925         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4926   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4927   [(set (match_dup 2) (match_dup 1))
4928    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4929   "")
4930
4931 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4932   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4933         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935    && TARGET_FISTTP
4936    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4937          && (TARGET_64BIT || <MODE>mode != DImode))
4938         && TARGET_SSE_MATH)
4939    && can_create_pseudo_p ()"
4940   "#"
4941   "&& 1"
4942   [(const_int 0)]
4943 {
4944   if (memory_operand (operands[0], VOIDmode))
4945     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4946   else
4947     {
4948       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4949       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4950                                                             operands[1],
4951                                                             operands[2]));
4952     }
4953   DONE;
4954 }
4955   [(set_attr "type" "fisttp")
4956    (set_attr "mode" "<MODE>")])
4957
4958 (define_insn "fix_trunc<mode>_i387_fisttp"
4959   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4960         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4961    (clobber (match_scratch:XF 2 "=&1f"))]
4962   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4963    && TARGET_FISTTP
4964    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4965          && (TARGET_64BIT || <MODE>mode != DImode))
4966         && TARGET_SSE_MATH)"
4967   "* return output_fix_trunc (insn, operands, 1);"
4968   [(set_attr "type" "fisttp")
4969    (set_attr "mode" "<MODE>")])
4970
4971 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4972   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4973         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4974    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4975    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977    && TARGET_FISTTP
4978    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4979         && (TARGET_64BIT || <MODE>mode != DImode))
4980         && TARGET_SSE_MATH)"
4981   "#"
4982   [(set_attr "type" "fisttp")
4983    (set_attr "mode" "<MODE>")])
4984
4985 (define_split
4986   [(set (match_operand:X87MODEI 0 "register_operand" "")
4987         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4988    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4989    (clobber (match_scratch 3 ""))]
4990   "reload_completed"
4991   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4992               (clobber (match_dup 3))])
4993    (set (match_dup 0) (match_dup 2))]
4994   "")
4995
4996 (define_split
4997   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4998         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4999    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5000    (clobber (match_scratch 3 ""))]
5001   "reload_completed"
5002   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5003               (clobber (match_dup 3))])]
5004   "")
5005
5006 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5007 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5008 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5009 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5010 ;; function in i386.c.
5011 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5012   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5013         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5014    (clobber (reg:CC FLAGS_REG))]
5015   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5016    && !TARGET_FISTTP
5017    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5018          && (TARGET_64BIT || <MODE>mode != DImode))
5019    && can_create_pseudo_p ()"
5020   "#"
5021   "&& 1"
5022   [(const_int 0)]
5023 {
5024   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5025
5026   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5027   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5028   if (memory_operand (operands[0], VOIDmode))
5029     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5030                                          operands[2], operands[3]));
5031   else
5032     {
5033       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5034       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5035                                                      operands[2], operands[3],
5036                                                      operands[4]));
5037     }
5038   DONE;
5039 }
5040   [(set_attr "type" "fistp")
5041    (set_attr "i387_cw" "trunc")
5042    (set_attr "mode" "<MODE>")])
5043
5044 (define_insn "fix_truncdi_i387"
5045   [(set (match_operand:DI 0 "memory_operand" "=m")
5046         (fix:DI (match_operand 1 "register_operand" "f")))
5047    (use (match_operand:HI 2 "memory_operand" "m"))
5048    (use (match_operand:HI 3 "memory_operand" "m"))
5049    (clobber (match_scratch:XF 4 "=&1f"))]
5050   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5051    && !TARGET_FISTTP
5052    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5053   "* return output_fix_trunc (insn, operands, 0);"
5054   [(set_attr "type" "fistp")
5055    (set_attr "i387_cw" "trunc")
5056    (set_attr "mode" "DI")])
5057
5058 (define_insn "fix_truncdi_i387_with_temp"
5059   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5060         (fix:DI (match_operand 1 "register_operand" "f,f")))
5061    (use (match_operand:HI 2 "memory_operand" "m,m"))
5062    (use (match_operand:HI 3 "memory_operand" "m,m"))
5063    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5064    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5065   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5066    && !TARGET_FISTTP
5067    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5068   "#"
5069   [(set_attr "type" "fistp")
5070    (set_attr "i387_cw" "trunc")
5071    (set_attr "mode" "DI")])
5072
5073 (define_split
5074   [(set (match_operand:DI 0 "register_operand" "")
5075         (fix:DI (match_operand 1 "register_operand" "")))
5076    (use (match_operand:HI 2 "memory_operand" ""))
5077    (use (match_operand:HI 3 "memory_operand" ""))
5078    (clobber (match_operand:DI 4 "memory_operand" ""))
5079    (clobber (match_scratch 5 ""))]
5080   "reload_completed"
5081   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5082               (use (match_dup 2))
5083               (use (match_dup 3))
5084               (clobber (match_dup 5))])
5085    (set (match_dup 0) (match_dup 4))]
5086   "")
5087
5088 (define_split
5089   [(set (match_operand:DI 0 "memory_operand" "")
5090         (fix:DI (match_operand 1 "register_operand" "")))
5091    (use (match_operand:HI 2 "memory_operand" ""))
5092    (use (match_operand:HI 3 "memory_operand" ""))
5093    (clobber (match_operand:DI 4 "memory_operand" ""))
5094    (clobber (match_scratch 5 ""))]
5095   "reload_completed"
5096   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5097               (use (match_dup 2))
5098               (use (match_dup 3))
5099               (clobber (match_dup 5))])]
5100   "")
5101
5102 (define_insn "fix_trunc<mode>_i387"
5103   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5104         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5105    (use (match_operand:HI 2 "memory_operand" "m"))
5106    (use (match_operand:HI 3 "memory_operand" "m"))]
5107   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5108    && !TARGET_FISTTP
5109    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5110   "* return output_fix_trunc (insn, operands, 0);"
5111   [(set_attr "type" "fistp")
5112    (set_attr "i387_cw" "trunc")
5113    (set_attr "mode" "<MODE>")])
5114
5115 (define_insn "fix_trunc<mode>_i387_with_temp"
5116   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5117         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5118    (use (match_operand:HI 2 "memory_operand" "m,m"))
5119    (use (match_operand:HI 3 "memory_operand" "m,m"))
5120    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5121   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5122    && !TARGET_FISTTP
5123    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5124   "#"
5125   [(set_attr "type" "fistp")
5126    (set_attr "i387_cw" "trunc")
5127    (set_attr "mode" "<MODE>")])
5128
5129 (define_split
5130   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5131         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5132    (use (match_operand:HI 2 "memory_operand" ""))
5133    (use (match_operand:HI 3 "memory_operand" ""))
5134    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5135   "reload_completed"
5136   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5137               (use (match_dup 2))
5138               (use (match_dup 3))])
5139    (set (match_dup 0) (match_dup 4))]
5140   "")
5141
5142 (define_split
5143   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5144         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5145    (use (match_operand:HI 2 "memory_operand" ""))
5146    (use (match_operand:HI 3 "memory_operand" ""))
5147    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5148   "reload_completed"
5149   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5150               (use (match_dup 2))
5151               (use (match_dup 3))])]
5152   "")
5153
5154 (define_insn "x86_fnstcw_1"
5155   [(set (match_operand:HI 0 "memory_operand" "=m")
5156         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5157   "TARGET_80387"
5158   "fnstcw\t%0"
5159   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5160    (set_attr "mode" "HI")
5161    (set_attr "unit" "i387")])
5162
5163 (define_insn "x86_fldcw_1"
5164   [(set (reg:HI FPCR_REG)
5165         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5166   "TARGET_80387"
5167   "fldcw\t%0"
5168   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5169    (set_attr "mode" "HI")
5170    (set_attr "unit" "i387")
5171    (set_attr "athlon_decode" "vector")
5172    (set_attr "amdfam10_decode" "vector")])
5173 \f
5174 ;; Conversion between fixed point and floating point.
5175
5176 ;; Even though we only accept memory inputs, the backend _really_
5177 ;; wants to be able to do this between registers.
5178
5179 (define_expand "floathi<mode>2"
5180   [(set (match_operand:X87MODEF 0 "register_operand" "")
5181         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5182   "TARGET_80387
5183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5184        || TARGET_MIX_SSE_I387)"
5185   "")
5186
5187 ;; Pre-reload splitter to add memory clobber to the pattern.
5188 (define_insn_and_split "*floathi<mode>2_1"
5189   [(set (match_operand:X87MODEF 0 "register_operand" "")
5190         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5191   "TARGET_80387
5192    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5193        || TARGET_MIX_SSE_I387)
5194    && can_create_pseudo_p ()"
5195   "#"
5196   "&& 1"
5197   [(parallel [(set (match_dup 0)
5198               (float:X87MODEF (match_dup 1)))
5199    (clobber (match_dup 2))])]
5200   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5201
5202 (define_insn "*floathi<mode>2_i387_with_temp"
5203   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5204         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5205   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5206   "TARGET_80387
5207    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5208        || TARGET_MIX_SSE_I387)"
5209   "#"
5210   [(set_attr "type" "fmov,multi")
5211    (set_attr "mode" "<MODE>")
5212    (set_attr "unit" "*,i387")
5213    (set_attr "fp_int_src" "true")])
5214
5215 (define_insn "*floathi<mode>2_i387"
5216   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5217         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5218   "TARGET_80387
5219    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5220        || TARGET_MIX_SSE_I387)"
5221   "fild%Z1\t%1"
5222   [(set_attr "type" "fmov")
5223    (set_attr "mode" "<MODE>")
5224    (set_attr "fp_int_src" "true")])
5225
5226 (define_split
5227   [(set (match_operand:X87MODEF 0 "register_operand" "")
5228         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5229    (clobber (match_operand:HI 2 "memory_operand" ""))]
5230   "TARGET_80387
5231    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5232        || TARGET_MIX_SSE_I387)
5233    && reload_completed"
5234   [(set (match_dup 2) (match_dup 1))
5235    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5236   "")
5237
5238 (define_split
5239   [(set (match_operand:X87MODEF 0 "register_operand" "")
5240         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5241    (clobber (match_operand:HI 2 "memory_operand" ""))]
5242    "TARGET_80387
5243     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5244         || TARGET_MIX_SSE_I387)
5245     && reload_completed"
5246   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5247   "")
5248
5249 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5250   [(set (match_operand:X87MODEF 0 "register_operand" "")
5251         (float:X87MODEF
5252           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5253   "TARGET_80387
5254    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5255        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5256   "
5257 {
5258   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5260       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5261     {
5262       rtx reg = gen_reg_rtx (XFmode);
5263       rtx insn;
5264
5265       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5266
5267       if (<X87MODEF:MODE>mode == SFmode)
5268         insn = gen_truncxfsf2 (operands[0], reg);
5269       else if (<X87MODEF:MODE>mode == DFmode)
5270         insn = gen_truncxfdf2 (operands[0], reg);
5271       else
5272         gcc_unreachable ();
5273
5274       emit_insn (insn);
5275       DONE;
5276     }
5277 }")
5278
5279 ;; Pre-reload splitter to add memory clobber to the pattern.
5280 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5281   [(set (match_operand:X87MODEF 0 "register_operand" "")
5282         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5283   "((TARGET_80387
5284      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5285      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5286            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5287          || TARGET_MIX_SSE_I387))
5288     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5289         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5290         && ((<SSEMODEI24:MODE>mode == SImode
5291              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5292              && optimize_function_for_speed_p (cfun)
5293              && flag_trapping_math)
5294             || !(TARGET_INTER_UNIT_CONVERSIONS
5295                  || optimize_function_for_size_p (cfun)))))
5296    && can_create_pseudo_p ()"
5297   "#"
5298   "&& 1"
5299   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5300               (clobber (match_dup 2))])]
5301 {
5302   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5303
5304   /* Avoid store forwarding (partial memory) stall penalty
5305      by passing DImode value through XMM registers.  */
5306   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5307       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308       && optimize_function_for_speed_p (cfun))
5309     {
5310       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5311                                                             operands[1],
5312                                                             operands[2]));
5313       DONE;
5314     }
5315 })
5316
5317 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5318   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5319         (float:MODEF
5320           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5321    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5322   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5323    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5324   "#"
5325   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5326    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5327    (set_attr "unit" "*,i387,*,*,*")
5328    (set_attr "athlon_decode" "*,*,double,direct,double")
5329    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5330    (set_attr "fp_int_src" "true")])
5331
5332 (define_insn "*floatsi<mode>2_vector_mixed"
5333   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5334         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5335   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5336    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5337   "@
5338    fild%Z1\t%1
5339    #"
5340   [(set_attr "type" "fmov,sseicvt")
5341    (set_attr "mode" "<MODE>,<ssevecmode>")
5342    (set_attr "unit" "i387,*")
5343    (set_attr "athlon_decode" "*,direct")
5344    (set_attr "amdfam10_decode" "*,double")
5345    (set_attr "fp_int_src" "true")])
5346
5347 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5348   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5349         (float:MODEF
5350           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5351   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5352   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5353    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5354   "#"
5355   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5356    (set_attr "mode" "<MODEF:MODE>")
5357    (set_attr "unit" "*,i387,*,*")
5358    (set_attr "athlon_decode" "*,*,double,direct")
5359    (set_attr "amdfam10_decode" "*,*,vector,double")
5360    (set_attr "fp_int_src" "true")])
5361
5362 (define_split
5363   [(set (match_operand:MODEF 0 "register_operand" "")
5364         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5365    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5366   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5368    && TARGET_INTER_UNIT_CONVERSIONS
5369    && reload_completed
5370    && (SSE_REG_P (operands[0])
5371        || (GET_CODE (operands[0]) == SUBREG
5372            && SSE_REG_P (operands[0])))"
5373   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5374   "")
5375
5376 (define_split
5377   [(set (match_operand:MODEF 0 "register_operand" "")
5378         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5379    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5381    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5382    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5383    && reload_completed
5384    && (SSE_REG_P (operands[0])
5385        || (GET_CODE (operands[0]) == SUBREG
5386            && SSE_REG_P (operands[0])))"
5387   [(set (match_dup 2) (match_dup 1))
5388    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5389   "")
5390
5391 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5392   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5393         (float:MODEF
5394           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5395   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5396    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5397    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5398   "@
5399    fild%Z1\t%1
5400    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5401    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5402   [(set_attr "type" "fmov,sseicvt,sseicvt")
5403    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5404    (set_attr "mode" "<MODEF:MODE>")
5405    (set (attr "prefix_rex")
5406      (if_then_else
5407        (and (eq_attr "prefix" "maybe_vex")
5408             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5409        (const_string "1")
5410        (const_string "*")))
5411    (set_attr "unit" "i387,*,*")
5412    (set_attr "athlon_decode" "*,double,direct")
5413    (set_attr "amdfam10_decode" "*,vector,double")
5414    (set_attr "fp_int_src" "true")])
5415
5416 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5417   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5418         (float:MODEF
5419           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5420   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5421    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5422    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5423   "@
5424    fild%Z1\t%1
5425    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5426   [(set_attr "type" "fmov,sseicvt")
5427    (set_attr "prefix" "orig,maybe_vex")
5428    (set_attr "mode" "<MODEF:MODE>")
5429    (set (attr "prefix_rex")
5430      (if_then_else
5431        (and (eq_attr "prefix" "maybe_vex")
5432             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5433        (const_string "1")
5434        (const_string "*")))
5435    (set_attr "athlon_decode" "*,direct")
5436    (set_attr "amdfam10_decode" "*,double")
5437    (set_attr "fp_int_src" "true")])
5438
5439 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5440   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5441         (float:MODEF
5442           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5443    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5444   "TARGET_SSE2 && TARGET_SSE_MATH
5445    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5446   "#"
5447   [(set_attr "type" "sseicvt")
5448    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5449    (set_attr "athlon_decode" "double,direct,double")
5450    (set_attr "amdfam10_decode" "vector,double,double")
5451    (set_attr "fp_int_src" "true")])
5452
5453 (define_insn "*floatsi<mode>2_vector_sse"
5454   [(set (match_operand:MODEF 0 "register_operand" "=x")
5455         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5456   "TARGET_SSE2 && TARGET_SSE_MATH
5457    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5458   "#"
5459   [(set_attr "type" "sseicvt")
5460    (set_attr "mode" "<MODE>")
5461    (set_attr "athlon_decode" "direct")
5462    (set_attr "amdfam10_decode" "double")
5463    (set_attr "fp_int_src" "true")])
5464
5465 (define_split
5466   [(set (match_operand:MODEF 0 "register_operand" "")
5467         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5468    (clobber (match_operand:SI 2 "memory_operand" ""))]
5469   "TARGET_SSE2 && TARGET_SSE_MATH
5470    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5471    && reload_completed
5472    && (SSE_REG_P (operands[0])
5473        || (GET_CODE (operands[0]) == SUBREG
5474            && SSE_REG_P (operands[0])))"
5475   [(const_int 0)]
5476 {
5477   rtx op1 = operands[1];
5478
5479   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5480                                      <MODE>mode, 0);
5481   if (GET_CODE (op1) == SUBREG)
5482     op1 = SUBREG_REG (op1);
5483
5484   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5485     {
5486       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5487       emit_insn (gen_sse2_loadld (operands[4],
5488                                   CONST0_RTX (V4SImode), operands[1]));
5489     }
5490   /* We can ignore possible trapping value in the
5491      high part of SSE register for non-trapping math. */
5492   else if (SSE_REG_P (op1) && !flag_trapping_math)
5493     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5494   else
5495     {
5496       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5497       emit_move_insn (operands[2], operands[1]);
5498       emit_insn (gen_sse2_loadld (operands[4],
5499                                   CONST0_RTX (V4SImode), operands[2]));
5500     }
5501   emit_insn
5502     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5503   DONE;
5504 })
5505
5506 (define_split
5507   [(set (match_operand:MODEF 0 "register_operand" "")
5508         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5509    (clobber (match_operand:SI 2 "memory_operand" ""))]
5510   "TARGET_SSE2 && TARGET_SSE_MATH
5511    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5512    && reload_completed
5513    && (SSE_REG_P (operands[0])
5514        || (GET_CODE (operands[0]) == SUBREG
5515            && SSE_REG_P (operands[0])))"
5516   [(const_int 0)]
5517 {
5518   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5519                                      <MODE>mode, 0);
5520   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5521
5522   emit_insn (gen_sse2_loadld (operands[4],
5523                               CONST0_RTX (V4SImode), operands[1]));
5524   emit_insn
5525     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5526   DONE;
5527 })
5528
5529 (define_split
5530   [(set (match_operand:MODEF 0 "register_operand" "")
5531         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5532   "TARGET_SSE2 && TARGET_SSE_MATH
5533    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5534    && reload_completed
5535    && (SSE_REG_P (operands[0])
5536        || (GET_CODE (operands[0]) == SUBREG
5537            && SSE_REG_P (operands[0])))"
5538   [(const_int 0)]
5539 {
5540   rtx op1 = operands[1];
5541
5542   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5543                                      <MODE>mode, 0);
5544   if (GET_CODE (op1) == SUBREG)
5545     op1 = SUBREG_REG (op1);
5546
5547   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5548     {
5549       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5550       emit_insn (gen_sse2_loadld (operands[4],
5551                                   CONST0_RTX (V4SImode), operands[1]));
5552     }
5553   /* We can ignore possible trapping value in the
5554      high part of SSE register for non-trapping math. */
5555   else if (SSE_REG_P (op1) && !flag_trapping_math)
5556     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5557   else
5558     gcc_unreachable ();
5559   emit_insn
5560     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5561   DONE;
5562 })
5563
5564 (define_split
5565   [(set (match_operand:MODEF 0 "register_operand" "")
5566         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5567   "TARGET_SSE2 && TARGET_SSE_MATH
5568    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5569    && reload_completed
5570    && (SSE_REG_P (operands[0])
5571        || (GET_CODE (operands[0]) == SUBREG
5572            && SSE_REG_P (operands[0])))"
5573   [(const_int 0)]
5574 {
5575   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5576                                      <MODE>mode, 0);
5577   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5578
5579   emit_insn (gen_sse2_loadld (operands[4],
5580                               CONST0_RTX (V4SImode), operands[1]));
5581   emit_insn
5582     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5583   DONE;
5584 })
5585
5586 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5587   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5588         (float:MODEF
5589           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5590   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5591   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5592    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5593   "#"
5594   [(set_attr "type" "sseicvt")
5595    (set_attr "mode" "<MODEF:MODE>")
5596    (set_attr "athlon_decode" "double,direct")
5597    (set_attr "amdfam10_decode" "vector,double")
5598    (set_attr "fp_int_src" "true")])
5599
5600 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5601   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5602         (float:MODEF
5603           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5604   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5605    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5606    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5607   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5608   [(set_attr "type" "sseicvt")
5609    (set_attr "prefix" "maybe_vex")
5610    (set_attr "mode" "<MODEF:MODE>")
5611    (set (attr "prefix_rex")
5612      (if_then_else
5613        (and (eq_attr "prefix" "maybe_vex")
5614             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5615        (const_string "1")
5616        (const_string "*")))
5617    (set_attr "athlon_decode" "double,direct")
5618    (set_attr "amdfam10_decode" "vector,double")
5619    (set_attr "fp_int_src" "true")])
5620
5621 (define_split
5622   [(set (match_operand:MODEF 0 "register_operand" "")
5623         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5624    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5625   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5626    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5627    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5628    && reload_completed
5629    && (SSE_REG_P (operands[0])
5630        || (GET_CODE (operands[0]) == SUBREG
5631            && SSE_REG_P (operands[0])))"
5632   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5633   "")
5634
5635 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5636   [(set (match_operand:MODEF 0 "register_operand" "=x")
5637         (float:MODEF
5638           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5639   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5640    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5641    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5642   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5643   [(set_attr "type" "sseicvt")
5644    (set_attr "prefix" "maybe_vex")
5645    (set_attr "mode" "<MODEF:MODE>")
5646    (set (attr "prefix_rex")
5647      (if_then_else
5648        (and (eq_attr "prefix" "maybe_vex")
5649             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5650        (const_string "1")
5651        (const_string "*")))
5652    (set_attr "athlon_decode" "direct")
5653    (set_attr "amdfam10_decode" "double")
5654    (set_attr "fp_int_src" "true")])
5655
5656 (define_split
5657   [(set (match_operand:MODEF 0 "register_operand" "")
5658         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5659    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5660   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5661    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5662    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5663    && reload_completed
5664    && (SSE_REG_P (operands[0])
5665        || (GET_CODE (operands[0]) == SUBREG
5666            && SSE_REG_P (operands[0])))"
5667   [(set (match_dup 2) (match_dup 1))
5668    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5669   "")
5670
5671 (define_split
5672   [(set (match_operand:MODEF 0 "register_operand" "")
5673         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5674    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5675   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5676    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5677    && reload_completed
5678    && (SSE_REG_P (operands[0])
5679        || (GET_CODE (operands[0]) == SUBREG
5680            && SSE_REG_P (operands[0])))"
5681   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5682   "")
5683
5684 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5685   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5686         (float:X87MODEF
5687           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5688   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5689   "TARGET_80387
5690    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5691   "@
5692    fild%Z1\t%1
5693    #"
5694   [(set_attr "type" "fmov,multi")
5695    (set_attr "mode" "<X87MODEF:MODE>")
5696    (set_attr "unit" "*,i387")
5697    (set_attr "fp_int_src" "true")])
5698
5699 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5700   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5701         (float:X87MODEF
5702           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5703   "TARGET_80387
5704    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5705   "fild%Z1\t%1"
5706   [(set_attr "type" "fmov")
5707    (set_attr "mode" "<X87MODEF:MODE>")
5708    (set_attr "fp_int_src" "true")])
5709
5710 (define_split
5711   [(set (match_operand:X87MODEF 0 "register_operand" "")
5712         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5713    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5714   "TARGET_80387
5715    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5716    && reload_completed
5717    && FP_REG_P (operands[0])"
5718   [(set (match_dup 2) (match_dup 1))
5719    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5720   "")
5721
5722 (define_split
5723   [(set (match_operand:X87MODEF 0 "register_operand" "")
5724         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5725    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5726   "TARGET_80387
5727    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5728    && reload_completed
5729    && FP_REG_P (operands[0])"
5730   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5731   "")
5732
5733 ;; Avoid store forwarding (partial memory) stall penalty
5734 ;; by passing DImode value through XMM registers.  */
5735
5736 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5737   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5738         (float:X87MODEF
5739           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5740    (clobber (match_scratch:V4SI 3 "=X,x"))
5741    (clobber (match_scratch:V4SI 4 "=X,x"))
5742    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5743   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5744    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5745    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5746   "#"
5747   [(set_attr "type" "multi")
5748    (set_attr "mode" "<X87MODEF:MODE>")
5749    (set_attr "unit" "i387")
5750    (set_attr "fp_int_src" "true")])
5751
5752 (define_split
5753   [(set (match_operand:X87MODEF 0 "register_operand" "")
5754         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5755    (clobber (match_scratch:V4SI 3 ""))
5756    (clobber (match_scratch:V4SI 4 ""))
5757    (clobber (match_operand:DI 2 "memory_operand" ""))]
5758   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5759    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5760    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5761    && reload_completed
5762    && FP_REG_P (operands[0])"
5763   [(set (match_dup 2) (match_dup 3))
5764    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5765 {
5766   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5767      Assemble the 64-bit DImode value in an xmm register.  */
5768   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5769                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5770   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5771                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5772   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5773
5774   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5775 })
5776
5777 (define_split
5778   [(set (match_operand:X87MODEF 0 "register_operand" "")
5779         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5780    (clobber (match_scratch:V4SI 3 ""))
5781    (clobber (match_scratch:V4SI 4 ""))
5782    (clobber (match_operand:DI 2 "memory_operand" ""))]
5783   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5784    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5785    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5786    && reload_completed
5787    && FP_REG_P (operands[0])"
5788   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5789   "")
5790
5791 ;; Avoid store forwarding (partial memory) stall penalty by extending
5792 ;; SImode value to DImode through XMM register instead of pushing two
5793 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5794 ;; targets benefit from this optimization. Also note that fild
5795 ;; loads from memory only.
5796
5797 (define_insn "*floatunssi<mode>2_1"
5798   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5799         (unsigned_float:X87MODEF
5800           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5801    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5802    (clobber (match_scratch:SI 3 "=X,x"))]
5803   "!TARGET_64BIT
5804    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5805    && TARGET_SSE"
5806   "#"
5807   [(set_attr "type" "multi")
5808    (set_attr "mode" "<MODE>")])
5809
5810 (define_split
5811   [(set (match_operand:X87MODEF 0 "register_operand" "")
5812         (unsigned_float:X87MODEF
5813           (match_operand:SI 1 "register_operand" "")))
5814    (clobber (match_operand:DI 2 "memory_operand" ""))
5815    (clobber (match_scratch:SI 3 ""))]
5816   "!TARGET_64BIT
5817    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5818    && TARGET_SSE
5819    && reload_completed"
5820   [(set (match_dup 2) (match_dup 1))
5821    (set (match_dup 0)
5822         (float:X87MODEF (match_dup 2)))]
5823   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5824
5825 (define_split
5826   [(set (match_operand:X87MODEF 0 "register_operand" "")
5827         (unsigned_float:X87MODEF
5828           (match_operand:SI 1 "memory_operand" "")))
5829    (clobber (match_operand:DI 2 "memory_operand" ""))
5830    (clobber (match_scratch:SI 3 ""))]
5831   "!TARGET_64BIT
5832    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5833    && TARGET_SSE
5834    && reload_completed"
5835   [(set (match_dup 2) (match_dup 3))
5836    (set (match_dup 0)
5837         (float:X87MODEF (match_dup 2)))]
5838 {
5839   emit_move_insn (operands[3], operands[1]);
5840   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5841 })
5842
5843 (define_expand "floatunssi<mode>2"
5844   [(parallel
5845      [(set (match_operand:X87MODEF 0 "register_operand" "")
5846            (unsigned_float:X87MODEF
5847              (match_operand:SI 1 "nonimmediate_operand" "")))
5848       (clobber (match_dup 2))
5849       (clobber (match_scratch:SI 3 ""))])]
5850   "!TARGET_64BIT
5851    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5852         && TARGET_SSE)
5853        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5854 {
5855   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5856     {
5857       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5858       DONE;
5859     }
5860   else
5861     {
5862       enum ix86_stack_slot slot = (virtuals_instantiated
5863                                    ? SLOT_TEMP
5864                                    : SLOT_VIRTUAL);
5865       operands[2] = assign_386_stack_local (DImode, slot);
5866     }
5867 })
5868
5869 (define_expand "floatunsdisf2"
5870   [(use (match_operand:SF 0 "register_operand" ""))
5871    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5872   "TARGET_64BIT && TARGET_SSE_MATH"
5873   "x86_emit_floatuns (operands); DONE;")
5874
5875 (define_expand "floatunsdidf2"
5876   [(use (match_operand:DF 0 "register_operand" ""))
5877    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5878   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5879    && TARGET_SSE2 && TARGET_SSE_MATH"
5880 {
5881   if (TARGET_64BIT)
5882     x86_emit_floatuns (operands);
5883   else
5884     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5885   DONE;
5886 })
5887 \f
5888 ;; Add instructions
5889
5890 (define_expand "add<mode>3"
5891   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5892         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5893                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5894   ""
5895   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5896
5897 (define_insn_and_split "*add<dwi>3_doubleword"
5898   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5899         (plus:<DWI>
5900           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5901           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5902    (clobber (reg:CC FLAGS_REG))]
5903   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5904   "#"
5905   "reload_completed"
5906   [(parallel [(set (reg:CC FLAGS_REG)
5907                    (unspec:CC [(match_dup 1) (match_dup 2)]
5908                               UNSPEC_ADD_CARRY))
5909               (set (match_dup 0)
5910                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5911    (parallel [(set (match_dup 3)
5912                    (plus:DWIH
5913                      (match_dup 4)
5914                      (plus:DWIH
5915                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5916                        (match_dup 5))))
5917               (clobber (reg:CC FLAGS_REG))])]
5918   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5919
5920 (define_insn "*add<mode>3_cc"
5921   [(set (reg:CC FLAGS_REG)
5922         (unspec:CC
5923           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5924            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5925           UNSPEC_ADD_CARRY))
5926    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5927         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5928   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5929   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5930   [(set_attr "type" "alu")
5931    (set_attr "mode" "<MODE>")])
5932
5933 (define_insn "addqi3_cc"
5934   [(set (reg:CC FLAGS_REG)
5935         (unspec:CC
5936           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5937            (match_operand:QI 2 "general_operand" "qn,qm")]
5938           UNSPEC_ADD_CARRY))
5939    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5940         (plus:QI (match_dup 1) (match_dup 2)))]
5941   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5942   "add{b}\t{%2, %0|%0, %2}"
5943   [(set_attr "type" "alu")
5944    (set_attr "mode" "QI")])
5945
5946 (define_insn "*lea_1"
5947   [(set (match_operand:DWIH 0 "register_operand" "=r")
5948         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5949   ""
5950   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5951   [(set_attr "type" "lea")
5952    (set_attr "mode" "<MODE>")])
5953
5954 (define_insn "*lea_2"
5955   [(set (match_operand:SI 0 "register_operand" "=r")
5956         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5957   "TARGET_64BIT"
5958   "lea{l}\t{%a1, %0|%0, %a1}"
5959   [(set_attr "type" "lea")
5960    (set_attr "mode" "SI")])
5961
5962 (define_insn "*lea_2_zext"
5963   [(set (match_operand:DI 0 "register_operand" "=r")
5964         (zero_extend:DI
5965           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5966   "TARGET_64BIT"
5967   "lea{l}\t{%a1, %k0|%k0, %a1}"
5968   [(set_attr "type" "lea")
5969    (set_attr "mode" "SI")])
5970
5971 (define_insn "*add<mode>_1"
5972   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5973         (plus:SWI48
5974           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5975           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5976    (clobber (reg:CC FLAGS_REG))]
5977   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5978 {
5979   switch (get_attr_type (insn))
5980     {
5981     case TYPE_LEA:
5982       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5983       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5984
5985     case TYPE_INCDEC:
5986       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5987       if (operands[2] == const1_rtx)
5988         return "inc{<imodesuffix>}\t%0";
5989       else
5990         {
5991           gcc_assert (operands[2] == constm1_rtx);
5992           return "dec{<imodesuffix>}\t%0";
5993         }
5994
5995     default:
5996       /* Use add as much as possible to replace lea for AGU optimization. */
5997       if (which_alternative == 2 && TARGET_OPT_AGU)
5998         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
5999         
6000       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001
6002       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6003          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6004       if (CONST_INT_P (operands[2])
6005           /* Avoid overflows.  */
6006           && (<MODE>mode != DImode
6007               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6008           && (INTVAL (operands[2]) == 128
6009               || (INTVAL (operands[2]) < 0
6010                   && INTVAL (operands[2]) != -128)))
6011         {
6012           operands[2] = GEN_INT (-INTVAL (operands[2]));
6013           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6014         }
6015       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6016     }
6017 }
6018   [(set (attr "type")
6019      (cond [(and (eq_attr "alternative" "2") 
6020                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6021               (const_string "lea")
6022             (eq_attr "alternative" "3")
6023               (const_string "lea")
6024             ; Current assemblers are broken and do not allow @GOTOFF in
6025             ; ought but a memory context.
6026             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6027               (const_string "lea")
6028             (match_operand:SWI48 2 "incdec_operand" "")
6029               (const_string "incdec")
6030            ]
6031            (const_string "alu")))
6032    (set (attr "length_immediate")
6033       (if_then_else
6034         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6035         (const_string "1")
6036         (const_string "*")))
6037    (set_attr "mode" "<MODE>")])
6038
6039 ;; It may seem that nonimmediate operand is proper one for operand 1.
6040 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6041 ;; we take care in ix86_binary_operator_ok to not allow two memory
6042 ;; operands so proper swapping will be done in reload.  This allow
6043 ;; patterns constructed from addsi_1 to match.
6044
6045 (define_insn "*addsi_1_zext"
6046   [(set (match_operand:DI 0 "register_operand" "=r,r")
6047         (zero_extend:DI
6048           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6049                    (match_operand:SI 2 "general_operand" "g,li"))))
6050    (clobber (reg:CC FLAGS_REG))]
6051   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6052 {
6053   switch (get_attr_type (insn))
6054     {
6055     case TYPE_LEA:
6056       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6057       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6058
6059     case TYPE_INCDEC:
6060       if (operands[2] == const1_rtx)
6061         return "inc{l}\t%k0";
6062       else
6063         {
6064           gcc_assert (operands[2] == constm1_rtx);
6065           return "dec{l}\t%k0";
6066         }
6067
6068     default:
6069       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6070          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6071       if (CONST_INT_P (operands[2])
6072           && (INTVAL (operands[2]) == 128
6073               || (INTVAL (operands[2]) < 0
6074                   && INTVAL (operands[2]) != -128)))
6075         {
6076           operands[2] = GEN_INT (-INTVAL (operands[2]));
6077           return "sub{l}\t{%2, %k0|%k0, %2}";
6078         }
6079       return "add{l}\t{%2, %k0|%k0, %2}";
6080     }
6081 }
6082   [(set (attr "type")
6083      (cond [(eq_attr "alternative" "1")
6084               (const_string "lea")
6085             ; Current assemblers are broken and do not allow @GOTOFF in
6086             ; ought but a memory context.
6087             (match_operand:SI 2 "pic_symbolic_operand" "")
6088               (const_string "lea")
6089             (match_operand:SI 2 "incdec_operand" "")
6090               (const_string "incdec")
6091            ]
6092            (const_string "alu")))
6093    (set (attr "length_immediate")
6094       (if_then_else
6095         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6096         (const_string "1")
6097         (const_string "*")))
6098    (set_attr "mode" "SI")])
6099
6100 (define_insn "*addhi_1"
6101   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6102         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6103                  (match_operand:HI 2 "general_operand" "rn,rm")))
6104    (clobber (reg:CC FLAGS_REG))]
6105   "TARGET_PARTIAL_REG_STALL
6106    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6107 {
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_INCDEC:
6111       if (operands[2] == const1_rtx)
6112         return "inc{w}\t%0";
6113       else
6114         {
6115           gcc_assert (operands[2] == constm1_rtx);
6116           return "dec{w}\t%0";
6117         }
6118
6119     default:
6120       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6121          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6122       if (CONST_INT_P (operands[2])
6123           && (INTVAL (operands[2]) == 128
6124               || (INTVAL (operands[2]) < 0
6125                   && INTVAL (operands[2]) != -128)))
6126         {
6127           operands[2] = GEN_INT (-INTVAL (operands[2]));
6128           return "sub{w}\t{%2, %0|%0, %2}";
6129         }
6130       return "add{w}\t{%2, %0|%0, %2}";
6131     }
6132 }
6133   [(set (attr "type")
6134      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135         (const_string "incdec")
6136         (const_string "alu")))
6137    (set (attr "length_immediate")
6138       (if_then_else
6139         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6140         (const_string "1")
6141         (const_string "*")))
6142    (set_attr "mode" "HI")])
6143
6144 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6145 ;; type optimizations enabled by define-splits.  This is not important
6146 ;; for PII, and in fact harmful because of partial register stalls.
6147
6148 (define_insn "*addhi_1_lea"
6149   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6150         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6151                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6152    (clobber (reg:CC FLAGS_REG))]
6153   "!TARGET_PARTIAL_REG_STALL
6154    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6155 {
6156   switch (get_attr_type (insn))
6157     {
6158     case TYPE_LEA:
6159       return "#";
6160     case TYPE_INCDEC:
6161       if (operands[2] == const1_rtx)
6162         return "inc{w}\t%0";
6163       else
6164         {
6165           gcc_assert (operands[2] == constm1_rtx);
6166           return "dec{w}\t%0";
6167         }
6168
6169     default:
6170       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6171          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6172       if (CONST_INT_P (operands[2])
6173           && (INTVAL (operands[2]) == 128
6174               || (INTVAL (operands[2]) < 0
6175                   && INTVAL (operands[2]) != -128)))
6176         {
6177           operands[2] = GEN_INT (-INTVAL (operands[2]));
6178           return "sub{w}\t{%2, %0|%0, %2}";
6179         }
6180       return "add{w}\t{%2, %0|%0, %2}";
6181     }
6182 }
6183   [(set (attr "type")
6184      (if_then_else (eq_attr "alternative" "2")
6185         (const_string "lea")
6186         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6187            (const_string "incdec")
6188            (const_string "alu"))))
6189    (set (attr "length_immediate")
6190       (if_then_else
6191         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6192         (const_string "1")
6193         (const_string "*")))
6194    (set_attr "mode" "HI,HI,SI")])
6195
6196 (define_insn "*addqi_1"
6197   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6198         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6199                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6200    (clobber (reg:CC FLAGS_REG))]
6201   "TARGET_PARTIAL_REG_STALL
6202    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6203 {
6204   int widen = (which_alternative == 2);
6205   switch (get_attr_type (insn))
6206     {
6207     case TYPE_INCDEC:
6208       if (operands[2] == const1_rtx)
6209         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6210       else
6211         {
6212           gcc_assert (operands[2] == constm1_rtx);
6213           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6214         }
6215
6216     default:
6217       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6218          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6219       if (CONST_INT_P (operands[2])
6220           && (INTVAL (operands[2]) == 128
6221               || (INTVAL (operands[2]) < 0
6222                   && INTVAL (operands[2]) != -128)))
6223         {
6224           operands[2] = GEN_INT (-INTVAL (operands[2]));
6225           if (widen)
6226             return "sub{l}\t{%2, %k0|%k0, %2}";
6227           else
6228             return "sub{b}\t{%2, %0|%0, %2}";
6229         }
6230       if (widen)
6231         return "add{l}\t{%k2, %k0|%k0, %k2}";
6232       else
6233         return "add{b}\t{%2, %0|%0, %2}";
6234     }
6235 }
6236   [(set (attr "type")
6237      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6238         (const_string "incdec")
6239         (const_string "alu")))
6240    (set (attr "length_immediate")
6241       (if_then_else
6242         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6243         (const_string "1")
6244         (const_string "*")))
6245    (set_attr "mode" "QI,QI,SI")])
6246
6247 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6248 (define_insn "*addqi_1_lea"
6249   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6250         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6251                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6252    (clobber (reg:CC FLAGS_REG))]
6253   "!TARGET_PARTIAL_REG_STALL
6254    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6255 {
6256   int widen = (which_alternative == 2);
6257   switch (get_attr_type (insn))
6258     {
6259     case TYPE_LEA:
6260       return "#";
6261     case TYPE_INCDEC:
6262       if (operands[2] == const1_rtx)
6263         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6264       else
6265         {
6266           gcc_assert (operands[2] == constm1_rtx);
6267           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6268         }
6269
6270     default:
6271       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6272          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6273       if (CONST_INT_P (operands[2])
6274           && (INTVAL (operands[2]) == 128
6275               || (INTVAL (operands[2]) < 0
6276                   && INTVAL (operands[2]) != -128)))
6277         {
6278           operands[2] = GEN_INT (-INTVAL (operands[2]));
6279           if (widen)
6280             return "sub{l}\t{%2, %k0|%k0, %2}";
6281           else
6282             return "sub{b}\t{%2, %0|%0, %2}";
6283         }
6284       if (widen)
6285         return "add{l}\t{%k2, %k0|%k0, %k2}";
6286       else
6287         return "add{b}\t{%2, %0|%0, %2}";
6288     }
6289 }
6290   [(set (attr "type")
6291      (if_then_else (eq_attr "alternative" "3")
6292         (const_string "lea")
6293         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294            (const_string "incdec")
6295            (const_string "alu"))))
6296    (set (attr "length_immediate")
6297       (if_then_else
6298         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6299         (const_string "1")
6300         (const_string "*")))
6301    (set_attr "mode" "QI,QI,SI,SI")])
6302
6303 (define_insn "*addqi_1_slp"
6304   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6305         (plus:QI (match_dup 0)
6306                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6307    (clobber (reg:CC FLAGS_REG))]
6308   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6309    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6310 {
6311   switch (get_attr_type (insn))
6312     {
6313     case TYPE_INCDEC:
6314       if (operands[1] == const1_rtx)
6315         return "inc{b}\t%0";
6316       else
6317         {
6318           gcc_assert (operands[1] == constm1_rtx);
6319           return "dec{b}\t%0";
6320         }
6321
6322     default:
6323       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6324       if (CONST_INT_P (operands[1])
6325           && INTVAL (operands[1]) < 0)
6326         {
6327           operands[1] = GEN_INT (-INTVAL (operands[1]));
6328           return "sub{b}\t{%1, %0|%0, %1}";
6329         }
6330       return "add{b}\t{%1, %0|%0, %1}";
6331     }
6332 }
6333   [(set (attr "type")
6334      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6335         (const_string "incdec")
6336         (const_string "alu1")))
6337    (set (attr "memory")
6338      (if_then_else (match_operand 1 "memory_operand" "")
6339         (const_string "load")
6340         (const_string "none")))
6341    (set_attr "mode" "QI")])
6342
6343 (define_insn "*add<mode>_2"
6344   [(set (reg FLAGS_REG)
6345         (compare
6346           (plus:SWI48
6347             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6348             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6349           (const_int 0)))
6350    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6351         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6352   "ix86_match_ccmode (insn, CCGOCmode)
6353    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6354    /* Current assemblers are broken and do not allow @GOTOFF in
6355       ought but a memory context.  */
6356    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6357 {
6358   switch (get_attr_type (insn))
6359     {
6360     case TYPE_INCDEC:
6361       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6362       if (operands[2] == const1_rtx)
6363         return "inc{<imodesuffix>}\t%0";
6364       else
6365         {
6366           gcc_assert (operands[2] == constm1_rtx);
6367           return "dec{<imodesuffix>}\t%0";
6368         }
6369
6370     default:
6371       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6372       /* ???? In DImode, we ought to handle there the 32bit case too
6373          - do we need new constraint?  */
6374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6376       if (CONST_INT_P (operands[2])
6377           /* Avoid overflows.  */
6378           && (<MODE>mode != DImode
6379               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6380           && (INTVAL (operands[2]) == 128
6381               || (INTVAL (operands[2]) < 0
6382                   && INTVAL (operands[2]) != -128)))
6383         {
6384           operands[2] = GEN_INT (-INTVAL (operands[2]));
6385           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6386         }
6387       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set (attr "length_immediate")
6395       (if_then_else
6396         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6397         (const_string "1")
6398         (const_string "*")))
6399    (set_attr "mode" "<MODE>")])
6400
6401 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6402 (define_insn "*addsi_2_zext"
6403   [(set (reg FLAGS_REG)
6404         (compare
6405           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6406                    (match_operand:SI 2 "general_operand" "g"))
6407           (const_int 0)))
6408    (set (match_operand:DI 0 "register_operand" "=r")
6409         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6410   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6411    && ix86_binary_operator_ok (PLUS, SImode, operands)
6412    /* Current assemblers are broken and do not allow @GOTOFF in
6413       ought but a memory context.  */
6414    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6415 {
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_INCDEC:
6419       if (operands[2] == const1_rtx)
6420         return "inc{l}\t%k0";
6421       else
6422         {
6423           gcc_assert (operands[2] == constm1_rtx);
6424           return "dec{l}\t%k0";
6425         }
6426
6427     default:
6428       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6429          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6430       if (CONST_INT_P (operands[2])
6431           && (INTVAL (operands[2]) == 128
6432               || (INTVAL (operands[2]) < 0
6433                   && INTVAL (operands[2]) != -128)))
6434         {
6435           operands[2] = GEN_INT (-INTVAL (operands[2]));
6436           return "sub{l}\t{%2, %k0|%k0, %2}";
6437         }
6438       return "add{l}\t{%2, %k0|%k0, %2}";
6439     }
6440 }
6441   [(set (attr "type")
6442      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6443         (const_string "incdec")
6444         (const_string "alu")))
6445    (set (attr "length_immediate")
6446       (if_then_else
6447         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6448         (const_string "1")
6449         (const_string "*")))
6450    (set_attr "mode" "SI")])
6451
6452 (define_insn "*addhi_2"
6453   [(set (reg FLAGS_REG)
6454         (compare
6455           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6456                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6457           (const_int 0)))
6458    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6459         (plus:HI (match_dup 1) (match_dup 2)))]
6460   "ix86_match_ccmode (insn, CCGOCmode)
6461    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6462 {
6463   switch (get_attr_type (insn))
6464     {
6465     case TYPE_INCDEC:
6466       if (operands[2] == const1_rtx)
6467         return "inc{w}\t%0";
6468       else
6469         {
6470           gcc_assert (operands[2] == constm1_rtx);
6471           return "dec{w}\t%0";
6472         }
6473
6474     default:
6475       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6476          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6477       if (CONST_INT_P (operands[2])
6478           && (INTVAL (operands[2]) == 128
6479               || (INTVAL (operands[2]) < 0
6480                   && INTVAL (operands[2]) != -128)))
6481         {
6482           operands[2] = GEN_INT (-INTVAL (operands[2]));
6483           return "sub{w}\t{%2, %0|%0, %2}";
6484         }
6485       return "add{w}\t{%2, %0|%0, %2}";
6486     }
6487 }
6488   [(set (attr "type")
6489      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6490         (const_string "incdec")
6491         (const_string "alu")))
6492    (set (attr "length_immediate")
6493       (if_then_else
6494         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6495         (const_string "1")
6496         (const_string "*")))
6497    (set_attr "mode" "HI")])
6498
6499 (define_insn "*addqi_2"
6500   [(set (reg FLAGS_REG)
6501         (compare
6502           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6503                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6504           (const_int 0)))
6505    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6506         (plus:QI (match_dup 1) (match_dup 2)))]
6507   "ix86_match_ccmode (insn, CCGOCmode)
6508    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6509 {
6510   switch (get_attr_type (insn))
6511     {
6512     case TYPE_INCDEC:
6513       if (operands[2] == const1_rtx)
6514         return "inc{b}\t%0";
6515       else
6516         {
6517           gcc_assert (operands[2] == constm1_rtx
6518                       || (CONST_INT_P (operands[2])
6519                           && INTVAL (operands[2]) == 255));
6520           return "dec{b}\t%0";
6521         }
6522
6523     default:
6524       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6525       if (CONST_INT_P (operands[2])
6526           && INTVAL (operands[2]) < 0)
6527         {
6528           operands[2] = GEN_INT (-INTVAL (operands[2]));
6529           return "sub{b}\t{%2, %0|%0, %2}";
6530         }
6531       return "add{b}\t{%2, %0|%0, %2}";
6532     }
6533 }
6534   [(set (attr "type")
6535      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6536         (const_string "incdec")
6537         (const_string "alu")))
6538    (set_attr "mode" "QI")])
6539
6540 (define_insn "*add<mode>_3"
6541   [(set (reg FLAGS_REG)
6542         (compare
6543           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6544           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6545    (clobber (match_scratch:SWI48 0 "=r"))]
6546   "ix86_match_ccmode (insn, CCZmode)
6547    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6548    /* Current assemblers are broken and do not allow @GOTOFF in
6549       ought but a memory context.  */
6550    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6551 {
6552   switch (get_attr_type (insn))
6553     {
6554     case TYPE_INCDEC:
6555       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6556       if (operands[2] == const1_rtx)
6557         return "inc{<imodesuffix>}\t%0";
6558       else
6559         {
6560           gcc_assert (operands[2] == constm1_rtx);
6561           return "dec{<imodesuffix>}\t%0";
6562         }
6563
6564     default:
6565       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6566       /* ???? In DImode, we ought to handle there the 32bit case too
6567          - do we need new constraint?  */
6568       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6569          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6570       if (CONST_INT_P (operands[2])
6571           /* Avoid overflows.  */
6572           && (<MODE>mode != DImode
6573               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6574           && (INTVAL (operands[2]) == 128
6575               || (INTVAL (operands[2]) < 0
6576                   && INTVAL (operands[2]) != -128)))
6577         {
6578           operands[2] = GEN_INT (-INTVAL (operands[2]));
6579           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6580         }
6581       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6582     }
6583 }
6584   [(set (attr "type")
6585      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6586         (const_string "incdec")
6587         (const_string "alu")))
6588    (set (attr "length_immediate")
6589       (if_then_else
6590         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6591         (const_string "1")
6592         (const_string "*")))
6593    (set_attr "mode" "<MODE>")])
6594
6595 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6596 (define_insn "*addsi_3_zext"
6597   [(set (reg FLAGS_REG)
6598         (compare
6599           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6600           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6601    (set (match_operand:DI 0 "register_operand" "=r")
6602         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6603   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6604    && ix86_binary_operator_ok (PLUS, SImode, operands)
6605    /* Current assemblers are broken and do not allow @GOTOFF in
6606       ought but a memory context.  */
6607    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6608 {
6609   switch (get_attr_type (insn))
6610     {
6611     case TYPE_INCDEC:
6612       if (operands[2] == const1_rtx)
6613         return "inc{l}\t%k0";
6614       else
6615         {
6616           gcc_assert (operands[2] == constm1_rtx);
6617           return "dec{l}\t%k0";
6618         }
6619
6620     default:
6621       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6622          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6623       if (CONST_INT_P (operands[2])
6624           && (INTVAL (operands[2]) == 128
6625               || (INTVAL (operands[2]) < 0
6626                   && INTVAL (operands[2]) != -128)))
6627         {
6628           operands[2] = GEN_INT (-INTVAL (operands[2]));
6629           return "sub{l}\t{%2, %k0|%k0, %2}";
6630         }
6631       return "add{l}\t{%2, %k0|%k0, %2}";
6632     }
6633 }
6634   [(set (attr "type")
6635      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6636         (const_string "incdec")
6637         (const_string "alu")))
6638    (set (attr "length_immediate")
6639       (if_then_else
6640         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6641         (const_string "1")
6642         (const_string "*")))
6643    (set_attr "mode" "SI")])
6644
6645 (define_insn "*addhi_3"
6646   [(set (reg FLAGS_REG)
6647         (compare
6648           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6649           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6650    (clobber (match_scratch:HI 0 "=r"))]
6651   "ix86_match_ccmode (insn, CCZmode)
6652    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6653 {
6654   switch (get_attr_type (insn))
6655     {
6656     case TYPE_INCDEC:
6657       if (operands[2] == const1_rtx)
6658         return "inc{w}\t%0";
6659       else
6660         {
6661           gcc_assert (operands[2] == constm1_rtx);
6662           return "dec{w}\t%0";
6663         }
6664
6665     default:
6666       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6667          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6668       if (CONST_INT_P (operands[2])
6669           && (INTVAL (operands[2]) == 128
6670               || (INTVAL (operands[2]) < 0
6671                   && INTVAL (operands[2]) != -128)))
6672         {
6673           operands[2] = GEN_INT (-INTVAL (operands[2]));
6674           return "sub{w}\t{%2, %0|%0, %2}";
6675         }
6676       return "add{w}\t{%2, %0|%0, %2}";
6677     }
6678 }
6679   [(set (attr "type")
6680      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6681         (const_string "incdec")
6682         (const_string "alu")))
6683    (set (attr "length_immediate")
6684       (if_then_else
6685         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6686         (const_string "1")
6687         (const_string "*")))
6688    (set_attr "mode" "HI")])
6689
6690 (define_insn "*addqi_3"
6691   [(set (reg FLAGS_REG)
6692         (compare
6693           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6694           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6695    (clobber (match_scratch:QI 0 "=q"))]
6696   "ix86_match_ccmode (insn, CCZmode)
6697    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6698 {
6699   switch (get_attr_type (insn))
6700     {
6701     case TYPE_INCDEC:
6702       if (operands[2] == const1_rtx)
6703         return "inc{b}\t%0";
6704       else
6705         {
6706           gcc_assert (operands[2] == constm1_rtx
6707                       || (CONST_INT_P (operands[2])
6708                           && INTVAL (operands[2]) == 255));
6709           return "dec{b}\t%0";
6710         }
6711
6712     default:
6713       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6714       if (CONST_INT_P (operands[2])
6715           && INTVAL (operands[2]) < 0)
6716         {
6717           operands[2] = GEN_INT (-INTVAL (operands[2]));
6718           return "sub{b}\t{%2, %0|%0, %2}";
6719         }
6720       return "add{b}\t{%2, %0|%0, %2}";
6721     }
6722 }
6723   [(set (attr "type")
6724      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6725         (const_string "incdec")
6726         (const_string "alu")))
6727    (set_attr "mode" "QI")])
6728
6729 ; For comparisons against 1, -1 and 128, we may generate better code
6730 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6731 ; is matched then.  We can't accept general immediate, because for
6732 ; case of overflows,  the result is messed up.
6733 ; This pattern also don't hold of 0x8000000000000000, since the value
6734 ; overflows when negated.
6735 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6736 ; only for comparisons not depending on it.
6737
6738 (define_insn "*adddi_4"
6739   [(set (reg FLAGS_REG)
6740         (compare
6741           (match_operand:DI 1 "nonimmediate_operand" "0")
6742           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6743    (clobber (match_scratch:DI 0 "=rm"))]
6744   "TARGET_64BIT
6745    && ix86_match_ccmode (insn, CCGCmode)"
6746 {
6747   switch (get_attr_type (insn))
6748     {
6749     case TYPE_INCDEC:
6750       if (operands[2] == constm1_rtx)
6751         return "inc{q}\t%0";
6752       else
6753         {
6754           gcc_assert (operands[2] == const1_rtx);
6755           return "dec{q}\t%0";
6756         }
6757
6758     default:
6759       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6760       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6761          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6762       if ((INTVAL (operands[2]) == -128
6763            || (INTVAL (operands[2]) > 0
6764                && INTVAL (operands[2]) != 128))
6765           /* Avoid overflows.  */
6766           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6767         return "sub{q}\t{%2, %0|%0, %2}";
6768       operands[2] = GEN_INT (-INTVAL (operands[2]));
6769       return "add{q}\t{%2, %0|%0, %2}";
6770     }
6771 }
6772   [(set (attr "type")
6773      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6774         (const_string "incdec")
6775         (const_string "alu")))
6776    (set (attr "length_immediate")
6777       (if_then_else
6778         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6779         (const_string "1")
6780         (const_string "*")))
6781    (set_attr "mode" "DI")])
6782
6783 ; For comparisons against 1, -1 and 128, we may generate better code
6784 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6785 ; is matched then.  We can't accept general immediate, because for
6786 ; case of overflows,  the result is messed up.
6787 ; This pattern also don't hold of 0x80000000, since the value overflows
6788 ; when negated.
6789 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6790 ; only for comparisons not depending on it.
6791
6792 (define_insn "*addsi_4"
6793   [(set (reg FLAGS_REG)
6794         (compare
6795           (match_operand:SI 1 "nonimmediate_operand" "0")
6796           (match_operand:SI 2 "const_int_operand" "n")))
6797    (clobber (match_scratch:SI 0 "=rm"))]
6798   "ix86_match_ccmode (insn, CCGCmode)
6799    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6800 {
6801   switch (get_attr_type (insn))
6802     {
6803     case TYPE_INCDEC:
6804       if (operands[2] == constm1_rtx)
6805         return "inc{l}\t%0";
6806       else
6807         {
6808           gcc_assert (operands[2] == const1_rtx);
6809           return "dec{l}\t%0";
6810         }
6811
6812     default:
6813       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6814       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6815          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6816       if ((INTVAL (operands[2]) == -128
6817            || (INTVAL (operands[2]) > 0
6818                && INTVAL (operands[2]) != 128)))
6819         return "sub{l}\t{%2, %0|%0, %2}";
6820       operands[2] = GEN_INT (-INTVAL (operands[2]));
6821       return "add{l}\t{%2, %0|%0, %2}";
6822     }
6823 }
6824   [(set (attr "type")
6825      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6826         (const_string "incdec")
6827         (const_string "alu")))
6828    (set (attr "length_immediate")
6829       (if_then_else
6830         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6831         (const_string "1")
6832         (const_string "*")))
6833    (set_attr "mode" "SI")])
6834
6835 ; See comments above addsi_4 for details.
6836
6837 (define_insn "*addhi_4"
6838   [(set (reg FLAGS_REG)
6839         (compare
6840           (match_operand:HI 1 "nonimmediate_operand" "0")
6841           (match_operand:HI 2 "const_int_operand" "n")))
6842    (clobber (match_scratch:HI 0 "=rm"))]
6843   "ix86_match_ccmode (insn, CCGCmode)
6844    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6845 {
6846   switch (get_attr_type (insn))
6847     {
6848     case TYPE_INCDEC:
6849       if (operands[2] == constm1_rtx)
6850         return "inc{w}\t%0";
6851       else
6852         {
6853           gcc_assert (operands[2] == const1_rtx);
6854           return "dec{w}\t%0";
6855         }
6856
6857     default:
6858       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6859       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6860          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6861       if ((INTVAL (operands[2]) == -128
6862            || (INTVAL (operands[2]) > 0
6863                && INTVAL (operands[2]) != 128)))
6864         return "sub{w}\t{%2, %0|%0, %2}";
6865       operands[2] = GEN_INT (-INTVAL (operands[2]));
6866       return "add{w}\t{%2, %0|%0, %2}";
6867     }
6868 }
6869   [(set (attr "type")
6870      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6871         (const_string "incdec")
6872         (const_string "alu")))
6873    (set (attr "length_immediate")
6874       (if_then_else
6875         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6876         (const_string "1")
6877         (const_string "*")))
6878    (set_attr "mode" "HI")])
6879
6880 ; See comments above addsi_4 for details.
6881
6882 (define_insn "*addqi_4"
6883   [(set (reg FLAGS_REG)
6884         (compare
6885           (match_operand:QI 1 "nonimmediate_operand" "0")
6886           (match_operand:QI 2 "const_int_operand" "n")))
6887    (clobber (match_scratch:QI 0 "=qm"))]
6888   "ix86_match_ccmode (insn, CCGCmode)
6889    && (INTVAL (operands[2]) & 0xff) != 0x80"
6890 {
6891   switch (get_attr_type (insn))
6892     {
6893     case TYPE_INCDEC:
6894       if (operands[2] == constm1_rtx
6895           || (CONST_INT_P (operands[2])
6896               && INTVAL (operands[2]) == 255))
6897         return "inc{b}\t%0";
6898       else
6899         {
6900           gcc_assert (operands[2] == const1_rtx);
6901           return "dec{b}\t%0";
6902         }
6903
6904     default:
6905       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6906       if (INTVAL (operands[2]) < 0)
6907         {
6908           operands[2] = GEN_INT (-INTVAL (operands[2]));
6909           return "add{b}\t{%2, %0|%0, %2}";
6910         }
6911       return "sub{b}\t{%2, %0|%0, %2}";
6912     }
6913 }
6914   [(set (attr "type")
6915      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6916         (const_string "incdec")
6917         (const_string "alu")))
6918    (set_attr "mode" "QI")])
6919
6920 (define_insn "*add<mode>_5"
6921   [(set (reg FLAGS_REG)
6922         (compare
6923           (plus:SWI48
6924             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6925             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6926           (const_int 0)))
6927    (clobber (match_scratch:SWI48 0 "=r"))]
6928   "ix86_match_ccmode (insn, CCGOCmode)
6929    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6930    /* Current assemblers are broken and do not allow @GOTOFF in
6931       ought but a memory context.  */
6932    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6933 {
6934   switch (get_attr_type (insn))
6935     {
6936     case TYPE_INCDEC:
6937       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6938       if (operands[2] == const1_rtx)
6939         return "inc{<imodesuffix>}\t%0";
6940       else
6941         {
6942           gcc_assert (operands[2] == constm1_rtx);
6943           return "dec{<imodesuffix>}\t%0";
6944         }
6945
6946     default:
6947       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6948       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6949          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6950       if (CONST_INT_P (operands[2])
6951           /* Avoid overflows.  */
6952           && (<MODE>mode != DImode
6953               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6954           && (INTVAL (operands[2]) == 128
6955               || (INTVAL (operands[2]) < 0
6956                   && INTVAL (operands[2]) != -128)))
6957         {
6958           operands[2] = GEN_INT (-INTVAL (operands[2]));
6959           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6960         }
6961       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6962     }
6963 }
6964   [(set (attr "type")
6965      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6966         (const_string "incdec")
6967         (const_string "alu")))
6968    (set (attr "length_immediate")
6969       (if_then_else
6970         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6971         (const_string "1")
6972         (const_string "*")))
6973    (set_attr "mode" "<MODE>")])
6974
6975 (define_insn "*addhi_5"
6976   [(set (reg FLAGS_REG)
6977         (compare
6978           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6979                    (match_operand:HI 2 "general_operand" "rmn"))
6980           (const_int 0)))
6981    (clobber (match_scratch:HI 0 "=r"))]
6982   "ix86_match_ccmode (insn, CCGOCmode)
6983    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6984 {
6985   switch (get_attr_type (insn))
6986     {
6987     case TYPE_INCDEC:
6988       if (operands[2] == const1_rtx)
6989         return "inc{w}\t%0";
6990       else
6991         {
6992           gcc_assert (operands[2] == constm1_rtx);
6993           return "dec{w}\t%0";
6994         }
6995
6996     default:
6997       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6999       if (CONST_INT_P (operands[2])
7000           && (INTVAL (operands[2]) == 128
7001               || (INTVAL (operands[2]) < 0
7002                   && INTVAL (operands[2]) != -128)))
7003         {
7004           operands[2] = GEN_INT (-INTVAL (operands[2]));
7005           return "sub{w}\t{%2, %0|%0, %2}";
7006         }
7007       return "add{w}\t{%2, %0|%0, %2}";
7008     }
7009 }
7010   [(set (attr "type")
7011      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7012         (const_string "incdec")
7013         (const_string "alu")))
7014    (set (attr "length_immediate")
7015       (if_then_else
7016         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7017         (const_string "1")
7018         (const_string "*")))
7019    (set_attr "mode" "HI")])
7020
7021 (define_insn "*addqi_5"
7022   [(set (reg FLAGS_REG)
7023         (compare
7024           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7025                    (match_operand:QI 2 "general_operand" "qmn"))
7026           (const_int 0)))
7027    (clobber (match_scratch:QI 0 "=q"))]
7028   "ix86_match_ccmode (insn, CCGOCmode)
7029    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7030 {
7031   switch (get_attr_type (insn))
7032     {
7033     case TYPE_INCDEC:
7034       if (operands[2] == const1_rtx)
7035         return "inc{b}\t%0";
7036       else
7037         {
7038           gcc_assert (operands[2] == constm1_rtx
7039                       || (CONST_INT_P (operands[2])
7040                           && INTVAL (operands[2]) == 255));
7041           return "dec{b}\t%0";
7042         }
7043
7044     default:
7045       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7046       if (CONST_INT_P (operands[2])
7047           && INTVAL (operands[2]) < 0)
7048         {
7049           operands[2] = GEN_INT (-INTVAL (operands[2]));
7050           return "sub{b}\t{%2, %0|%0, %2}";
7051         }
7052       return "add{b}\t{%2, %0|%0, %2}";
7053     }
7054 }
7055   [(set (attr "type")
7056      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7057         (const_string "incdec")
7058         (const_string "alu")))
7059    (set_attr "mode" "QI")])
7060
7061 (define_insn "*addqi_ext_1_rex64"
7062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7063                          (const_int 8)
7064                          (const_int 8))
7065         (plus:SI
7066           (zero_extract:SI
7067             (match_operand 1 "ext_register_operand" "0")
7068             (const_int 8)
7069             (const_int 8))
7070           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7071    (clobber (reg:CC FLAGS_REG))]
7072   "TARGET_64BIT"
7073 {
7074   switch (get_attr_type (insn))
7075     {
7076     case TYPE_INCDEC:
7077       if (operands[2] == const1_rtx)
7078         return "inc{b}\t%h0";
7079       else
7080         {
7081           gcc_assert (operands[2] == constm1_rtx
7082                       || (CONST_INT_P (operands[2])
7083                           && INTVAL (operands[2]) == 255));
7084           return "dec{b}\t%h0";
7085         }
7086
7087     default:
7088       return "add{b}\t{%2, %h0|%h0, %2}";
7089     }
7090 }
7091   [(set (attr "type")
7092      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7093         (const_string "incdec")
7094         (const_string "alu")))
7095    (set_attr "modrm" "1")
7096    (set_attr "mode" "QI")])
7097
7098 (define_insn "addqi_ext_1"
7099   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7100                          (const_int 8)
7101                          (const_int 8))
7102         (plus:SI
7103           (zero_extract:SI
7104             (match_operand 1 "ext_register_operand" "0")
7105             (const_int 8)
7106             (const_int 8))
7107           (match_operand:QI 2 "general_operand" "Qmn")))
7108    (clobber (reg:CC FLAGS_REG))]
7109   "!TARGET_64BIT"
7110 {
7111   switch (get_attr_type (insn))
7112     {
7113     case TYPE_INCDEC:
7114       if (operands[2] == const1_rtx)
7115         return "inc{b}\t%h0";
7116       else
7117         {
7118           gcc_assert (operands[2] == constm1_rtx
7119                       || (CONST_INT_P (operands[2])
7120                           && INTVAL (operands[2]) == 255));
7121           return "dec{b}\t%h0";
7122         }
7123
7124     default:
7125       return "add{b}\t{%2, %h0|%h0, %2}";
7126     }
7127 }
7128   [(set (attr "type")
7129      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7130         (const_string "incdec")
7131         (const_string "alu")))
7132    (set_attr "modrm" "1")
7133    (set_attr "mode" "QI")])
7134
7135 (define_insn "*addqi_ext_2"
7136   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7137                          (const_int 8)
7138                          (const_int 8))
7139         (plus:SI
7140           (zero_extract:SI
7141             (match_operand 1 "ext_register_operand" "%0")
7142             (const_int 8)
7143             (const_int 8))
7144           (zero_extract:SI
7145             (match_operand 2 "ext_register_operand" "Q")
7146             (const_int 8)
7147             (const_int 8))))
7148    (clobber (reg:CC FLAGS_REG))]
7149   ""
7150   "add{b}\t{%h2, %h0|%h0, %h2}"
7151   [(set_attr "type" "alu")
7152    (set_attr "mode" "QI")])
7153
7154 ;; The lea patterns for non-Pmodes needs to be matched by
7155 ;; several insns converted to real lea by splitters.
7156
7157 (define_insn_and_split "*lea_general_1"
7158   [(set (match_operand 0 "register_operand" "=r")
7159         (plus (plus (match_operand 1 "index_register_operand" "l")
7160                     (match_operand 2 "register_operand" "r"))
7161               (match_operand 3 "immediate_operand" "i")))]
7162   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7163     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7164    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7165    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7166    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7167    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7168        || GET_MODE (operands[3]) == VOIDmode)"
7169   "#"
7170   "&& reload_completed"
7171   [(const_int 0)]
7172 {
7173   rtx pat;
7174   operands[0] = gen_lowpart (SImode, operands[0]);
7175   operands[1] = gen_lowpart (Pmode, operands[1]);
7176   operands[2] = gen_lowpart (Pmode, operands[2]);
7177   operands[3] = gen_lowpart (Pmode, operands[3]);
7178   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7179                       operands[3]);
7180   if (Pmode != SImode)
7181     pat = gen_rtx_SUBREG (SImode, pat, 0);
7182   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7183   DONE;
7184 }
7185   [(set_attr "type" "lea")
7186    (set_attr "mode" "SI")])
7187
7188 (define_insn_and_split "*lea_general_1_zext"
7189   [(set (match_operand:DI 0 "register_operand" "=r")
7190         (zero_extend:DI
7191           (plus:SI (plus:SI
7192                      (match_operand:SI 1 "index_register_operand" "l")
7193                      (match_operand:SI 2 "register_operand" "r"))
7194                    (match_operand:SI 3 "immediate_operand" "i"))))]
7195   "TARGET_64BIT"
7196   "#"
7197   "&& reload_completed"
7198   [(set (match_dup 0)
7199         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7200                                                      (match_dup 2))
7201                                             (match_dup 3)) 0)))]
7202 {
7203   operands[1] = gen_lowpart (Pmode, operands[1]);
7204   operands[2] = gen_lowpart (Pmode, operands[2]);
7205   operands[3] = gen_lowpart (Pmode, operands[3]);
7206 }
7207   [(set_attr "type" "lea")
7208    (set_attr "mode" "SI")])
7209
7210 (define_insn_and_split "*lea_general_2"
7211   [(set (match_operand 0 "register_operand" "=r")
7212         (plus (mult (match_operand 1 "index_register_operand" "l")
7213                     (match_operand 2 "const248_operand" "i"))
7214               (match_operand 3 "nonmemory_operand" "ri")))]
7215   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7216     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7217    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7218    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7219    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7220        || GET_MODE (operands[3]) == VOIDmode)"
7221   "#"
7222   "&& reload_completed"
7223   [(const_int 0)]
7224 {
7225   rtx pat;
7226   operands[0] = gen_lowpart (SImode, operands[0]);
7227   operands[1] = gen_lowpart (Pmode, operands[1]);
7228   operands[3] = gen_lowpart (Pmode, operands[3]);
7229   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7230                       operands[3]);
7231   if (Pmode != SImode)
7232     pat = gen_rtx_SUBREG (SImode, pat, 0);
7233   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7234   DONE;
7235 }
7236   [(set_attr "type" "lea")
7237    (set_attr "mode" "SI")])
7238
7239 (define_insn_and_split "*lea_general_2_zext"
7240   [(set (match_operand:DI 0 "register_operand" "=r")
7241         (zero_extend:DI
7242           (plus:SI (mult:SI
7243                      (match_operand:SI 1 "index_register_operand" "l")
7244                      (match_operand:SI 2 "const248_operand" "n"))
7245                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7246   "TARGET_64BIT"
7247   "#"
7248   "&& reload_completed"
7249   [(set (match_dup 0)
7250         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7251                                                      (match_dup 2))
7252                                             (match_dup 3)) 0)))]
7253 {
7254   operands[1] = gen_lowpart (Pmode, operands[1]);
7255   operands[3] = gen_lowpart (Pmode, operands[3]);
7256 }
7257   [(set_attr "type" "lea")
7258    (set_attr "mode" "SI")])
7259
7260 (define_insn_and_split "*lea_general_3"
7261   [(set (match_operand 0 "register_operand" "=r")
7262         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7263                           (match_operand 2 "const248_operand" "i"))
7264                     (match_operand 3 "register_operand" "r"))
7265               (match_operand 4 "immediate_operand" "i")))]
7266   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7267     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7268    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7269    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7270    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7271   "#"
7272   "&& reload_completed"
7273   [(const_int 0)]
7274 {
7275   rtx pat;
7276   operands[0] = gen_lowpart (SImode, operands[0]);
7277   operands[1] = gen_lowpart (Pmode, operands[1]);
7278   operands[3] = gen_lowpart (Pmode, operands[3]);
7279   operands[4] = gen_lowpart (Pmode, operands[4]);
7280   pat = gen_rtx_PLUS (Pmode,
7281                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7282                                                          operands[2]),
7283                                     operands[3]),
7284                       operands[4]);
7285   if (Pmode != SImode)
7286     pat = gen_rtx_SUBREG (SImode, pat, 0);
7287   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7288   DONE;
7289 }
7290   [(set_attr "type" "lea")
7291    (set_attr "mode" "SI")])
7292
7293 (define_insn_and_split "*lea_general_3_zext"
7294   [(set (match_operand:DI 0 "register_operand" "=r")
7295         (zero_extend:DI
7296           (plus:SI (plus:SI
7297                      (mult:SI
7298                        (match_operand:SI 1 "index_register_operand" "l")
7299                        (match_operand:SI 2 "const248_operand" "n"))
7300                      (match_operand:SI 3 "register_operand" "r"))
7301                    (match_operand:SI 4 "immediate_operand" "i"))))]
7302   "TARGET_64BIT"
7303   "#"
7304   "&& reload_completed"
7305   [(set (match_dup 0)
7306         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7307                                                               (match_dup 2))
7308                                                      (match_dup 3))
7309                                             (match_dup 4)) 0)))]
7310 {
7311   operands[1] = gen_lowpart (Pmode, operands[1]);
7312   operands[3] = gen_lowpart (Pmode, operands[3]);
7313   operands[4] = gen_lowpart (Pmode, operands[4]);
7314 }
7315   [(set_attr "type" "lea")
7316    (set_attr "mode" "SI")])
7317
7318 ;; Convert lea to the lea pattern to avoid flags dependency.
7319 (define_split
7320   [(set (match_operand:DI 0 "register_operand" "")
7321         (plus:DI (match_operand:DI 1 "register_operand" "")
7322                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT && reload_completed 
7325    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7326   [(set (match_dup 0)
7327         (plus:DI (match_dup 1)
7328                  (match_dup 2)))]
7329   "")
7330
7331 ;; Convert lea to the lea pattern to avoid flags dependency.
7332 (define_split
7333   [(set (match_operand 0 "register_operand" "")
7334         (plus (match_operand 1 "register_operand" "")
7335               (match_operand 2 "nonmemory_operand" "")))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7338   [(const_int 0)]
7339 {
7340   rtx pat;
7341   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7342      may confuse gen_lowpart.  */
7343   if (GET_MODE (operands[0]) != Pmode)
7344     {
7345       operands[1] = gen_lowpart (Pmode, operands[1]);
7346       operands[2] = gen_lowpart (Pmode, operands[2]);
7347     }
7348   operands[0] = gen_lowpart (SImode, operands[0]);
7349   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7350   if (Pmode != SImode)
7351     pat = gen_rtx_SUBREG (SImode, pat, 0);
7352   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7353   DONE;
7354 })
7355
7356 ;; Convert lea to the lea pattern to avoid flags dependency.
7357 (define_split
7358   [(set (match_operand:DI 0 "register_operand" "")
7359         (zero_extend:DI
7360           (plus:SI (match_operand:SI 1 "register_operand" "")
7361                    (match_operand:SI 2 "nonmemory_operand" ""))))
7362    (clobber (reg:CC FLAGS_REG))]
7363   "TARGET_64BIT && reload_completed
7364    && true_regnum (operands[0]) != true_regnum (operands[1])"
7365   [(set (match_dup 0)
7366         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7367 {
7368   operands[1] = gen_lowpart (Pmode, operands[1]);
7369   operands[2] = gen_lowpart (Pmode, operands[2]);
7370 })
7371 \f
7372 ;; Subtract instructions
7373
7374 (define_expand "sub<mode>3"
7375   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7376         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7377                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7378   ""
7379   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7380
7381 (define_insn_and_split "*sub<dwi>3_doubleword"
7382   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7383         (minus:<DWI>
7384           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7385           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7386    (clobber (reg:CC FLAGS_REG))]
7387   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7388   "#"
7389   "reload_completed"
7390   [(parallel [(set (reg:CC FLAGS_REG)
7391                    (compare:CC (match_dup 1) (match_dup 2)))
7392               (set (match_dup 0)
7393                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7394    (parallel [(set (match_dup 3)
7395                    (minus:DWIH
7396                      (match_dup 4)
7397                      (plus:DWIH
7398                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7399                        (match_dup 5))))
7400               (clobber (reg:CC FLAGS_REG))])]
7401   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7402
7403 (define_insn "*sub<mode>_1"
7404   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7405         (minus:SWI
7406           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7407           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7408    (clobber (reg:CC FLAGS_REG))]
7409   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7410   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7411   [(set_attr "type" "alu")
7412    (set_attr "mode" "<MODE>")])
7413
7414 (define_insn "*subsi_1_zext"
7415   [(set (match_operand:DI 0 "register_operand" "=r")
7416         (zero_extend:DI
7417           (minus:SI (match_operand:SI 1 "register_operand" "0")
7418                     (match_operand:SI 2 "general_operand" "g"))))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421   "sub{l}\t{%2, %k0|%k0, %2}"
7422   [(set_attr "type" "alu")
7423    (set_attr "mode" "SI")])
7424
7425 (define_insn "*subqi_1_slp"
7426   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7427         (minus:QI (match_dup 0)
7428                   (match_operand:QI 1 "general_operand" "qn,qm")))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7431    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7432   "sub{b}\t{%1, %0|%0, %1}"
7433   [(set_attr "type" "alu1")
7434    (set_attr "mode" "QI")])
7435
7436 (define_insn "*sub<mode>_2"
7437   [(set (reg FLAGS_REG)
7438         (compare
7439           (minus:SWI
7440             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7441             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7442           (const_int 0)))
7443    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7444         (minus:SWI (match_dup 1) (match_dup 2)))]
7445   "ix86_match_ccmode (insn, CCGOCmode)
7446    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7447   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7448   [(set_attr "type" "alu")
7449    (set_attr "mode" "<MODE>")])
7450
7451 (define_insn "*subsi_2_zext"
7452   [(set (reg FLAGS_REG)
7453         (compare
7454           (minus:SI (match_operand:SI 1 "register_operand" "0")
7455                     (match_operand:SI 2 "general_operand" "g"))
7456           (const_int 0)))
7457    (set (match_operand:DI 0 "register_operand" "=r")
7458         (zero_extend:DI
7459           (minus:SI (match_dup 1)
7460                     (match_dup 2))))]
7461   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7462    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7463   "sub{l}\t{%2, %k0|%k0, %2}"
7464   [(set_attr "type" "alu")
7465    (set_attr "mode" "SI")])
7466
7467 (define_insn "*sub<mode>_3"
7468   [(set (reg FLAGS_REG)
7469         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7470                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7471    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7472         (minus:SWI (match_dup 1) (match_dup 2)))]
7473   "ix86_match_ccmode (insn, CCmode)
7474    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7475   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7476   [(set_attr "type" "alu")
7477    (set_attr "mode" "<MODE>")])
7478
7479 (define_insn "*subsi_3_zext"
7480   [(set (reg FLAGS_REG)
7481         (compare (match_operand:SI 1 "register_operand" "0")
7482                  (match_operand:SI 2 "general_operand" "g")))
7483    (set (match_operand:DI 0 "register_operand" "=r")
7484         (zero_extend:DI
7485           (minus:SI (match_dup 1)
7486                     (match_dup 2))))]
7487   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7488    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7489   "sub{l}\t{%2, %1|%1, %2}"
7490   [(set_attr "type" "alu")
7491    (set_attr "mode" "SI")])
7492 \f
7493 ;; Add with carry and subtract with borrow
7494
7495 (define_expand "<plusminus_insn><mode>3_carry"
7496   [(parallel
7497     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7498           (plusminus:SWI
7499             (match_operand:SWI 1 "nonimmediate_operand" "")
7500             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7501                        [(match_operand 3 "flags_reg_operand" "")
7502                         (const_int 0)])
7503                       (match_operand:SWI 2 "<general_operand>" ""))))
7504      (clobber (reg:CC FLAGS_REG))])]
7505   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7506   "")
7507
7508 (define_insn "*<plusminus_insn><mode>3_carry"
7509   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7510         (plusminus:SWI
7511           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7512           (plus:SWI
7513             (match_operator 3 "ix86_carry_flag_operator"
7514              [(reg FLAGS_REG) (const_int 0)])
7515             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7516    (clobber (reg:CC FLAGS_REG))]
7517   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7518   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7519   [(set_attr "type" "alu")
7520    (set_attr "use_carry" "1")
7521    (set_attr "pent_pair" "pu")
7522    (set_attr "mode" "<MODE>")])
7523
7524 (define_insn "*addsi3_carry_zext"
7525   [(set (match_operand:DI 0 "register_operand" "=r")
7526         (zero_extend:DI
7527           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7528                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7529                              [(reg FLAGS_REG) (const_int 0)])
7530                             (match_operand:SI 2 "general_operand" "g")))))
7531    (clobber (reg:CC FLAGS_REG))]
7532   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7533   "adc{l}\t{%2, %k0|%k0, %2}"
7534   [(set_attr "type" "alu")
7535    (set_attr "use_carry" "1")
7536    (set_attr "pent_pair" "pu")
7537    (set_attr "mode" "SI")])
7538
7539 (define_insn "*subsi3_carry_zext"
7540   [(set (match_operand:DI 0 "register_operand" "=r")
7541         (zero_extend:DI
7542           (minus:SI (match_operand:SI 1 "register_operand" "0")
7543                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7544                               [(reg FLAGS_REG) (const_int 0)])
7545                              (match_operand:SI 2 "general_operand" "g")))))
7546    (clobber (reg:CC FLAGS_REG))]
7547   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7548   "sbb{l}\t{%2, %k0|%k0, %2}"
7549   [(set_attr "type" "alu")
7550    (set_attr "pent_pair" "pu")
7551    (set_attr "mode" "SI")])
7552 \f
7553 ;; Overflow setting add and subtract instructions
7554
7555 (define_insn "*add<mode>3_cconly_overflow"
7556   [(set (reg:CCC FLAGS_REG)
7557         (compare:CCC
7558           (plus:SWI
7559             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7560             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7561           (match_dup 1)))
7562    (clobber (match_scratch:SWI 0 "=<r>"))]
7563   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7564   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7565   [(set_attr "type" "alu")
7566    (set_attr "mode" "<MODE>")])
7567
7568 (define_insn "*sub<mode>3_cconly_overflow"
7569   [(set (reg:CCC FLAGS_REG)
7570         (compare:CCC
7571           (minus:SWI
7572             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7573             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7574           (match_dup 0)))]
7575   ""
7576   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7577   [(set_attr "type" "icmp")
7578    (set_attr "mode" "<MODE>")])
7579
7580 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7581   [(set (reg:CCC FLAGS_REG)
7582         (compare:CCC
7583             (plusminus:SWI
7584                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7585                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7586             (match_dup 1)))
7587    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7588         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7589   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7590   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7591   [(set_attr "type" "alu")
7592    (set_attr "mode" "<MODE>")])
7593
7594 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7595   [(set (reg:CCC FLAGS_REG)
7596         (compare:CCC
7597           (plusminus:SI
7598             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7599             (match_operand:SI 2 "general_operand" "g"))
7600           (match_dup 1)))
7601    (set (match_operand:DI 0 "register_operand" "=r")
7602         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7603   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7604   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7605   [(set_attr "type" "alu")
7606    (set_attr "mode" "SI")])
7607
7608 ;; The patterns that match these are at the end of this file.
7609
7610 (define_expand "<plusminus_insn>xf3"
7611   [(set (match_operand:XF 0 "register_operand" "")
7612         (plusminus:XF
7613           (match_operand:XF 1 "register_operand" "")
7614           (match_operand:XF 2 "register_operand" "")))]
7615   "TARGET_80387"
7616   "")
7617
7618 (define_expand "<plusminus_insn><mode>3"
7619   [(set (match_operand:MODEF 0 "register_operand" "")
7620         (plusminus:MODEF
7621           (match_operand:MODEF 1 "register_operand" "")
7622           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7623   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7624     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7625   "")
7626 \f
7627 ;; Multiply instructions
7628
7629 (define_expand "mul<mode>3"
7630   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7631                    (mult:SWIM248
7632                      (match_operand:SWIM248 1 "register_operand" "")
7633                      (match_operand:SWIM248 2 "<general_operand>" "")))
7634               (clobber (reg:CC FLAGS_REG))])]
7635   ""
7636   "")
7637
7638 (define_expand "mulqi3"
7639   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7640                    (mult:QI
7641                      (match_operand:QI 1 "register_operand" "")
7642                      (match_operand:QI 2 "nonimmediate_operand" "")))
7643               (clobber (reg:CC FLAGS_REG))])]
7644   "TARGET_QIMODE_MATH"
7645   "")
7646
7647 ;; On AMDFAM10
7648 ;; IMUL reg32/64, reg32/64, imm8        Direct
7649 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7650 ;; IMUL reg32/64, reg32/64, imm32       Direct
7651 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7652 ;; IMUL reg32/64, reg32/64              Direct
7653 ;; IMUL reg32/64, mem32/64              Direct
7654
7655 (define_insn "*mul<mode>3_1"
7656   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7657         (mult:SWI48
7658           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7659           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7662   "@
7663    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7664    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7665    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7666   [(set_attr "type" "imul")
7667    (set_attr "prefix_0f" "0,0,1")
7668    (set (attr "athlon_decode")
7669         (cond [(eq_attr "cpu" "athlon")
7670                   (const_string "vector")
7671                (eq_attr "alternative" "1")
7672                   (const_string "vector")
7673                (and (eq_attr "alternative" "2")
7674                     (match_operand 1 "memory_operand" ""))
7675                   (const_string "vector")]
7676               (const_string "direct")))
7677    (set (attr "amdfam10_decode")
7678         (cond [(and (eq_attr "alternative" "0,1")
7679                     (match_operand 1 "memory_operand" ""))
7680                   (const_string "vector")]
7681               (const_string "direct")))
7682    (set_attr "mode" "<MODE>")])
7683
7684 (define_insn "*mulsi3_1_zext"
7685   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7686         (zero_extend:DI
7687           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7688                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7689    (clobber (reg:CC FLAGS_REG))]
7690   "TARGET_64BIT
7691    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7692   "@
7693    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7694    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7695    imul{l}\t{%2, %k0|%k0, %2}"
7696   [(set_attr "type" "imul")
7697    (set_attr "prefix_0f" "0,0,1")
7698    (set (attr "athlon_decode")
7699         (cond [(eq_attr "cpu" "athlon")
7700                   (const_string "vector")
7701                (eq_attr "alternative" "1")
7702                   (const_string "vector")
7703                (and (eq_attr "alternative" "2")
7704                     (match_operand 1 "memory_operand" ""))
7705                   (const_string "vector")]
7706               (const_string "direct")))
7707    (set (attr "amdfam10_decode")
7708         (cond [(and (eq_attr "alternative" "0,1")
7709                     (match_operand 1 "memory_operand" ""))
7710                   (const_string "vector")]
7711               (const_string "direct")))
7712    (set_attr "mode" "SI")])
7713
7714 ;; On AMDFAM10
7715 ;; IMUL reg16, reg16, imm8      VectorPath
7716 ;; IMUL reg16, mem16, imm8      VectorPath
7717 ;; IMUL reg16, reg16, imm16     VectorPath
7718 ;; IMUL reg16, mem16, imm16     VectorPath
7719 ;; IMUL reg16, reg16            Direct
7720 ;; IMUL reg16, mem16            Direct
7721
7722 (define_insn "*mulhi3_1"
7723   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7724         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7725                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "TARGET_HIMODE_MATH
7728    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7729   "@
7730    imul{w}\t{%2, %1, %0|%0, %1, %2}
7731    imul{w}\t{%2, %1, %0|%0, %1, %2}
7732    imul{w}\t{%2, %0|%0, %2}"
7733   [(set_attr "type" "imul")
7734    (set_attr "prefix_0f" "0,0,1")
7735    (set (attr "athlon_decode")
7736         (cond [(eq_attr "cpu" "athlon")
7737                   (const_string "vector")
7738                (eq_attr "alternative" "1,2")
7739                   (const_string "vector")]
7740               (const_string "direct")))
7741    (set (attr "amdfam10_decode")
7742         (cond [(eq_attr "alternative" "0,1")
7743                   (const_string "vector")]
7744               (const_string "direct")))
7745    (set_attr "mode" "HI")])
7746
7747 ;;On AMDFAM10
7748 ;; MUL reg8     Direct
7749 ;; MUL mem8     Direct
7750
7751 (define_insn "*mulqi3_1"
7752   [(set (match_operand:QI 0 "register_operand" "=a")
7753         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7754                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7755    (clobber (reg:CC FLAGS_REG))]
7756   "TARGET_QIMODE_MATH
7757    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7758   "mul{b}\t%2"
7759   [(set_attr "type" "imul")
7760    (set_attr "length_immediate" "0")
7761    (set (attr "athlon_decode")
7762      (if_then_else (eq_attr "cpu" "athlon")
7763         (const_string "vector")
7764         (const_string "direct")))
7765    (set_attr "amdfam10_decode" "direct")
7766    (set_attr "mode" "QI")])
7767
7768 (define_expand "<u>mul<mode><dwi>3"
7769   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7770                    (mult:<DWI>
7771                      (any_extend:<DWI>
7772                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7773                      (any_extend:<DWI>
7774                        (match_operand:DWIH 2 "register_operand" ""))))
7775               (clobber (reg:CC FLAGS_REG))])]
7776   ""
7777   "")
7778
7779 (define_expand "<u>mulqihi3"
7780   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7781                    (mult:HI
7782                      (any_extend:HI
7783                        (match_operand:QI 1 "nonimmediate_operand" ""))
7784                      (any_extend:HI
7785                        (match_operand:QI 2 "register_operand" ""))))
7786               (clobber (reg:CC FLAGS_REG))])]
7787   "TARGET_QIMODE_MATH"
7788   "")
7789
7790 (define_insn "*<u>mul<mode><dwi>3_1"
7791   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7792         (mult:<DWI>
7793           (any_extend:<DWI>
7794             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7795           (any_extend:<DWI>
7796             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7797    (clobber (reg:CC FLAGS_REG))]
7798   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7799   "<sgnprefix>mul{<imodesuffix>}\t%2"
7800   [(set_attr "type" "imul")
7801    (set_attr "length_immediate" "0")
7802    (set (attr "athlon_decode")
7803      (if_then_else (eq_attr "cpu" "athlon")
7804         (const_string "vector")
7805         (const_string "double")))
7806    (set_attr "amdfam10_decode" "double")
7807    (set_attr "mode" "<MODE>")])
7808
7809 (define_insn "*<u>mulqihi3_1"
7810   [(set (match_operand:HI 0 "register_operand" "=a")
7811         (mult:HI
7812           (any_extend:HI
7813             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7814           (any_extend:HI
7815             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7816    (clobber (reg:CC FLAGS_REG))]
7817   "TARGET_QIMODE_MATH
7818    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7819   "<sgnprefix>mul{b}\t%2"
7820   [(set_attr "type" "imul")
7821    (set_attr "length_immediate" "0")
7822    (set (attr "athlon_decode")
7823      (if_then_else (eq_attr "cpu" "athlon")
7824         (const_string "vector")
7825         (const_string "direct")))
7826    (set_attr "amdfam10_decode" "direct")
7827    (set_attr "mode" "QI")])
7828
7829 (define_expand "<s>mul<mode>3_highpart"
7830   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7831                    (truncate:SWI48
7832                      (lshiftrt:<DWI>
7833                        (mult:<DWI>
7834                          (any_extend:<DWI>
7835                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7836                          (any_extend:<DWI>
7837                            (match_operand:SWI48 2 "register_operand" "")))
7838                        (match_dup 4))))
7839               (clobber (match_scratch:SWI48 3 ""))
7840               (clobber (reg:CC FLAGS_REG))])]
7841   ""
7842   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7843
7844 (define_insn "*<s>muldi3_highpart_1"
7845   [(set (match_operand:DI 0 "register_operand" "=d")
7846         (truncate:DI
7847           (lshiftrt:TI
7848             (mult:TI
7849               (any_extend:TI
7850                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7851               (any_extend:TI
7852                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7853             (const_int 64))))
7854    (clobber (match_scratch:DI 3 "=1"))
7855    (clobber (reg:CC FLAGS_REG))]
7856   "TARGET_64BIT
7857    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7858   "<sgnprefix>mul{q}\t%2"
7859   [(set_attr "type" "imul")
7860    (set_attr "length_immediate" "0")
7861    (set (attr "athlon_decode")
7862      (if_then_else (eq_attr "cpu" "athlon")
7863         (const_string "vector")
7864         (const_string "double")))
7865    (set_attr "amdfam10_decode" "double")
7866    (set_attr "mode" "DI")])
7867
7868 (define_insn "*<s>mulsi3_highpart_1"
7869   [(set (match_operand:SI 0 "register_operand" "=d")
7870         (truncate:SI
7871           (lshiftrt:DI
7872             (mult:DI
7873               (any_extend:DI
7874                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7875               (any_extend:DI
7876                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7877             (const_int 32))))
7878    (clobber (match_scratch:SI 3 "=1"))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7881   "<sgnprefix>mul{l}\t%2"
7882   [(set_attr "type" "imul")
7883    (set_attr "length_immediate" "0")
7884    (set (attr "athlon_decode")
7885      (if_then_else (eq_attr "cpu" "athlon")
7886         (const_string "vector")
7887         (const_string "double")))
7888    (set_attr "amdfam10_decode" "double")
7889    (set_attr "mode" "SI")])
7890
7891 (define_insn "*<s>mulsi3_highpart_zext"
7892   [(set (match_operand:DI 0 "register_operand" "=d")
7893         (zero_extend:DI (truncate:SI
7894           (lshiftrt:DI
7895             (mult:DI (any_extend:DI
7896                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7897                      (any_extend:DI
7898                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7899             (const_int 32)))))
7900    (clobber (match_scratch:SI 3 "=1"))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "TARGET_64BIT
7903    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7904   "<sgnprefix>mul{l}\t%2"
7905   [(set_attr "type" "imul")
7906    (set_attr "length_immediate" "0")
7907    (set (attr "athlon_decode")
7908      (if_then_else (eq_attr "cpu" "athlon")
7909         (const_string "vector")
7910         (const_string "double")))
7911    (set_attr "amdfam10_decode" "double")
7912    (set_attr "mode" "SI")])
7913
7914 ;; The patterns that match these are at the end of this file.
7915
7916 (define_expand "mulxf3"
7917   [(set (match_operand:XF 0 "register_operand" "")
7918         (mult:XF (match_operand:XF 1 "register_operand" "")
7919                  (match_operand:XF 2 "register_operand" "")))]
7920   "TARGET_80387"
7921   "")
7922
7923 (define_expand "mul<mode>3"
7924   [(set (match_operand:MODEF 0 "register_operand" "")
7925         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7926                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7927   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7928     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7929   "")
7930 \f
7931 ;; Divide instructions
7932
7933 (define_insn "<u>divqi3"
7934   [(set (match_operand:QI 0 "register_operand" "=a")
7935         (any_div:QI
7936           (match_operand:HI 1 "register_operand" "0")
7937           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7938    (clobber (reg:CC FLAGS_REG))]
7939   "TARGET_QIMODE_MATH"
7940   "<sgnprefix>div{b}\t%2"
7941   [(set_attr "type" "idiv")
7942    (set_attr "mode" "QI")])
7943
7944 ;; The patterns that match these are at the end of this file.
7945
7946 (define_expand "divxf3"
7947   [(set (match_operand:XF 0 "register_operand" "")
7948         (div:XF (match_operand:XF 1 "register_operand" "")
7949                 (match_operand:XF 2 "register_operand" "")))]
7950   "TARGET_80387"
7951   "")
7952
7953 (define_expand "divdf3"
7954   [(set (match_operand:DF 0 "register_operand" "")
7955         (div:DF (match_operand:DF 1 "register_operand" "")
7956                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7957    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7958     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7959    "")
7960
7961 (define_expand "divsf3"
7962   [(set (match_operand:SF 0 "register_operand" "")
7963         (div:SF (match_operand:SF 1 "register_operand" "")
7964                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7965   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7966     || TARGET_SSE_MATH"
7967 {
7968   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7969       && flag_finite_math_only && !flag_trapping_math
7970       && flag_unsafe_math_optimizations)
7971     {
7972       ix86_emit_swdivsf (operands[0], operands[1],
7973                          operands[2], SFmode);
7974       DONE;
7975     }
7976 })
7977 \f
7978 ;; Divmod instructions.
7979
7980 (define_expand "divmod<mode>4"
7981   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7982                    (div:SWIM248
7983                      (match_operand:SWIM248 1 "register_operand" "")
7984                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7985               (set (match_operand:SWIM248 3 "register_operand" "")
7986                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7987               (clobber (reg:CC FLAGS_REG))])]
7988   ""
7989   "")
7990
7991 (define_insn_and_split "*divmod<mode>4"
7992   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7993         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7994                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7995    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7996         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7997    (clobber (reg:CC FLAGS_REG))]
7998   ""
7999   "#"
8000   "&& reload_completed"
8001   [(parallel [(set (match_dup 1)
8002                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8003               (clobber (reg:CC FLAGS_REG))])
8004    (parallel [(set (match_dup 0)
8005                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8006               (set (match_dup 1)
8007                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8008               (use (match_dup 1))
8009               (clobber (reg:CC FLAGS_REG))])]
8010 {
8011   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8012
8013   if (<MODE>mode != HImode
8014       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8015     operands[4] = operands[2];
8016   else
8017     {
8018       /* Avoid use of cltd in favor of a mov+shift.  */
8019       emit_move_insn (operands[1], operands[2]);
8020       operands[4] = operands[1];
8021     }
8022 }
8023   [(set_attr "type" "multi")
8024    (set_attr "mode" "<MODE>")])
8025
8026 (define_insn "*divmod<mode>4_noext"
8027   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8028         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8029                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8030    (set (match_operand:SWIM248 1 "register_operand" "=d")
8031         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8032    (use (match_operand:SWIM248 4 "register_operand" "1"))
8033    (clobber (reg:CC FLAGS_REG))]
8034   ""
8035   "idiv{<imodesuffix>}\t%3"
8036   [(set_attr "type" "idiv")
8037    (set_attr "mode" "<MODE>")])
8038
8039 (define_expand "udivmod<mode>4"
8040   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8041                    (udiv:SWIM248
8042                      (match_operand:SWIM248 1 "register_operand" "")
8043                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8044               (set (match_operand:SWIM248 3 "register_operand" "")
8045                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8046               (clobber (reg:CC FLAGS_REG))])]
8047   ""
8048   "")
8049
8050 (define_insn_and_split "*udivmod<mode>4"
8051   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8052         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8053                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8054    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8055         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8056    (clobber (reg:CC FLAGS_REG))]
8057   ""
8058   "#"
8059   "&& reload_completed"
8060   [(set (match_dup 1) (const_int 0))
8061    (parallel [(set (match_dup 0)
8062                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8063               (set (match_dup 1)
8064                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8065               (use (match_dup 1))
8066               (clobber (reg:CC FLAGS_REG))])]
8067   ""
8068   [(set_attr "type" "multi")
8069    (set_attr "mode" "<MODE>")])
8070
8071 (define_insn "*udivmod<mode>4_noext"
8072   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8073         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8074                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8075    (set (match_operand:SWIM248 1 "register_operand" "=d")
8076         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8077    (use (match_operand:SWIM248 4 "register_operand" "1"))
8078    (clobber (reg:CC FLAGS_REG))]
8079   ""
8080   "div{<imodesuffix>}\t%3"
8081   [(set_attr "type" "idiv")
8082    (set_attr "mode" "<MODE>")])
8083
8084 ;; We cannot use div/idiv for double division, because it causes
8085 ;; "division by zero" on the overflow and that's not what we expect
8086 ;; from truncate.  Because true (non truncating) double division is
8087 ;; never generated, we can't create this insn anyway.
8088 ;
8089 ;(define_insn ""
8090 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8091 ;       (truncate:SI
8092 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8093 ;                  (zero_extend:DI
8094 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8095 ;   (set (match_operand:SI 3 "register_operand" "=d")
8096 ;       (truncate:SI
8097 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8098 ;   (clobber (reg:CC FLAGS_REG))]
8099 ;  ""
8100 ;  "div{l}\t{%2, %0|%0, %2}"
8101 ;  [(set_attr "type" "idiv")])
8102 \f
8103 ;;- Logical AND instructions
8104
8105 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8106 ;; Note that this excludes ah.
8107
8108 (define_insn "*testdi_1_rex64"
8109   [(set (reg FLAGS_REG)
8110         (compare
8111           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8112                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8113           (const_int 0)))]
8114   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8115    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8116   "@
8117    test{l}\t{%k1, %k0|%k0, %k1}
8118    test{l}\t{%k1, %k0|%k0, %k1}
8119    test{q}\t{%1, %0|%0, %1}
8120    test{q}\t{%1, %0|%0, %1}
8121    test{q}\t{%1, %0|%0, %1}"
8122   [(set_attr "type" "test")
8123    (set_attr "modrm" "0,1,0,1,1")
8124    (set_attr "mode" "SI,SI,DI,DI,DI")
8125    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8126
8127 (define_insn "testsi_1"
8128   [(set (reg FLAGS_REG)
8129         (compare
8130           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8131                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8132           (const_int 0)))]
8133   "ix86_match_ccmode (insn, CCNOmode)
8134    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8135   "test{l}\t{%1, %0|%0, %1}"
8136   [(set_attr "type" "test")
8137    (set_attr "modrm" "0,1,1")
8138    (set_attr "mode" "SI")
8139    (set_attr "pent_pair" "uv,np,uv")])
8140
8141 (define_expand "testsi_ccno_1"
8142   [(set (reg:CCNO FLAGS_REG)
8143         (compare:CCNO
8144           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8145                   (match_operand:SI 1 "nonmemory_operand" ""))
8146           (const_int 0)))]
8147   ""
8148   "")
8149
8150 (define_insn "*testhi_1"
8151   [(set (reg FLAGS_REG)
8152         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8153                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8154                  (const_int 0)))]
8155   "ix86_match_ccmode (insn, CCNOmode)
8156    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8157   "test{w}\t{%1, %0|%0, %1}"
8158   [(set_attr "type" "test")
8159    (set_attr "modrm" "0,1,1")
8160    (set_attr "mode" "HI")
8161    (set_attr "pent_pair" "uv,np,uv")])
8162
8163 (define_expand "testqi_ccz_1"
8164   [(set (reg:CCZ FLAGS_REG)
8165         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8166                              (match_operand:QI 1 "nonmemory_operand" ""))
8167                  (const_int 0)))]
8168   ""
8169   "")
8170
8171 (define_insn "*testqi_1_maybe_si"
8172   [(set (reg FLAGS_REG)
8173         (compare
8174           (and:QI
8175             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8176             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8177           (const_int 0)))]
8178    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8179     && ix86_match_ccmode (insn,
8180                          CONST_INT_P (operands[1])
8181                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8182 {
8183   if (which_alternative == 3)
8184     {
8185       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8186         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8187       return "test{l}\t{%1, %k0|%k0, %1}";
8188     }
8189   return "test{b}\t{%1, %0|%0, %1}";
8190 }
8191   [(set_attr "type" "test")
8192    (set_attr "modrm" "0,1,1,1")
8193    (set_attr "mode" "QI,QI,QI,SI")
8194    (set_attr "pent_pair" "uv,np,uv,np")])
8195
8196 (define_insn "*testqi_1"
8197   [(set (reg FLAGS_REG)
8198         (compare
8199           (and:QI
8200             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8201             (match_operand:QI 1 "general_operand" "n,n,qn"))
8202           (const_int 0)))]
8203   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8204    && ix86_match_ccmode (insn, CCNOmode)"
8205   "test{b}\t{%1, %0|%0, %1}"
8206   [(set_attr "type" "test")
8207    (set_attr "modrm" "0,1,1")
8208    (set_attr "mode" "QI")
8209    (set_attr "pent_pair" "uv,np,uv")])
8210
8211 (define_expand "testqi_ext_ccno_0"
8212   [(set (reg:CCNO FLAGS_REG)
8213         (compare:CCNO
8214           (and:SI
8215             (zero_extract:SI
8216               (match_operand 0 "ext_register_operand" "")
8217               (const_int 8)
8218               (const_int 8))
8219             (match_operand 1 "const_int_operand" ""))
8220           (const_int 0)))]
8221   ""
8222   "")
8223
8224 (define_insn "*testqi_ext_0"
8225   [(set (reg FLAGS_REG)
8226         (compare
8227           (and:SI
8228             (zero_extract:SI
8229               (match_operand 0 "ext_register_operand" "Q")
8230               (const_int 8)
8231               (const_int 8))
8232             (match_operand 1 "const_int_operand" "n"))
8233           (const_int 0)))]
8234   "ix86_match_ccmode (insn, CCNOmode)"
8235   "test{b}\t{%1, %h0|%h0, %1}"
8236   [(set_attr "type" "test")
8237    (set_attr "mode" "QI")
8238    (set_attr "length_immediate" "1")
8239    (set_attr "modrm" "1")
8240    (set_attr "pent_pair" "np")])
8241
8242 (define_insn "*testqi_ext_1"
8243   [(set (reg FLAGS_REG)
8244         (compare
8245           (and:SI
8246             (zero_extract:SI
8247               (match_operand 0 "ext_register_operand" "Q")
8248               (const_int 8)
8249               (const_int 8))
8250             (zero_extend:SI
8251               (match_operand:QI 1 "general_operand" "Qm")))
8252           (const_int 0)))]
8253   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8254    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8255   "test{b}\t{%1, %h0|%h0, %1}"
8256   [(set_attr "type" "test")
8257    (set_attr "mode" "QI")])
8258
8259 (define_insn "*testqi_ext_1_rex64"
8260   [(set (reg FLAGS_REG)
8261         (compare
8262           (and:SI
8263             (zero_extract:SI
8264               (match_operand 0 "ext_register_operand" "Q")
8265               (const_int 8)
8266               (const_int 8))
8267             (zero_extend:SI
8268               (match_operand:QI 1 "register_operand" "Q")))
8269           (const_int 0)))]
8270   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8271   "test{b}\t{%1, %h0|%h0, %1}"
8272   [(set_attr "type" "test")
8273    (set_attr "mode" "QI")])
8274
8275 (define_insn "*testqi_ext_2"
8276   [(set (reg FLAGS_REG)
8277         (compare
8278           (and:SI
8279             (zero_extract:SI
8280               (match_operand 0 "ext_register_operand" "Q")
8281               (const_int 8)
8282               (const_int 8))
8283             (zero_extract:SI
8284               (match_operand 1 "ext_register_operand" "Q")
8285               (const_int 8)
8286               (const_int 8)))
8287           (const_int 0)))]
8288   "ix86_match_ccmode (insn, CCNOmode)"
8289   "test{b}\t{%h1, %h0|%h0, %h1}"
8290   [(set_attr "type" "test")
8291    (set_attr "mode" "QI")])
8292
8293 ;; Combine likes to form bit extractions for some tests.  Humor it.
8294 (define_insn "*testqi_ext_3"
8295   [(set (reg FLAGS_REG)
8296         (compare (zero_extract:SI
8297                    (match_operand 0 "nonimmediate_operand" "rm")
8298                    (match_operand:SI 1 "const_int_operand" "")
8299                    (match_operand:SI 2 "const_int_operand" ""))
8300                  (const_int 0)))]
8301   "ix86_match_ccmode (insn, CCNOmode)
8302    && INTVAL (operands[1]) > 0
8303    && INTVAL (operands[2]) >= 0
8304    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8305    && (GET_MODE (operands[0]) == SImode
8306        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8307        || GET_MODE (operands[0]) == HImode
8308        || GET_MODE (operands[0]) == QImode)"
8309   "#")
8310
8311 (define_insn "*testqi_ext_3_rex64"
8312   [(set (reg FLAGS_REG)
8313         (compare (zero_extract:DI
8314                    (match_operand 0 "nonimmediate_operand" "rm")
8315                    (match_operand:DI 1 "const_int_operand" "")
8316                    (match_operand:DI 2 "const_int_operand" ""))
8317                  (const_int 0)))]
8318   "TARGET_64BIT
8319    && ix86_match_ccmode (insn, CCNOmode)
8320    && INTVAL (operands[1]) > 0
8321    && INTVAL (operands[2]) >= 0
8322    /* Ensure that resulting mask is zero or sign extended operand.  */
8323    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8324        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8325            && INTVAL (operands[1]) > 32))
8326    && (GET_MODE (operands[0]) == SImode
8327        || GET_MODE (operands[0]) == DImode
8328        || GET_MODE (operands[0]) == HImode
8329        || GET_MODE (operands[0]) == QImode)"
8330   "#")
8331
8332 (define_split
8333   [(set (match_operand 0 "flags_reg_operand" "")
8334         (match_operator 1 "compare_operator"
8335           [(zero_extract
8336              (match_operand 2 "nonimmediate_operand" "")
8337              (match_operand 3 "const_int_operand" "")
8338              (match_operand 4 "const_int_operand" ""))
8339            (const_int 0)]))]
8340   "ix86_match_ccmode (insn, CCNOmode)"
8341   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8342 {
8343   rtx val = operands[2];
8344   HOST_WIDE_INT len = INTVAL (operands[3]);
8345   HOST_WIDE_INT pos = INTVAL (operands[4]);
8346   HOST_WIDE_INT mask;
8347   enum machine_mode mode, submode;
8348
8349   mode = GET_MODE (val);
8350   if (MEM_P (val))
8351     {
8352       /* ??? Combine likes to put non-volatile mem extractions in QImode
8353          no matter the size of the test.  So find a mode that works.  */
8354       if (! MEM_VOLATILE_P (val))
8355         {
8356           mode = smallest_mode_for_size (pos + len, MODE_INT);
8357           val = adjust_address (val, mode, 0);
8358         }
8359     }
8360   else if (GET_CODE (val) == SUBREG
8361            && (submode = GET_MODE (SUBREG_REG (val)),
8362                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8363            && pos + len <= GET_MODE_BITSIZE (submode)
8364            && GET_MODE_CLASS (submode) == MODE_INT)
8365     {
8366       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8367       mode = submode;
8368       val = SUBREG_REG (val);
8369     }
8370   else if (mode == HImode && pos + len <= 8)
8371     {
8372       /* Small HImode tests can be converted to QImode.  */
8373       mode = QImode;
8374       val = gen_lowpart (QImode, val);
8375     }
8376
8377   if (len == HOST_BITS_PER_WIDE_INT)
8378     mask = -1;
8379   else
8380     mask = ((HOST_WIDE_INT)1 << len) - 1;
8381   mask <<= pos;
8382
8383   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8384 })
8385
8386 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8387 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8388 ;; this is relatively important trick.
8389 ;; Do the conversion only post-reload to avoid limiting of the register class
8390 ;; to QI regs.
8391 (define_split
8392   [(set (match_operand 0 "flags_reg_operand" "")
8393         (match_operator 1 "compare_operator"
8394           [(and (match_operand 2 "register_operand" "")
8395                 (match_operand 3 "const_int_operand" ""))
8396            (const_int 0)]))]
8397    "reload_completed
8398     && QI_REG_P (operands[2])
8399     && GET_MODE (operands[2]) != QImode
8400     && ((ix86_match_ccmode (insn, CCZmode)
8401          && !(INTVAL (operands[3]) & ~(255 << 8)))
8402         || (ix86_match_ccmode (insn, CCNOmode)
8403             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8404   [(set (match_dup 0)
8405         (match_op_dup 1
8406           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8407                    (match_dup 3))
8408            (const_int 0)]))]
8409   "operands[2] = gen_lowpart (SImode, operands[2]);
8410    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8411
8412 (define_split
8413   [(set (match_operand 0 "flags_reg_operand" "")
8414         (match_operator 1 "compare_operator"
8415           [(and (match_operand 2 "nonimmediate_operand" "")
8416                 (match_operand 3 "const_int_operand" ""))
8417            (const_int 0)]))]
8418    "reload_completed
8419     && GET_MODE (operands[2]) != QImode
8420     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8421     && ((ix86_match_ccmode (insn, CCZmode)
8422          && !(INTVAL (operands[3]) & ~255))
8423         || (ix86_match_ccmode (insn, CCNOmode)
8424             && !(INTVAL (operands[3]) & ~127)))"
8425   [(set (match_dup 0)
8426         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8427                          (const_int 0)]))]
8428   "operands[2] = gen_lowpart (QImode, operands[2]);
8429    operands[3] = gen_lowpart (QImode, operands[3]);")
8430
8431
8432 ;; %%% This used to optimize known byte-wide and operations to memory,
8433 ;; and sometimes to QImode registers.  If this is considered useful,
8434 ;; it should be done with splitters.
8435
8436 (define_expand "anddi3"
8437   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8438         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8439                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8440   "TARGET_64BIT"
8441   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8442
8443 (define_insn "*anddi_1_rex64"
8444   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8445         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8446                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8449 {
8450   switch (get_attr_type (insn))
8451     {
8452     case TYPE_IMOVX:
8453       {
8454         enum machine_mode mode;
8455
8456         gcc_assert (CONST_INT_P (operands[2]));
8457         if (INTVAL (operands[2]) == 0xff)
8458           mode = QImode;
8459         else
8460           {
8461             gcc_assert (INTVAL (operands[2]) == 0xffff);
8462             mode = HImode;
8463           }
8464
8465         operands[1] = gen_lowpart (mode, operands[1]);
8466         if (mode == QImode)
8467           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8468         else
8469           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8470       }
8471
8472     default:
8473       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8474       if (get_attr_mode (insn) == MODE_SI)
8475         return "and{l}\t{%k2, %k0|%k0, %k2}";
8476       else
8477         return "and{q}\t{%2, %0|%0, %2}";
8478     }
8479 }
8480   [(set_attr "type" "alu,alu,alu,imovx")
8481    (set_attr "length_immediate" "*,*,*,0")
8482    (set (attr "prefix_rex")
8483      (if_then_else
8484        (and (eq_attr "type" "imovx")
8485             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8486                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8487        (const_string "1")
8488        (const_string "*")))
8489    (set_attr "mode" "SI,DI,DI,SI")])
8490
8491 (define_insn "*anddi_2"
8492   [(set (reg FLAGS_REG)
8493         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8494                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8495                  (const_int 0)))
8496    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8497         (and:DI (match_dup 1) (match_dup 2)))]
8498   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8499    && ix86_binary_operator_ok (AND, DImode, operands)"
8500   "@
8501    and{l}\t{%k2, %k0|%k0, %k2}
8502    and{q}\t{%2, %0|%0, %2}
8503    and{q}\t{%2, %0|%0, %2}"
8504   [(set_attr "type" "alu")
8505    (set_attr "mode" "SI,DI,DI")])
8506
8507 (define_expand "andsi3"
8508   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8509         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8510                 (match_operand:SI 2 "general_operand" "")))]
8511   ""
8512   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8513
8514 (define_insn "*andsi_1"
8515   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8516         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8517                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8518    (clobber (reg:CC FLAGS_REG))]
8519   "ix86_binary_operator_ok (AND, SImode, operands)"
8520 {
8521   switch (get_attr_type (insn))
8522     {
8523     case TYPE_IMOVX:
8524       {
8525         enum machine_mode mode;
8526
8527         gcc_assert (CONST_INT_P (operands[2]));
8528         if (INTVAL (operands[2]) == 0xff)
8529           mode = QImode;
8530         else
8531           {
8532             gcc_assert (INTVAL (operands[2]) == 0xffff);
8533             mode = HImode;
8534           }
8535
8536         operands[1] = gen_lowpart (mode, operands[1]);
8537         if (mode == QImode)
8538           return "movz{bl|x}\t{%1, %0|%0, %1}";
8539         else
8540           return "movz{wl|x}\t{%1, %0|%0, %1}";
8541       }
8542
8543     default:
8544       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8545       return "and{l}\t{%2, %0|%0, %2}";
8546     }
8547 }
8548   [(set_attr "type" "alu,alu,imovx")
8549    (set (attr "prefix_rex")
8550      (if_then_else
8551        (and (eq_attr "type" "imovx")
8552             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8553                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8554        (const_string "1")
8555        (const_string "*")))
8556    (set_attr "length_immediate" "*,*,0")
8557    (set_attr "mode" "SI")])
8558
8559 (define_split
8560   [(set (match_operand 0 "register_operand" "")
8561         (and (match_dup 0)
8562              (const_int -65536)))
8563    (clobber (reg:CC FLAGS_REG))]
8564   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8565   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8566   "operands[1] = gen_lowpart (HImode, operands[0]);")
8567
8568 (define_split
8569   [(set (match_operand 0 "ext_register_operand" "")
8570         (and (match_dup 0)
8571              (const_int -256)))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8574   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8575   "operands[1] = gen_lowpart (QImode, operands[0]);")
8576
8577 (define_split
8578   [(set (match_operand 0 "ext_register_operand" "")
8579         (and (match_dup 0)
8580              (const_int -65281)))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8583   [(parallel [(set (zero_extract:SI (match_dup 0)
8584                                     (const_int 8)
8585                                     (const_int 8))
8586                    (xor:SI
8587                      (zero_extract:SI (match_dup 0)
8588                                       (const_int 8)
8589                                       (const_int 8))
8590                      (zero_extract:SI (match_dup 0)
8591                                       (const_int 8)
8592                                       (const_int 8))))
8593               (clobber (reg:CC FLAGS_REG))])]
8594   "operands[0] = gen_lowpart (SImode, operands[0]);")
8595
8596 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8597 (define_insn "*andsi_1_zext"
8598   [(set (match_operand:DI 0 "register_operand" "=r")
8599         (zero_extend:DI
8600           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8601                   (match_operand:SI 2 "general_operand" "g"))))
8602    (clobber (reg:CC FLAGS_REG))]
8603   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8604   "and{l}\t{%2, %k0|%k0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "SI")])
8607
8608 (define_insn "*andsi_2"
8609   [(set (reg FLAGS_REG)
8610         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8611                          (match_operand:SI 2 "general_operand" "g,ri"))
8612                  (const_int 0)))
8613    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8614         (and:SI (match_dup 1) (match_dup 2)))]
8615   "ix86_match_ccmode (insn, CCNOmode)
8616    && ix86_binary_operator_ok (AND, SImode, operands)"
8617   "and{l}\t{%2, %0|%0, %2}"
8618   [(set_attr "type" "alu")
8619    (set_attr "mode" "SI")])
8620
8621 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8622 (define_insn "*andsi_2_zext"
8623   [(set (reg FLAGS_REG)
8624         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8625                          (match_operand:SI 2 "general_operand" "g"))
8626                  (const_int 0)))
8627    (set (match_operand:DI 0 "register_operand" "=r")
8628         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8629   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8630    && ix86_binary_operator_ok (AND, SImode, operands)"
8631   "and{l}\t{%2, %k0|%k0, %2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "SI")])
8634
8635 (define_expand "andhi3"
8636   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8637         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8638                 (match_operand:HI 2 "general_operand" "")))]
8639   "TARGET_HIMODE_MATH"
8640   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8641
8642 (define_insn "*andhi_1"
8643   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8644         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8645                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8646    (clobber (reg:CC FLAGS_REG))]
8647   "ix86_binary_operator_ok (AND, HImode, operands)"
8648 {
8649   switch (get_attr_type (insn))
8650     {
8651     case TYPE_IMOVX:
8652       gcc_assert (CONST_INT_P (operands[2]));
8653       gcc_assert (INTVAL (operands[2]) == 0xff);
8654       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8655
8656     default:
8657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8658
8659       return "and{w}\t{%2, %0|%0, %2}";
8660     }
8661 }
8662   [(set_attr "type" "alu,alu,imovx")
8663    (set_attr "length_immediate" "*,*,0")
8664    (set (attr "prefix_rex")
8665      (if_then_else
8666        (and (eq_attr "type" "imovx")
8667             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8668        (const_string "1")
8669        (const_string "*")))
8670    (set_attr "mode" "HI,HI,SI")])
8671
8672 (define_insn "*andhi_2"
8673   [(set (reg FLAGS_REG)
8674         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8675                          (match_operand:HI 2 "general_operand" "rmn,rn"))
8676                  (const_int 0)))
8677    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8678         (and:HI (match_dup 1) (match_dup 2)))]
8679   "ix86_match_ccmode (insn, CCNOmode)
8680    && ix86_binary_operator_ok (AND, HImode, operands)"
8681   "and{w}\t{%2, %0|%0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "mode" "HI")])
8684
8685 (define_expand "andqi3"
8686   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8687         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8688                 (match_operand:QI 2 "general_operand" "")))]
8689   "TARGET_QIMODE_MATH"
8690   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8691
8692 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8693 (define_insn "*andqi_1"
8694   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8695         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8696                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8697    (clobber (reg:CC FLAGS_REG))]
8698   "ix86_binary_operator_ok (AND, QImode, operands)"
8699   "@
8700    and{b}\t{%2, %0|%0, %2}
8701    and{b}\t{%2, %0|%0, %2}
8702    and{l}\t{%k2, %k0|%k0, %k2}"
8703   [(set_attr "type" "alu")
8704    (set_attr "mode" "QI,QI,SI")])
8705
8706 (define_insn "*andqi_1_slp"
8707   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8708         (and:QI (match_dup 0)
8709                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8710    (clobber (reg:CC FLAGS_REG))]
8711   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8712    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8713   "and{b}\t{%1, %0|%0, %1}"
8714   [(set_attr "type" "alu1")
8715    (set_attr "mode" "QI")])
8716
8717 (define_insn "*andqi_2_maybe_si"
8718   [(set (reg FLAGS_REG)
8719         (compare (and:QI
8720                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8721                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8722                  (const_int 0)))
8723    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8724         (and:QI (match_dup 1) (match_dup 2)))]
8725   "ix86_binary_operator_ok (AND, QImode, operands)
8726    && ix86_match_ccmode (insn,
8727                          CONST_INT_P (operands[2])
8728                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8729 {
8730   if (which_alternative == 2)
8731     {
8732       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8733         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8734       return "and{l}\t{%2, %k0|%k0, %2}";
8735     }
8736   return "and{b}\t{%2, %0|%0, %2}";
8737 }
8738   [(set_attr "type" "alu")
8739    (set_attr "mode" "QI,QI,SI")])
8740
8741 (define_insn "*andqi_2"
8742   [(set (reg FLAGS_REG)
8743         (compare (and:QI
8744                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8745                    (match_operand:QI 2 "general_operand" "qmn,qn"))
8746                  (const_int 0)))
8747    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8748         (and:QI (match_dup 1) (match_dup 2)))]
8749   "ix86_match_ccmode (insn, CCNOmode)
8750    && ix86_binary_operator_ok (AND, QImode, operands)"
8751   "and{b}\t{%2, %0|%0, %2}"
8752   [(set_attr "type" "alu")
8753    (set_attr "mode" "QI")])
8754
8755 (define_insn "*andqi_2_slp"
8756   [(set (reg FLAGS_REG)
8757         (compare (and:QI
8758                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8759                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8760                  (const_int 0)))
8761    (set (strict_low_part (match_dup 0))
8762         (and:QI (match_dup 0) (match_dup 1)))]
8763   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8764    && ix86_match_ccmode (insn, CCNOmode)
8765    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8766   "and{b}\t{%1, %0|%0, %1}"
8767   [(set_attr "type" "alu1")
8768    (set_attr "mode" "QI")])
8769
8770 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8771 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8772 ;; for a QImode operand, which of course failed.
8773
8774 (define_insn "andqi_ext_0"
8775   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8776                          (const_int 8)
8777                          (const_int 8))
8778         (and:SI
8779           (zero_extract:SI
8780             (match_operand 1 "ext_register_operand" "0")
8781             (const_int 8)
8782             (const_int 8))
8783           (match_operand 2 "const_int_operand" "n")))
8784    (clobber (reg:CC FLAGS_REG))]
8785   ""
8786   "and{b}\t{%2, %h0|%h0, %2}"
8787   [(set_attr "type" "alu")
8788    (set_attr "length_immediate" "1")
8789    (set_attr "modrm" "1")
8790    (set_attr "mode" "QI")])
8791
8792 ;; Generated by peephole translating test to and.  This shows up
8793 ;; often in fp comparisons.
8794
8795 (define_insn "*andqi_ext_0_cc"
8796   [(set (reg FLAGS_REG)
8797         (compare
8798           (and:SI
8799             (zero_extract:SI
8800               (match_operand 1 "ext_register_operand" "0")
8801               (const_int 8)
8802               (const_int 8))
8803             (match_operand 2 "const_int_operand" "n"))
8804           (const_int 0)))
8805    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8806                          (const_int 8)
8807                          (const_int 8))
8808         (and:SI
8809           (zero_extract:SI
8810             (match_dup 1)
8811             (const_int 8)
8812             (const_int 8))
8813           (match_dup 2)))]
8814   "ix86_match_ccmode (insn, CCNOmode)"
8815   "and{b}\t{%2, %h0|%h0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "length_immediate" "1")
8818    (set_attr "modrm" "1")
8819    (set_attr "mode" "QI")])
8820
8821 (define_insn "*andqi_ext_1"
8822   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8823                          (const_int 8)
8824                          (const_int 8))
8825         (and:SI
8826           (zero_extract:SI
8827             (match_operand 1 "ext_register_operand" "0")
8828             (const_int 8)
8829             (const_int 8))
8830           (zero_extend:SI
8831             (match_operand:QI 2 "general_operand" "Qm"))))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "!TARGET_64BIT"
8834   "and{b}\t{%2, %h0|%h0, %2}"
8835   [(set_attr "type" "alu")
8836    (set_attr "length_immediate" "0")
8837    (set_attr "mode" "QI")])
8838
8839 (define_insn "*andqi_ext_1_rex64"
8840   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8841                          (const_int 8)
8842                          (const_int 8))
8843         (and:SI
8844           (zero_extract:SI
8845             (match_operand 1 "ext_register_operand" "0")
8846             (const_int 8)
8847             (const_int 8))
8848           (zero_extend:SI
8849             (match_operand 2 "ext_register_operand" "Q"))))
8850    (clobber (reg:CC FLAGS_REG))]
8851   "TARGET_64BIT"
8852   "and{b}\t{%2, %h0|%h0, %2}"
8853   [(set_attr "type" "alu")
8854    (set_attr "length_immediate" "0")
8855    (set_attr "mode" "QI")])
8856
8857 (define_insn "*andqi_ext_2"
8858   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8859                          (const_int 8)
8860                          (const_int 8))
8861         (and:SI
8862           (zero_extract:SI
8863             (match_operand 1 "ext_register_operand" "%0")
8864             (const_int 8)
8865             (const_int 8))
8866           (zero_extract:SI
8867             (match_operand 2 "ext_register_operand" "Q")
8868             (const_int 8)
8869             (const_int 8))))
8870    (clobber (reg:CC FLAGS_REG))]
8871   ""
8872   "and{b}\t{%h2, %h0|%h0, %h2}"
8873   [(set_attr "type" "alu")
8874    (set_attr "length_immediate" "0")
8875    (set_attr "mode" "QI")])
8876
8877 ;; Convert wide AND instructions with immediate operand to shorter QImode
8878 ;; equivalents when possible.
8879 ;; Don't do the splitting with memory operands, since it introduces risk
8880 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8881 ;; for size, but that can (should?) be handled by generic code instead.
8882 (define_split
8883   [(set (match_operand 0 "register_operand" "")
8884         (and (match_operand 1 "register_operand" "")
8885              (match_operand 2 "const_int_operand" "")))
8886    (clobber (reg:CC FLAGS_REG))]
8887    "reload_completed
8888     && QI_REG_P (operands[0])
8889     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8890     && !(~INTVAL (operands[2]) & ~(255 << 8))
8891     && GET_MODE (operands[0]) != QImode"
8892   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8893                    (and:SI (zero_extract:SI (match_dup 1)
8894                                             (const_int 8) (const_int 8))
8895                            (match_dup 2)))
8896               (clobber (reg:CC FLAGS_REG))])]
8897   "operands[0] = gen_lowpart (SImode, operands[0]);
8898    operands[1] = gen_lowpart (SImode, operands[1]);
8899    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8900
8901 ;; Since AND can be encoded with sign extended immediate, this is only
8902 ;; profitable when 7th bit is not set.
8903 (define_split
8904   [(set (match_operand 0 "register_operand" "")
8905         (and (match_operand 1 "general_operand" "")
8906              (match_operand 2 "const_int_operand" "")))
8907    (clobber (reg:CC FLAGS_REG))]
8908    "reload_completed
8909     && ANY_QI_REG_P (operands[0])
8910     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8911     && !(~INTVAL (operands[2]) & ~255)
8912     && !(INTVAL (operands[2]) & 128)
8913     && GET_MODE (operands[0]) != QImode"
8914   [(parallel [(set (strict_low_part (match_dup 0))
8915                    (and:QI (match_dup 1)
8916                            (match_dup 2)))
8917               (clobber (reg:CC FLAGS_REG))])]
8918   "operands[0] = gen_lowpart (QImode, operands[0]);
8919    operands[1] = gen_lowpart (QImode, operands[1]);
8920    operands[2] = gen_lowpart (QImode, operands[2]);")
8921 \f
8922 ;; Logical inclusive OR instructions
8923
8924 ;; %%% This used to optimize known byte-wide and operations to memory.
8925 ;; If this is considered useful, it should be done with splitters.
8926
8927 (define_expand "iordi3"
8928   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8929         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8930                 (match_operand:DI 2 "x86_64_general_operand" "")))]
8931   "TARGET_64BIT"
8932   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8933
8934 (define_insn "*iordi_1_rex64"
8935   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8936         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8937                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8938    (clobber (reg:CC FLAGS_REG))]
8939   "TARGET_64BIT
8940    && ix86_binary_operator_ok (IOR, DImode, operands)"
8941   "or{q}\t{%2, %0|%0, %2}"
8942   [(set_attr "type" "alu")
8943    (set_attr "mode" "DI")])
8944
8945 (define_insn "*iordi_2_rex64"
8946   [(set (reg FLAGS_REG)
8947         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8949                  (const_int 0)))
8950    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8951         (ior:DI (match_dup 1) (match_dup 2)))]
8952   "TARGET_64BIT
8953    && ix86_match_ccmode (insn, CCNOmode)
8954    && ix86_binary_operator_ok (IOR, DImode, operands)"
8955   "or{q}\t{%2, %0|%0, %2}"
8956   [(set_attr "type" "alu")
8957    (set_attr "mode" "DI")])
8958
8959 (define_insn "*iordi_3_rex64"
8960   [(set (reg FLAGS_REG)
8961         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8962                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8963                  (const_int 0)))
8964    (clobber (match_scratch:DI 0 "=r"))]
8965   "TARGET_64BIT
8966    && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (IOR, DImode, operands)"
8968   "or{q}\t{%2, %0|%0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "DI")])
8971
8972
8973 (define_expand "iorsi3"
8974   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8975         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8976                 (match_operand:SI 2 "general_operand" "")))]
8977   ""
8978   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8979
8980 (define_insn "*iorsi_1"
8981   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8982         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8983                 (match_operand:SI 2 "general_operand" "ri,g")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "ix86_binary_operator_ok (IOR, SImode, operands)"
8986   "or{l}\t{%2, %0|%0, %2}"
8987   [(set_attr "type" "alu")
8988    (set_attr "mode" "SI")])
8989
8990 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8991 (define_insn "*iorsi_1_zext"
8992   [(set (match_operand:DI 0 "register_operand" "=r")
8993         (zero_extend:DI
8994           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8995                   (match_operand:SI 2 "general_operand" "g"))))
8996    (clobber (reg:CC FLAGS_REG))]
8997   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8998   "or{l}\t{%2, %k0|%k0, %2}"
8999   [(set_attr "type" "alu")
9000    (set_attr "mode" "SI")])
9001
9002 (define_insn "*iorsi_1_zext_imm"
9003   [(set (match_operand:DI 0 "register_operand" "=r")
9004         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9005                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "TARGET_64BIT"
9008   "or{l}\t{%2, %k0|%k0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "SI")])
9011
9012 (define_insn "*iorsi_2"
9013   [(set (reg FLAGS_REG)
9014         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9015                          (match_operand:SI 2 "general_operand" "g,ri"))
9016                  (const_int 0)))
9017    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9018         (ior:SI (match_dup 1) (match_dup 2)))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && ix86_binary_operator_ok (IOR, SImode, operands)"
9021   "or{l}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "SI")])
9024
9025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9026 ;; ??? Special case for immediate operand is missing - it is tricky.
9027 (define_insn "*iorsi_2_zext"
9028   [(set (reg FLAGS_REG)
9029         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9030                          (match_operand:SI 2 "general_operand" "g"))
9031                  (const_int 0)))
9032    (set (match_operand:DI 0 "register_operand" "=r")
9033         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9034   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9035    && ix86_binary_operator_ok (IOR, SImode, operands)"
9036   "or{l}\t{%2, %k0|%k0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "SI")])
9039
9040 (define_insn "*iorsi_2_zext_imm"
9041   [(set (reg FLAGS_REG)
9042         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9043                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9044                  (const_int 0)))
9045    (set (match_operand:DI 0 "register_operand" "=r")
9046         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9047   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9048    && ix86_binary_operator_ok (IOR, SImode, operands)"
9049   "or{l}\t{%2, %k0|%k0, %2}"
9050   [(set_attr "type" "alu")
9051    (set_attr "mode" "SI")])
9052
9053 (define_insn "*iorsi_3"
9054   [(set (reg FLAGS_REG)
9055         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9056                          (match_operand:SI 2 "general_operand" "g"))
9057                  (const_int 0)))
9058    (clobber (match_scratch:SI 0 "=r"))]
9059   "ix86_match_ccmode (insn, CCNOmode)
9060    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9061   "or{l}\t{%2, %0|%0, %2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "mode" "SI")])
9064
9065 (define_expand "iorhi3"
9066   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9067         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9068                 (match_operand:HI 2 "general_operand" "")))]
9069   "TARGET_HIMODE_MATH"
9070   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9071
9072 (define_insn "*iorhi_1"
9073   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9074         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9075                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9076    (clobber (reg:CC FLAGS_REG))]
9077   "ix86_binary_operator_ok (IOR, HImode, operands)"
9078   "or{w}\t{%2, %0|%0, %2}"
9079   [(set_attr "type" "alu")
9080    (set_attr "mode" "HI")])
9081
9082 (define_insn "*iorhi_2"
9083   [(set (reg FLAGS_REG)
9084         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9085                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9086                  (const_int 0)))
9087    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9088         (ior:HI (match_dup 1) (match_dup 2)))]
9089   "ix86_match_ccmode (insn, CCNOmode)
9090    && ix86_binary_operator_ok (IOR, HImode, operands)"
9091   "or{w}\t{%2, %0|%0, %2}"
9092   [(set_attr "type" "alu")
9093    (set_attr "mode" "HI")])
9094
9095 (define_insn "*iorhi_3"
9096   [(set (reg FLAGS_REG)
9097         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9098                          (match_operand:HI 2 "general_operand" "rmn"))
9099                  (const_int 0)))
9100    (clobber (match_scratch:HI 0 "=r"))]
9101   "ix86_match_ccmode (insn, CCNOmode)
9102    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9103   "or{w}\t{%2, %0|%0, %2}"
9104   [(set_attr "type" "alu")
9105    (set_attr "mode" "HI")])
9106
9107 (define_expand "iorqi3"
9108   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9109         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9110                 (match_operand:QI 2 "general_operand" "")))]
9111   "TARGET_QIMODE_MATH"
9112   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9113
9114 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9115 (define_insn "*iorqi_1"
9116   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9117         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "ix86_binary_operator_ok (IOR, QImode, operands)"
9121   "@
9122    or{b}\t{%2, %0|%0, %2}
9123    or{b}\t{%2, %0|%0, %2}
9124    or{l}\t{%k2, %k0|%k0, %k2}"
9125   [(set_attr "type" "alu")
9126    (set_attr "mode" "QI,QI,SI")])
9127
9128 (define_insn "*iorqi_1_slp"
9129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9130         (ior:QI (match_dup 0)
9131                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9132    (clobber (reg:CC FLAGS_REG))]
9133   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9134    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9135   "or{b}\t{%1, %0|%0, %1}"
9136   [(set_attr "type" "alu1")
9137    (set_attr "mode" "QI")])
9138
9139 (define_insn "*iorqi_2"
9140   [(set (reg FLAGS_REG)
9141         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9142                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9143                  (const_int 0)))
9144    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9145         (ior:QI (match_dup 1) (match_dup 2)))]
9146   "ix86_match_ccmode (insn, CCNOmode)
9147    && ix86_binary_operator_ok (IOR, QImode, operands)"
9148   "or{b}\t{%2, %0|%0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "mode" "QI")])
9151
9152 (define_insn "*iorqi_2_slp"
9153   [(set (reg FLAGS_REG)
9154         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9155                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9156                  (const_int 0)))
9157    (set (strict_low_part (match_dup 0))
9158         (ior:QI (match_dup 0) (match_dup 1)))]
9159   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9160    && ix86_match_ccmode (insn, CCNOmode)
9161    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9162   "or{b}\t{%1, %0|%0, %1}"
9163   [(set_attr "type" "alu1")
9164    (set_attr "mode" "QI")])
9165
9166 (define_insn "*iorqi_3"
9167   [(set (reg FLAGS_REG)
9168         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9169                          (match_operand:QI 2 "general_operand" "qmn"))
9170                  (const_int 0)))
9171    (clobber (match_scratch:QI 0 "=q"))]
9172   "ix86_match_ccmode (insn, CCNOmode)
9173    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9174   "or{b}\t{%2, %0|%0, %2}"
9175   [(set_attr "type" "alu")
9176    (set_attr "mode" "QI")])
9177
9178 (define_insn "*iorqi_ext_0"
9179   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9180                          (const_int 8)
9181                          (const_int 8))
9182         (ior:SI
9183           (zero_extract:SI
9184             (match_operand 1 "ext_register_operand" "0")
9185             (const_int 8)
9186             (const_int 8))
9187           (match_operand 2 "const_int_operand" "n")))
9188    (clobber (reg:CC FLAGS_REG))]
9189   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9190   "or{b}\t{%2, %h0|%h0, %2}"
9191   [(set_attr "type" "alu")
9192    (set_attr "length_immediate" "1")
9193    (set_attr "modrm" "1")
9194    (set_attr "mode" "QI")])
9195
9196 (define_insn "*iorqi_ext_1"
9197   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9198                          (const_int 8)
9199                          (const_int 8))
9200         (ior:SI
9201           (zero_extract:SI
9202             (match_operand 1 "ext_register_operand" "0")
9203             (const_int 8)
9204             (const_int 8))
9205           (zero_extend:SI
9206             (match_operand:QI 2 "general_operand" "Qm"))))
9207    (clobber (reg:CC FLAGS_REG))]
9208   "!TARGET_64BIT
9209    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9210   "or{b}\t{%2, %h0|%h0, %2}"
9211   [(set_attr "type" "alu")
9212    (set_attr "length_immediate" "0")
9213    (set_attr "mode" "QI")])
9214
9215 (define_insn "*iorqi_ext_1_rex64"
9216   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9217                          (const_int 8)
9218                          (const_int 8))
9219         (ior:SI
9220           (zero_extract:SI
9221             (match_operand 1 "ext_register_operand" "0")
9222             (const_int 8)
9223             (const_int 8))
9224           (zero_extend:SI
9225             (match_operand 2 "ext_register_operand" "Q"))))
9226    (clobber (reg:CC FLAGS_REG))]
9227   "TARGET_64BIT
9228    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9229   "or{b}\t{%2, %h0|%h0, %2}"
9230   [(set_attr "type" "alu")
9231    (set_attr "length_immediate" "0")
9232    (set_attr "mode" "QI")])
9233
9234 (define_insn "*iorqi_ext_2"
9235   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236                          (const_int 8)
9237                          (const_int 8))
9238         (ior:SI
9239           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9240                            (const_int 8)
9241                            (const_int 8))
9242           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9243                            (const_int 8)
9244                            (const_int 8))))
9245    (clobber (reg:CC FLAGS_REG))]
9246   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9247   "ior{b}\t{%h2, %h0|%h0, %h2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "length_immediate" "0")
9250    (set_attr "mode" "QI")])
9251
9252 (define_split
9253   [(set (match_operand 0 "register_operand" "")
9254         (ior (match_operand 1 "register_operand" "")
9255              (match_operand 2 "const_int_operand" "")))
9256    (clobber (reg:CC FLAGS_REG))]
9257    "reload_completed
9258     && QI_REG_P (operands[0])
9259     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9260     && !(INTVAL (operands[2]) & ~(255 << 8))
9261     && GET_MODE (operands[0]) != QImode"
9262   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9263                    (ior:SI (zero_extract:SI (match_dup 1)
9264                                             (const_int 8) (const_int 8))
9265                            (match_dup 2)))
9266               (clobber (reg:CC FLAGS_REG))])]
9267   "operands[0] = gen_lowpart (SImode, operands[0]);
9268    operands[1] = gen_lowpart (SImode, operands[1]);
9269    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9270
9271 ;; Since OR can be encoded with sign extended immediate, this is only
9272 ;; profitable when 7th bit is set.
9273 (define_split
9274   [(set (match_operand 0 "register_operand" "")
9275         (ior (match_operand 1 "general_operand" "")
9276              (match_operand 2 "const_int_operand" "")))
9277    (clobber (reg:CC FLAGS_REG))]
9278    "reload_completed
9279     && ANY_QI_REG_P (operands[0])
9280     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9281     && !(INTVAL (operands[2]) & ~255)
9282     && (INTVAL (operands[2]) & 128)
9283     && GET_MODE (operands[0]) != QImode"
9284   [(parallel [(set (strict_low_part (match_dup 0))
9285                    (ior:QI (match_dup 1)
9286                            (match_dup 2)))
9287               (clobber (reg:CC FLAGS_REG))])]
9288   "operands[0] = gen_lowpart (QImode, operands[0]);
9289    operands[1] = gen_lowpart (QImode, operands[1]);
9290    operands[2] = gen_lowpart (QImode, operands[2]);")
9291 \f
9292 ;; Logical XOR instructions
9293
9294 ;; %%% This used to optimize known byte-wide and operations to memory.
9295 ;; If this is considered useful, it should be done with splitters.
9296
9297 (define_expand "xordi3"
9298   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9299         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9300                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9301   "TARGET_64BIT"
9302   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9303
9304 (define_insn "*xordi_1_rex64"
9305   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9306         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9307                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   "TARGET_64BIT
9310    && ix86_binary_operator_ok (XOR, DImode, operands)"
9311   "xor{q}\t{%2, %0|%0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "DI")])
9314
9315 (define_insn "*xordi_2_rex64"
9316   [(set (reg FLAGS_REG)
9317         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9318                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9319                  (const_int 0)))
9320    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9321         (xor:DI (match_dup 1) (match_dup 2)))]
9322   "TARGET_64BIT
9323    && ix86_match_ccmode (insn, CCNOmode)
9324    && ix86_binary_operator_ok (XOR, DImode, operands)"
9325   "xor{q}\t{%2, %0|%0, %2}"
9326   [(set_attr "type" "alu")
9327    (set_attr "mode" "DI")])
9328
9329 (define_insn "*xordi_3_rex64"
9330   [(set (reg FLAGS_REG)
9331         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9332                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9333                  (const_int 0)))
9334    (clobber (match_scratch:DI 0 "=r"))]
9335   "TARGET_64BIT
9336    && ix86_match_ccmode (insn, CCNOmode)
9337    && ix86_binary_operator_ok (XOR, DImode, operands)"
9338   "xor{q}\t{%2, %0|%0, %2}"
9339   [(set_attr "type" "alu")
9340    (set_attr "mode" "DI")])
9341
9342 (define_expand "xorsi3"
9343   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9344         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9345                 (match_operand:SI 2 "general_operand" "")))]
9346   ""
9347   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9348
9349 (define_insn "*xorsi_1"
9350   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9351         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9352                 (match_operand:SI 2 "general_operand" "ri,rm")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "ix86_binary_operator_ok (XOR, SImode, operands)"
9355   "xor{l}\t{%2, %0|%0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "SI")])
9358
9359 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9360 ;; Add speccase for immediates
9361 (define_insn "*xorsi_1_zext"
9362   [(set (match_operand:DI 0 "register_operand" "=r")
9363         (zero_extend:DI
9364           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9365                   (match_operand:SI 2 "general_operand" "g"))))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9368   "xor{l}\t{%2, %k0|%k0, %2}"
9369   [(set_attr "type" "alu")
9370    (set_attr "mode" "SI")])
9371
9372 (define_insn "*xorsi_1_zext_imm"
9373   [(set (match_operand:DI 0 "register_operand" "=r")
9374         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9375                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9376    (clobber (reg:CC FLAGS_REG))]
9377   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9378   "xor{l}\t{%2, %k0|%k0, %2}"
9379   [(set_attr "type" "alu")
9380    (set_attr "mode" "SI")])
9381
9382 (define_insn "*xorsi_2"
9383   [(set (reg FLAGS_REG)
9384         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9385                          (match_operand:SI 2 "general_operand" "g,ri"))
9386                  (const_int 0)))
9387    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9388         (xor:SI (match_dup 1) (match_dup 2)))]
9389   "ix86_match_ccmode (insn, CCNOmode)
9390    && ix86_binary_operator_ok (XOR, SImode, operands)"
9391   "xor{l}\t{%2, %0|%0, %2}"
9392   [(set_attr "type" "alu")
9393    (set_attr "mode" "SI")])
9394
9395 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9396 ;; ??? Special case for immediate operand is missing - it is tricky.
9397 (define_insn "*xorsi_2_zext"
9398   [(set (reg FLAGS_REG)
9399         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9400                          (match_operand:SI 2 "general_operand" "g"))
9401                  (const_int 0)))
9402    (set (match_operand:DI 0 "register_operand" "=r")
9403         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9404   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9405    && ix86_binary_operator_ok (XOR, SImode, operands)"
9406   "xor{l}\t{%2, %k0|%k0, %2}"
9407   [(set_attr "type" "alu")
9408    (set_attr "mode" "SI")])
9409
9410 (define_insn "*xorsi_2_zext_imm"
9411   [(set (reg FLAGS_REG)
9412         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9413                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9414                  (const_int 0)))
9415    (set (match_operand:DI 0 "register_operand" "=r")
9416         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9417   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9418    && ix86_binary_operator_ok (XOR, SImode, operands)"
9419   "xor{l}\t{%2, %k0|%k0, %2}"
9420   [(set_attr "type" "alu")
9421    (set_attr "mode" "SI")])
9422
9423 (define_insn "*xorsi_3"
9424   [(set (reg FLAGS_REG)
9425         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9426                          (match_operand:SI 2 "general_operand" "g"))
9427                  (const_int 0)))
9428    (clobber (match_scratch:SI 0 "=r"))]
9429   "ix86_match_ccmode (insn, CCNOmode)
9430    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9431   "xor{l}\t{%2, %0|%0, %2}"
9432   [(set_attr "type" "alu")
9433    (set_attr "mode" "SI")])
9434
9435 (define_expand "xorhi3"
9436   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9437         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9438                 (match_operand:HI 2 "general_operand" "")))]
9439   "TARGET_HIMODE_MATH"
9440   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9441
9442 (define_insn "*xorhi_1"
9443   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9444         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9445                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9446    (clobber (reg:CC FLAGS_REG))]
9447   "ix86_binary_operator_ok (XOR, HImode, operands)"
9448   "xor{w}\t{%2, %0|%0, %2}"
9449   [(set_attr "type" "alu")
9450    (set_attr "mode" "HI")])
9451
9452 (define_insn "*xorhi_2"
9453   [(set (reg FLAGS_REG)
9454         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9455                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9456                  (const_int 0)))
9457    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9458         (xor:HI (match_dup 1) (match_dup 2)))]
9459   "ix86_match_ccmode (insn, CCNOmode)
9460    && ix86_binary_operator_ok (XOR, HImode, operands)"
9461   "xor{w}\t{%2, %0|%0, %2}"
9462   [(set_attr "type" "alu")
9463    (set_attr "mode" "HI")])
9464
9465 (define_insn "*xorhi_3"
9466   [(set (reg FLAGS_REG)
9467         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9468                          (match_operand:HI 2 "general_operand" "rmn"))
9469                  (const_int 0)))
9470    (clobber (match_scratch:HI 0 "=r"))]
9471   "ix86_match_ccmode (insn, CCNOmode)
9472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9473   "xor{w}\t{%2, %0|%0, %2}"
9474   [(set_attr "type" "alu")
9475    (set_attr "mode" "HI")])
9476
9477 (define_expand "xorqi3"
9478   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9479         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9480                 (match_operand:QI 2 "general_operand" "")))]
9481   "TARGET_QIMODE_MATH"
9482   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9483
9484 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9485 (define_insn "*xorqi_1"
9486   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9487         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9488                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "ix86_binary_operator_ok (XOR, QImode, operands)"
9491   "@
9492    xor{b}\t{%2, %0|%0, %2}
9493    xor{b}\t{%2, %0|%0, %2}
9494    xor{l}\t{%k2, %k0|%k0, %k2}"
9495   [(set_attr "type" "alu")
9496    (set_attr "mode" "QI,QI,SI")])
9497
9498 (define_insn "*xorqi_1_slp"
9499   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9500         (xor:QI (match_dup 0)
9501                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9504    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9505   "xor{b}\t{%1, %0|%0, %1}"
9506   [(set_attr "type" "alu1")
9507    (set_attr "mode" "QI")])
9508
9509 (define_insn "*xorqi_ext_0"
9510   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9511                          (const_int 8)
9512                          (const_int 8))
9513         (xor:SI
9514           (zero_extract:SI
9515             (match_operand 1 "ext_register_operand" "0")
9516             (const_int 8)
9517             (const_int 8))
9518           (match_operand 2 "const_int_operand" "n")))
9519    (clobber (reg:CC FLAGS_REG))]
9520   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9521   "xor{b}\t{%2, %h0|%h0, %2}"
9522   [(set_attr "type" "alu")
9523    (set_attr "length_immediate" "1")
9524    (set_attr "modrm" "1")
9525    (set_attr "mode" "QI")])
9526
9527 (define_insn "*xorqi_ext_1"
9528   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9529                          (const_int 8)
9530                          (const_int 8))
9531         (xor:SI
9532           (zero_extract:SI
9533             (match_operand 1 "ext_register_operand" "0")
9534             (const_int 8)
9535             (const_int 8))
9536           (zero_extend:SI
9537             (match_operand:QI 2 "general_operand" "Qm"))))
9538    (clobber (reg:CC FLAGS_REG))]
9539   "!TARGET_64BIT
9540    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9541   "xor{b}\t{%2, %h0|%h0, %2}"
9542   [(set_attr "type" "alu")
9543    (set_attr "length_immediate" "0")
9544    (set_attr "mode" "QI")])
9545
9546 (define_insn "*xorqi_ext_1_rex64"
9547   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9548                          (const_int 8)
9549                          (const_int 8))
9550         (xor:SI
9551           (zero_extract:SI
9552             (match_operand 1 "ext_register_operand" "0")
9553             (const_int 8)
9554             (const_int 8))
9555           (zero_extend:SI
9556             (match_operand 2 "ext_register_operand" "Q"))))
9557    (clobber (reg:CC FLAGS_REG))]
9558   "TARGET_64BIT
9559    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9560   "xor{b}\t{%2, %h0|%h0, %2}"
9561   [(set_attr "type" "alu")
9562    (set_attr "length_immediate" "0")
9563    (set_attr "mode" "QI")])
9564
9565 (define_insn "*xorqi_ext_2"
9566   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9567                          (const_int 8)
9568                          (const_int 8))
9569         (xor:SI
9570           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9571                            (const_int 8)
9572                            (const_int 8))
9573           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9574                            (const_int 8)
9575                            (const_int 8))))
9576    (clobber (reg:CC FLAGS_REG))]
9577   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9578   "xor{b}\t{%h2, %h0|%h0, %h2}"
9579   [(set_attr "type" "alu")
9580    (set_attr "length_immediate" "0")
9581    (set_attr "mode" "QI")])
9582
9583 (define_insn "*xorqi_cc_1"
9584   [(set (reg FLAGS_REG)
9585         (compare
9586           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9587                   (match_operand:QI 2 "general_operand" "qmn,qn"))
9588           (const_int 0)))
9589    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9590         (xor:QI (match_dup 1) (match_dup 2)))]
9591   "ix86_match_ccmode (insn, CCNOmode)
9592    && ix86_binary_operator_ok (XOR, QImode, operands)"
9593   "xor{b}\t{%2, %0|%0, %2}"
9594   [(set_attr "type" "alu")
9595    (set_attr "mode" "QI")])
9596
9597 (define_insn "*xorqi_2_slp"
9598   [(set (reg FLAGS_REG)
9599         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9600                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9601                  (const_int 0)))
9602    (set (strict_low_part (match_dup 0))
9603         (xor:QI (match_dup 0) (match_dup 1)))]
9604   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9605    && ix86_match_ccmode (insn, CCNOmode)
9606    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9607   "xor{b}\t{%1, %0|%0, %1}"
9608   [(set_attr "type" "alu1")
9609    (set_attr "mode" "QI")])
9610
9611 (define_insn "*xorqi_cc_2"
9612   [(set (reg FLAGS_REG)
9613         (compare
9614           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9615                   (match_operand:QI 2 "general_operand" "qmn"))
9616           (const_int 0)))
9617    (clobber (match_scratch:QI 0 "=q"))]
9618   "ix86_match_ccmode (insn, CCNOmode)
9619    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9620   "xor{b}\t{%2, %0|%0, %2}"
9621   [(set_attr "type" "alu")
9622    (set_attr "mode" "QI")])
9623
9624 (define_insn "*xorqi_cc_ext_1"
9625   [(set (reg FLAGS_REG)
9626         (compare
9627           (xor:SI
9628             (zero_extract:SI
9629               (match_operand 1 "ext_register_operand" "0")
9630               (const_int 8)
9631               (const_int 8))
9632             (match_operand:QI 2 "general_operand" "qmn"))
9633           (const_int 0)))
9634    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9635                          (const_int 8)
9636                          (const_int 8))
9637         (xor:SI
9638           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9639           (match_dup 2)))]
9640   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9641   "xor{b}\t{%2, %h0|%h0, %2}"
9642   [(set_attr "type" "alu")
9643    (set_attr "modrm" "1")
9644    (set_attr "mode" "QI")])
9645
9646 (define_insn "*xorqi_cc_ext_1_rex64"
9647   [(set (reg FLAGS_REG)
9648         (compare
9649           (xor:SI
9650             (zero_extract:SI
9651               (match_operand 1 "ext_register_operand" "0")
9652               (const_int 8)
9653               (const_int 8))
9654             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9655           (const_int 0)))
9656    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9657                          (const_int 8)
9658                          (const_int 8))
9659         (xor:SI
9660           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9661           (match_dup 2)))]
9662   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9663   "xor{b}\t{%2, %h0|%h0, %2}"
9664   [(set_attr "type" "alu")
9665    (set_attr "modrm" "1")
9666    (set_attr "mode" "QI")])
9667
9668 (define_expand "xorqi_cc_ext_1"
9669   [(parallel [
9670      (set (reg:CCNO FLAGS_REG)
9671           (compare:CCNO
9672             (xor:SI
9673               (zero_extract:SI
9674                 (match_operand 1 "ext_register_operand" "")
9675                 (const_int 8)
9676                 (const_int 8))
9677               (match_operand:QI 2 "general_operand" ""))
9678             (const_int 0)))
9679      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9680                            (const_int 8)
9681                            (const_int 8))
9682           (xor:SI
9683             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9684             (match_dup 2)))])]
9685   ""
9686   "")
9687
9688 (define_split
9689   [(set (match_operand 0 "register_operand" "")
9690         (xor (match_operand 1 "register_operand" "")
9691              (match_operand 2 "const_int_operand" "")))
9692    (clobber (reg:CC FLAGS_REG))]
9693    "reload_completed
9694     && QI_REG_P (operands[0])
9695     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9696     && !(INTVAL (operands[2]) & ~(255 << 8))
9697     && GET_MODE (operands[0]) != QImode"
9698   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9699                    (xor:SI (zero_extract:SI (match_dup 1)
9700                                             (const_int 8) (const_int 8))
9701                            (match_dup 2)))
9702               (clobber (reg:CC FLAGS_REG))])]
9703   "operands[0] = gen_lowpart (SImode, operands[0]);
9704    operands[1] = gen_lowpart (SImode, operands[1]);
9705    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9706
9707 ;; Since XOR can be encoded with sign extended immediate, this is only
9708 ;; profitable when 7th bit is set.
9709 (define_split
9710   [(set (match_operand 0 "register_operand" "")
9711         (xor (match_operand 1 "general_operand" "")
9712              (match_operand 2 "const_int_operand" "")))
9713    (clobber (reg:CC FLAGS_REG))]
9714    "reload_completed
9715     && ANY_QI_REG_P (operands[0])
9716     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9717     && !(INTVAL (operands[2]) & ~255)
9718     && (INTVAL (operands[2]) & 128)
9719     && GET_MODE (operands[0]) != QImode"
9720   [(parallel [(set (strict_low_part (match_dup 0))
9721                    (xor:QI (match_dup 1)
9722                            (match_dup 2)))
9723               (clobber (reg:CC FLAGS_REG))])]
9724   "operands[0] = gen_lowpart (QImode, operands[0]);
9725    operands[1] = gen_lowpart (QImode, operands[1]);
9726    operands[2] = gen_lowpart (QImode, operands[2]);")
9727 \f
9728 ;; Negation instructions
9729
9730 (define_expand "neg<mode>2"
9731   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9732         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9733   ""
9734   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9735
9736 (define_insn_and_split "*neg<dwi>2_doubleword"
9737   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9738         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9741   "#"
9742   "reload_completed"
9743   [(parallel
9744     [(set (reg:CCZ FLAGS_REG)
9745           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9746      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9747    (parallel
9748     [(set (match_dup 2)
9749           (plus:DWIH (match_dup 3)
9750                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9751                                 (const_int 0))))
9752      (clobber (reg:CC FLAGS_REG))])
9753    (parallel
9754     [(set (match_dup 2)
9755           (neg:DWIH (match_dup 2)))
9756      (clobber (reg:CC FLAGS_REG))])]
9757   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9758
9759 (define_insn "*neg<mode>2_1"
9760   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9761         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9762    (clobber (reg:CC FLAGS_REG))]
9763   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9764   "neg{<imodesuffix>}\t%0"
9765   [(set_attr "type" "negnot")
9766    (set_attr "mode" "<MODE>")])
9767
9768 ;; Combine is quite creative about this pattern.
9769 (define_insn "*negsi2_1_zext"
9770   [(set (match_operand:DI 0 "register_operand" "=r")
9771         (lshiftrt:DI
9772           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9773                              (const_int 32)))
9774         (const_int 32)))
9775    (clobber (reg:CC FLAGS_REG))]
9776   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9777   "neg{l}\t%k0"
9778   [(set_attr "type" "negnot")
9779    (set_attr "mode" "SI")])
9780
9781 ;; The problem with neg is that it does not perform (compare x 0),
9782 ;; it really performs (compare 0 x), which leaves us with the zero
9783 ;; flag being the only useful item.
9784
9785 (define_insn "*neg<mode>2_cmpz"
9786   [(set (reg:CCZ FLAGS_REG)
9787         (compare:CCZ
9788           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9789                    (const_int 0)))
9790    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9791         (neg:SWI (match_dup 1)))]
9792   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9793   "neg{<imodesuffix>}\t%0"
9794   [(set_attr "type" "negnot")
9795    (set_attr "mode" "<MODE>")])
9796
9797 (define_insn "*negsi2_cmpz_zext"
9798   [(set (reg:CCZ FLAGS_REG)
9799         (compare:CCZ
9800           (lshiftrt:DI
9801             (neg:DI (ashift:DI
9802                       (match_operand:DI 1 "register_operand" "0")
9803                       (const_int 32)))
9804             (const_int 32))
9805           (const_int 0)))
9806    (set (match_operand:DI 0 "register_operand" "=r")
9807         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9808                                         (const_int 32)))
9809                      (const_int 32)))]
9810   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9811   "neg{l}\t%k0"
9812   [(set_attr "type" "negnot")
9813    (set_attr "mode" "SI")])
9814
9815 ;; Changing of sign for FP values is doable using integer unit too.
9816
9817 (define_expand "<code><mode>2"
9818   [(set (match_operand:X87MODEF 0 "register_operand" "")
9819         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9820   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9821   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9822
9823 (define_insn "*absneg<mode>2_mixed"
9824   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9825         (match_operator:MODEF 3 "absneg_operator"
9826           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9827    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9828    (clobber (reg:CC FLAGS_REG))]
9829   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9830   "#")
9831
9832 (define_insn "*absneg<mode>2_sse"
9833   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9834         (match_operator:MODEF 3 "absneg_operator"
9835           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9836    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9839   "#")
9840
9841 (define_insn "*absneg<mode>2_i387"
9842   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9843         (match_operator:X87MODEF 3 "absneg_operator"
9844           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9845    (use (match_operand 2 "" ""))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9848   "#")
9849
9850 (define_expand "<code>tf2"
9851   [(set (match_operand:TF 0 "register_operand" "")
9852         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9853   "TARGET_SSE2"
9854   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9855
9856 (define_insn "*absnegtf2_sse"
9857   [(set (match_operand:TF 0 "register_operand" "=x,x")
9858         (match_operator:TF 3 "absneg_operator"
9859           [(match_operand:TF 1 "register_operand" "0,x")]))
9860    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "TARGET_SSE2"
9863   "#")
9864
9865 ;; Splitters for fp abs and neg.
9866
9867 (define_split
9868   [(set (match_operand 0 "fp_register_operand" "")
9869         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9870    (use (match_operand 2 "" ""))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "reload_completed"
9873   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9874
9875 (define_split
9876   [(set (match_operand 0 "register_operand" "")
9877         (match_operator 3 "absneg_operator"
9878           [(match_operand 1 "register_operand" "")]))
9879    (use (match_operand 2 "nonimmediate_operand" ""))
9880    (clobber (reg:CC FLAGS_REG))]
9881   "reload_completed && SSE_REG_P (operands[0])"
9882   [(set (match_dup 0) (match_dup 3))]
9883 {
9884   enum machine_mode mode = GET_MODE (operands[0]);
9885   enum machine_mode vmode = GET_MODE (operands[2]);
9886   rtx tmp;
9887
9888   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9889   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9890   if (operands_match_p (operands[0], operands[2]))
9891     {
9892       tmp = operands[1];
9893       operands[1] = operands[2];
9894       operands[2] = tmp;
9895     }
9896   if (GET_CODE (operands[3]) == ABS)
9897     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9898   else
9899     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9900   operands[3] = tmp;
9901 })
9902
9903 (define_split
9904   [(set (match_operand:SF 0 "register_operand" "")
9905         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9906    (use (match_operand:V4SF 2 "" ""))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "reload_completed"
9909   [(parallel [(set (match_dup 0) (match_dup 1))
9910               (clobber (reg:CC FLAGS_REG))])]
9911 {
9912   rtx tmp;
9913   operands[0] = gen_lowpart (SImode, operands[0]);
9914   if (GET_CODE (operands[1]) == ABS)
9915     {
9916       tmp = gen_int_mode (0x7fffffff, SImode);
9917       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9918     }
9919   else
9920     {
9921       tmp = gen_int_mode (0x80000000, SImode);
9922       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9923     }
9924   operands[1] = tmp;
9925 })
9926
9927 (define_split
9928   [(set (match_operand:DF 0 "register_operand" "")
9929         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9930    (use (match_operand 2 "" ""))
9931    (clobber (reg:CC FLAGS_REG))]
9932   "reload_completed"
9933   [(parallel [(set (match_dup 0) (match_dup 1))
9934               (clobber (reg:CC FLAGS_REG))])]
9935 {
9936   rtx tmp;
9937   if (TARGET_64BIT)
9938     {
9939       tmp = gen_lowpart (DImode, operands[0]);
9940       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9941       operands[0] = tmp;
9942
9943       if (GET_CODE (operands[1]) == ABS)
9944         tmp = const0_rtx;
9945       else
9946         tmp = gen_rtx_NOT (DImode, tmp);
9947     }
9948   else
9949     {
9950       operands[0] = gen_highpart (SImode, operands[0]);
9951       if (GET_CODE (operands[1]) == ABS)
9952         {
9953           tmp = gen_int_mode (0x7fffffff, SImode);
9954           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9955         }
9956       else
9957         {
9958           tmp = gen_int_mode (0x80000000, SImode);
9959           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9960         }
9961     }
9962   operands[1] = tmp;
9963 })
9964
9965 (define_split
9966   [(set (match_operand:XF 0 "register_operand" "")
9967         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9968    (use (match_operand 2 "" ""))
9969    (clobber (reg:CC FLAGS_REG))]
9970   "reload_completed"
9971   [(parallel [(set (match_dup 0) (match_dup 1))
9972               (clobber (reg:CC FLAGS_REG))])]
9973 {
9974   rtx tmp;
9975   operands[0] = gen_rtx_REG (SImode,
9976                              true_regnum (operands[0])
9977                              + (TARGET_64BIT ? 1 : 2));
9978   if (GET_CODE (operands[1]) == ABS)
9979     {
9980       tmp = GEN_INT (0x7fff);
9981       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9982     }
9983   else
9984     {
9985       tmp = GEN_INT (0x8000);
9986       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9987     }
9988   operands[1] = tmp;
9989 })
9990
9991 ;; Conditionalize these after reload. If they match before reload, we
9992 ;; lose the clobber and ability to use integer instructions.
9993
9994 (define_insn "*<code><mode>2_1"
9995   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9996         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9997   "TARGET_80387
9998    && (reload_completed
9999        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10000   "f<absnegprefix>"
10001   [(set_attr "type" "fsgn")
10002    (set_attr "mode" "<MODE>")])
10003
10004 (define_insn "*<code>extendsfdf2"
10005   [(set (match_operand:DF 0 "register_operand" "=f")
10006         (absneg:DF (float_extend:DF
10007                      (match_operand:SF 1 "register_operand" "0"))))]
10008   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10009   "f<absnegprefix>"
10010   [(set_attr "type" "fsgn")
10011    (set_attr "mode" "DF")])
10012
10013 (define_insn "*<code>extendsfxf2"
10014   [(set (match_operand:XF 0 "register_operand" "=f")
10015         (absneg:XF (float_extend:XF
10016                      (match_operand:SF 1 "register_operand" "0"))))]
10017   "TARGET_80387"
10018   "f<absnegprefix>"
10019   [(set_attr "type" "fsgn")
10020    (set_attr "mode" "XF")])
10021
10022 (define_insn "*<code>extenddfxf2"
10023   [(set (match_operand:XF 0 "register_operand" "=f")
10024         (absneg:XF (float_extend:XF
10025                       (match_operand:DF 1 "register_operand" "0"))))]
10026   "TARGET_80387"
10027   "f<absnegprefix>"
10028   [(set_attr "type" "fsgn")
10029    (set_attr "mode" "XF")])
10030
10031 ;; Copysign instructions
10032
10033 (define_mode_iterator CSGNMODE [SF DF TF])
10034 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10035
10036 (define_expand "copysign<mode>3"
10037   [(match_operand:CSGNMODE 0 "register_operand" "")
10038    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10039    (match_operand:CSGNMODE 2 "register_operand" "")]
10040   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10041    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10042 {
10043   ix86_expand_copysign (operands);
10044   DONE;
10045 })
10046
10047 (define_insn_and_split "copysign<mode>3_const"
10048   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10049         (unspec:CSGNMODE
10050           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10051            (match_operand:CSGNMODE 2 "register_operand" "0")
10052            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10053           UNSPEC_COPYSIGN))]
10054   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10055    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10056   "#"
10057   "&& reload_completed"
10058   [(const_int 0)]
10059 {
10060   ix86_split_copysign_const (operands);
10061   DONE;
10062 })
10063
10064 (define_insn "copysign<mode>3_var"
10065   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10066         (unspec:CSGNMODE
10067           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10068            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10069            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10070            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10071           UNSPEC_COPYSIGN))
10072    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10073   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10074    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10075   "#")
10076
10077 (define_split
10078   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10079         (unspec:CSGNMODE
10080           [(match_operand:CSGNMODE 2 "register_operand" "")
10081            (match_operand:CSGNMODE 3 "register_operand" "")
10082            (match_operand:<CSGNVMODE> 4 "" "")
10083            (match_operand:<CSGNVMODE> 5 "" "")]
10084           UNSPEC_COPYSIGN))
10085    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10086   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10087     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10088    && reload_completed"
10089   [(const_int 0)]
10090 {
10091   ix86_split_copysign_var (operands);
10092   DONE;
10093 })
10094 \f
10095 ;; One complement instructions
10096
10097 (define_expand "one_cmpl<mode>2"
10098   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
10099         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
10100   ""
10101   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10102
10103 (define_insn "*one_cmpl<mode>2_1"
10104   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10105         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10106   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10107   "not{<imodesuffix>}\t%0"
10108   [(set_attr "type" "negnot")
10109    (set_attr "mode" "<MODE>")])
10110
10111 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10112 (define_insn "*one_cmplqi2_1"
10113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10114         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10115   "ix86_unary_operator_ok (NOT, QImode, operands)"
10116   "@
10117    not{b}\t%0
10118    not{l}\t%k0"
10119   [(set_attr "type" "negnot")
10120    (set_attr "mode" "QI,SI")])
10121
10122 ;; ??? Currently never generated - xor is used instead.
10123 (define_insn "*one_cmplsi2_1_zext"
10124   [(set (match_operand:DI 0 "register_operand" "=r")
10125         (zero_extend:DI
10126           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10127   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10128   "not{l}\t%k0"
10129   [(set_attr "type" "negnot")
10130    (set_attr "mode" "SI")])
10131
10132 (define_insn "*one_cmpl<mode>2_2"
10133   [(set (reg FLAGS_REG)
10134         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10135                  (const_int 0)))
10136    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10137         (not:SWI (match_dup 1)))]
10138   "ix86_match_ccmode (insn, CCNOmode)
10139    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10140   "#"
10141   [(set_attr "type" "alu1")
10142    (set_attr "mode" "<MODE>")])
10143
10144 (define_split
10145   [(set (match_operand 0 "flags_reg_operand" "")
10146         (match_operator 2 "compare_operator"
10147           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
10148            (const_int 0)]))
10149    (set (match_operand:SWI 1 "nonimmediate_operand" "")
10150         (not:SWI (match_dup 3)))]
10151   "ix86_match_ccmode (insn, CCNOmode)"
10152   [(parallel [(set (match_dup 0)
10153                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10154                                     (const_int 0)]))
10155               (set (match_dup 1)
10156                    (xor:SWI (match_dup 3) (const_int -1)))])]
10157   "")
10158
10159 ;; ??? Currently never generated - xor is used instead.
10160 (define_insn "*one_cmplsi2_2_zext"
10161   [(set (reg FLAGS_REG)
10162         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10163                  (const_int 0)))
10164    (set (match_operand:DI 0 "register_operand" "=r")
10165         (zero_extend:DI (not:SI (match_dup 1))))]
10166   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10167    && ix86_unary_operator_ok (NOT, SImode, operands)"
10168   "#"
10169   [(set_attr "type" "alu1")
10170    (set_attr "mode" "SI")])
10171
10172 (define_split
10173   [(set (match_operand 0 "flags_reg_operand" "")
10174         (match_operator 2 "compare_operator"
10175           [(not:SI (match_operand:SI 3 "register_operand" ""))
10176            (const_int 0)]))
10177    (set (match_operand:DI 1 "register_operand" "")
10178         (zero_extend:DI (not:SI (match_dup 3))))]
10179   "ix86_match_ccmode (insn, CCNOmode)"
10180   [(parallel [(set (match_dup 0)
10181                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10182                                     (const_int 0)]))
10183               (set (match_dup 1)
10184                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10185   "")
10186 \f
10187 ;; Arithmetic shift instructions
10188
10189 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10190 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10191 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10192 ;; from the assembler input.
10193 ;;
10194 ;; This instruction shifts the target reg/mem as usual, but instead of
10195 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10196 ;; is a left shift double, bits are taken from the high order bits of
10197 ;; reg, else if the insn is a shift right double, bits are taken from the
10198 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10199 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10200 ;;
10201 ;; Since sh[lr]d does not change the `reg' operand, that is done
10202 ;; separately, making all shifts emit pairs of shift double and normal
10203 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10204 ;; support a 63 bit shift, each shift where the count is in a reg expands
10205 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10206 ;;
10207 ;; If the shift count is a constant, we need never emit more than one
10208 ;; shift pair, instead using moves and sign extension for counts greater
10209 ;; than 31.
10210
10211 (define_expand "ashlti3"
10212   [(set (match_operand:TI 0 "register_operand" "")
10213         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10214                    (match_operand:QI 2 "nonmemory_operand" "")))]
10215   "TARGET_64BIT"
10216   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10217
10218 ;; This pattern must be defined before *ashlti3_1 to prevent
10219 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10220
10221 (define_insn "*avx_ashlti3"
10222   [(set (match_operand:TI 0 "register_operand" "=x")
10223         (ashift:TI (match_operand:TI 1 "register_operand" "x")
10224                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10225   "TARGET_AVX"
10226 {
10227   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10228   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10229 }
10230   [(set_attr "type" "sseishft")
10231    (set_attr "prefix" "vex")
10232    (set_attr "length_immediate" "1")
10233    (set_attr "mode" "TI")])
10234
10235 (define_insn "sse2_ashlti3"
10236   [(set (match_operand:TI 0 "register_operand" "=x")
10237         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10238                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10239   "TARGET_SSE2"
10240 {
10241   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10242   return "pslldq\t{%2, %0|%0, %2}";
10243 }
10244   [(set_attr "type" "sseishft")
10245    (set_attr "prefix_data16" "1")
10246    (set_attr "length_immediate" "1")
10247    (set_attr "mode" "TI")])
10248
10249 (define_insn "*ashlti3_1"
10250   [(set (match_operand:TI 0 "register_operand" "=&r,r")
10251         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10252                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10253    (clobber (reg:CC FLAGS_REG))]
10254   "TARGET_64BIT"
10255   "#"
10256   [(set_attr "type" "multi")])
10257
10258 (define_peephole2
10259   [(match_scratch:DI 3 "r")
10260    (parallel [(set (match_operand:TI 0 "register_operand" "")
10261                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10262                               (match_operand:QI 2 "nonmemory_operand" "")))
10263               (clobber (reg:CC FLAGS_REG))])
10264    (match_dup 3)]
10265   "TARGET_64BIT"
10266   [(const_int 0)]
10267   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10268
10269 (define_split
10270   [(set (match_operand:TI 0 "register_operand" "")
10271         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10272                    (match_operand:QI 2 "nonmemory_operand" "")))
10273    (clobber (reg:CC FLAGS_REG))]
10274   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10275                     ? epilogue_completed : reload_completed)"
10276   [(const_int 0)]
10277   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10278
10279 (define_insn "x86_64_shld"
10280   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10281         (ior:DI (ashift:DI (match_dup 0)
10282                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10283                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10284                   (minus:QI (const_int 64) (match_dup 2)))))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "TARGET_64BIT"
10287   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10288   [(set_attr "type" "ishift")
10289    (set_attr "prefix_0f" "1")
10290    (set_attr "mode" "DI")
10291    (set_attr "athlon_decode" "vector")
10292    (set_attr "amdfam10_decode" "vector")])
10293
10294 (define_expand "x86_64_shift_adj_1"
10295   [(set (reg:CCZ FLAGS_REG)
10296         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10297                              (const_int 64))
10298                      (const_int 0)))
10299    (set (match_operand:DI 0 "register_operand" "")
10300         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10301                          (match_operand:DI 1 "register_operand" "")
10302                          (match_dup 0)))
10303    (set (match_dup 1)
10304         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10305                          (match_operand:DI 3 "register_operand" "r")
10306                          (match_dup 1)))]
10307   "TARGET_64BIT"
10308   "")
10309
10310 (define_expand "x86_64_shift_adj_2"
10311   [(use (match_operand:DI 0 "register_operand" ""))
10312    (use (match_operand:DI 1 "register_operand" ""))
10313    (use (match_operand:QI 2 "register_operand" ""))]
10314   "TARGET_64BIT"
10315 {
10316   rtx label = gen_label_rtx ();
10317   rtx tmp;
10318
10319   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10320
10321   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10322   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10323   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10324                               gen_rtx_LABEL_REF (VOIDmode, label),
10325                               pc_rtx);
10326   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10327   JUMP_LABEL (tmp) = label;
10328
10329   emit_move_insn (operands[0], operands[1]);
10330   ix86_expand_clear (operands[1]);
10331
10332   emit_label (label);
10333   LABEL_NUSES (label) = 1;
10334
10335   DONE;
10336 })
10337
10338 (define_expand "ashldi3"
10339   [(set (match_operand:DI 0 "shiftdi_operand" "")
10340         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10341                    (match_operand:QI 2 "nonmemory_operand" "")))]
10342   ""
10343   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10344
10345 (define_insn "*ashldi3_1_rex64"
10346   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10347         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10348                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10349    (clobber (reg:CC FLAGS_REG))]
10350   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10351 {
10352   switch (get_attr_type (insn))
10353     {
10354     case TYPE_ALU:
10355       gcc_assert (operands[2] == const1_rtx);
10356       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10357       return "add{q}\t%0, %0";
10358
10359     case TYPE_LEA:
10360       gcc_assert (CONST_INT_P (operands[2]));
10361       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10362       operands[1] = gen_rtx_MULT (DImode, operands[1],
10363                                   GEN_INT (1 << INTVAL (operands[2])));
10364       return "lea{q}\t{%a1, %0|%0, %a1}";
10365
10366     default:
10367       if (REG_P (operands[2]))
10368         return "sal{q}\t{%b2, %0|%0, %b2}";
10369       else if (operands[2] == const1_rtx
10370                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10371         return "sal{q}\t%0";
10372       else
10373         return "sal{q}\t{%2, %0|%0, %2}";
10374     }
10375 }
10376   [(set (attr "type")
10377      (cond [(eq_attr "alternative" "1")
10378               (const_string "lea")
10379             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10380                           (const_int 0))
10381                       (match_operand 0 "register_operand" ""))
10382                  (match_operand 2 "const1_operand" ""))
10383               (const_string "alu")
10384            ]
10385            (const_string "ishift")))
10386    (set (attr "length_immediate")
10387      (if_then_else
10388        (ior (eq_attr "type" "alu")
10389             (and (eq_attr "type" "ishift")
10390                  (and (match_operand 2 "const1_operand" "")
10391                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10392                           (const_int 0)))))
10393        (const_string "0")
10394        (const_string "*")))
10395    (set_attr "mode" "DI")])
10396
10397 ;; Convert lea to the lea pattern to avoid flags dependency.
10398 (define_split
10399   [(set (match_operand:DI 0 "register_operand" "")
10400         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10401                    (match_operand:QI 2 "immediate_operand" "")))
10402    (clobber (reg:CC FLAGS_REG))]
10403   "TARGET_64BIT && reload_completed
10404    && true_regnum (operands[0]) != true_regnum (operands[1])"
10405   [(set (match_dup 0)
10406         (mult:DI (match_dup 1)
10407                  (match_dup 2)))]
10408   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10409
10410 ;; This pattern can't accept a variable shift count, since shifts by
10411 ;; zero don't affect the flags.  We assume that shifts by constant
10412 ;; zero are optimized away.
10413 (define_insn "*ashldi3_cmp_rex64"
10414   [(set (reg FLAGS_REG)
10415         (compare
10416           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10417                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10418           (const_int 0)))
10419    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10420         (ashift:DI (match_dup 1) (match_dup 2)))]
10421   "TARGET_64BIT
10422    && (optimize_function_for_size_p (cfun)
10423        || !TARGET_PARTIAL_FLAG_REG_STALL
10424        || (operands[2] == const1_rtx
10425            && (TARGET_SHIFT1
10426                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10427    && ix86_match_ccmode (insn, CCGOCmode)
10428    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10429 {
10430   switch (get_attr_type (insn))
10431     {
10432     case TYPE_ALU:
10433       gcc_assert (operands[2] == const1_rtx);
10434       return "add{q}\t%0, %0";
10435
10436     default:
10437       if (REG_P (operands[2]))
10438         return "sal{q}\t{%b2, %0|%0, %b2}";
10439       else if (operands[2] == const1_rtx
10440                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10441         return "sal{q}\t%0";
10442       else
10443         return "sal{q}\t{%2, %0|%0, %2}";
10444     }
10445 }
10446   [(set (attr "type")
10447      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10448                           (const_int 0))
10449                       (match_operand 0 "register_operand" ""))
10450                  (match_operand 2 "const1_operand" ""))
10451               (const_string "alu")
10452            ]
10453            (const_string "ishift")))
10454    (set (attr "length_immediate")
10455      (if_then_else
10456        (ior (eq_attr "type" "alu")
10457             (and (eq_attr "type" "ishift")
10458                  (and (match_operand 2 "const1_operand" "")
10459                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10460                           (const_int 0)))))
10461        (const_string "0")
10462        (const_string "*")))
10463    (set_attr "mode" "DI")])
10464
10465 (define_insn "*ashldi3_cconly_rex64"
10466   [(set (reg FLAGS_REG)
10467         (compare
10468           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10469                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10470           (const_int 0)))
10471    (clobber (match_scratch:DI 0 "=r"))]
10472   "TARGET_64BIT
10473    && (optimize_function_for_size_p (cfun)
10474        || !TARGET_PARTIAL_FLAG_REG_STALL
10475        || (operands[2] == const1_rtx
10476            && (TARGET_SHIFT1
10477                || TARGET_DOUBLE_WITH_ADD)))
10478    && ix86_match_ccmode (insn, CCGOCmode)
10479    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10480 {
10481   switch (get_attr_type (insn))
10482     {
10483     case TYPE_ALU:
10484       gcc_assert (operands[2] == const1_rtx);
10485       return "add{q}\t%0, %0";
10486
10487     default:
10488       if (REG_P (operands[2]))
10489         return "sal{q}\t{%b2, %0|%0, %b2}";
10490       else if (operands[2] == const1_rtx
10491                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10492         return "sal{q}\t%0";
10493       else
10494         return "sal{q}\t{%2, %0|%0, %2}";
10495     }
10496 }
10497   [(set (attr "type")
10498      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10499                           (const_int 0))
10500                       (match_operand 0 "register_operand" ""))
10501                  (match_operand 2 "const1_operand" ""))
10502               (const_string "alu")
10503            ]
10504            (const_string "ishift")))
10505    (set (attr "length_immediate")
10506      (if_then_else
10507        (ior (eq_attr "type" "alu")
10508             (and (eq_attr "type" "ishift")
10509                  (and (match_operand 2 "const1_operand" "")
10510                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10511                           (const_int 0)))))
10512        (const_string "0")
10513        (const_string "*")))
10514    (set_attr "mode" "DI")])
10515
10516 (define_insn "*ashldi3_1"
10517   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10518         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10519                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10520    (clobber (reg:CC FLAGS_REG))]
10521   "!TARGET_64BIT"
10522   "#"
10523   [(set_attr "type" "multi")])
10524
10525 ;; By default we don't ask for a scratch register, because when DImode
10526 ;; values are manipulated, registers are already at a premium.  But if
10527 ;; we have one handy, we won't turn it away.
10528 (define_peephole2
10529   [(match_scratch:SI 3 "r")
10530    (parallel [(set (match_operand:DI 0 "register_operand" "")
10531                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10532                               (match_operand:QI 2 "nonmemory_operand" "")))
10533               (clobber (reg:CC FLAGS_REG))])
10534    (match_dup 3)]
10535   "!TARGET_64BIT && TARGET_CMOVE"
10536   [(const_int 0)]
10537   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10538
10539 (define_split
10540   [(set (match_operand:DI 0 "register_operand" "")
10541         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10542                    (match_operand:QI 2 "nonmemory_operand" "")))
10543    (clobber (reg:CC FLAGS_REG))]
10544   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10545                      ? epilogue_completed : reload_completed)"
10546   [(const_int 0)]
10547   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10548
10549 (define_insn "x86_shld"
10550   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10551         (ior:SI (ashift:SI (match_dup 0)
10552                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10553                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10554                   (minus:QI (const_int 32) (match_dup 2)))))
10555    (clobber (reg:CC FLAGS_REG))]
10556   ""
10557   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10558   [(set_attr "type" "ishift")
10559    (set_attr "prefix_0f" "1")
10560    (set_attr "mode" "SI")
10561    (set_attr "pent_pair" "np")
10562    (set_attr "athlon_decode" "vector")
10563    (set_attr "amdfam10_decode" "vector")])
10564
10565 (define_expand "x86_shift_adj_1"
10566   [(set (reg:CCZ FLAGS_REG)
10567         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10568                              (const_int 32))
10569                      (const_int 0)))
10570    (set (match_operand:SI 0 "register_operand" "")
10571         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10572                          (match_operand:SI 1 "register_operand" "")
10573                          (match_dup 0)))
10574    (set (match_dup 1)
10575         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10576                          (match_operand:SI 3 "register_operand" "r")
10577                          (match_dup 1)))]
10578   "TARGET_CMOVE"
10579   "")
10580
10581 (define_expand "x86_shift_adj_2"
10582   [(use (match_operand:SI 0 "register_operand" ""))
10583    (use (match_operand:SI 1 "register_operand" ""))
10584    (use (match_operand:QI 2 "register_operand" ""))]
10585   ""
10586 {
10587   rtx label = gen_label_rtx ();
10588   rtx tmp;
10589
10590   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10591
10592   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10593   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10594   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10595                               gen_rtx_LABEL_REF (VOIDmode, label),
10596                               pc_rtx);
10597   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10598   JUMP_LABEL (tmp) = label;
10599
10600   emit_move_insn (operands[0], operands[1]);
10601   ix86_expand_clear (operands[1]);
10602
10603   emit_label (label);
10604   LABEL_NUSES (label) = 1;
10605
10606   DONE;
10607 })
10608
10609 (define_expand "ashlsi3"
10610   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10611         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10612                    (match_operand:QI 2 "nonmemory_operand" "")))]
10613   ""
10614   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10615
10616 (define_insn "*ashlsi3_1"
10617   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10618         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10619                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10620    (clobber (reg:CC FLAGS_REG))]
10621   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10622 {
10623   switch (get_attr_type (insn))
10624     {
10625     case TYPE_ALU:
10626       gcc_assert (operands[2] == const1_rtx);
10627       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10628       return "add{l}\t%0, %0";
10629
10630     case TYPE_LEA:
10631       return "#";
10632
10633     default:
10634       if (REG_P (operands[2]))
10635         return "sal{l}\t{%b2, %0|%0, %b2}";
10636       else if (operands[2] == const1_rtx
10637                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10638         return "sal{l}\t%0";
10639       else
10640         return "sal{l}\t{%2, %0|%0, %2}";
10641     }
10642 }
10643   [(set (attr "type")
10644      (cond [(eq_attr "alternative" "1")
10645               (const_string "lea")
10646             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10647                           (const_int 0))
10648                       (match_operand 0 "register_operand" ""))
10649                  (match_operand 2 "const1_operand" ""))
10650               (const_string "alu")
10651            ]
10652            (const_string "ishift")))
10653    (set (attr "length_immediate")
10654      (if_then_else
10655        (ior (eq_attr "type" "alu")
10656             (and (eq_attr "type" "ishift")
10657                  (and (match_operand 2 "const1_operand" "")
10658                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10659                           (const_int 0)))))
10660        (const_string "0")
10661        (const_string "*")))
10662    (set_attr "mode" "SI")])
10663
10664 ;; Convert lea to the lea pattern to avoid flags dependency.
10665 (define_split
10666   [(set (match_operand 0 "register_operand" "")
10667         (ashift (match_operand 1 "index_register_operand" "")
10668                 (match_operand:QI 2 "const_int_operand" "")))
10669    (clobber (reg:CC FLAGS_REG))]
10670   "reload_completed
10671    && true_regnum (operands[0]) != true_regnum (operands[1])
10672    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10673   [(const_int 0)]
10674 {
10675   rtx pat;
10676   enum machine_mode mode = GET_MODE (operands[0]);
10677
10678   if (GET_MODE_SIZE (mode) < 4)
10679     operands[0] = gen_lowpart (SImode, operands[0]);
10680   if (mode != Pmode)
10681     operands[1] = gen_lowpart (Pmode, operands[1]);
10682   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10683
10684   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10685   if (Pmode != SImode)
10686     pat = gen_rtx_SUBREG (SImode, pat, 0);
10687   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10688   DONE;
10689 })
10690
10691 ;; Rare case of shifting RSP is handled by generating move and shift
10692 (define_split
10693   [(set (match_operand 0 "register_operand" "")
10694         (ashift (match_operand 1 "register_operand" "")
10695                 (match_operand:QI 2 "const_int_operand" "")))
10696    (clobber (reg:CC FLAGS_REG))]
10697   "reload_completed
10698    && true_regnum (operands[0]) != true_regnum (operands[1])"
10699   [(const_int 0)]
10700 {
10701   rtx pat, clob;
10702   emit_move_insn (operands[0], operands[1]);
10703   pat = gen_rtx_SET (VOIDmode, operands[0],
10704                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10705                                      operands[0], operands[2]));
10706   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10707   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10708   DONE;
10709 })
10710
10711 (define_insn "*ashlsi3_1_zext"
10712   [(set (match_operand:DI 0 "register_operand" "=r,r")
10713         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10714                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10715    (clobber (reg:CC FLAGS_REG))]
10716   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10717 {
10718   switch (get_attr_type (insn))
10719     {
10720     case TYPE_ALU:
10721       gcc_assert (operands[2] == const1_rtx);
10722       return "add{l}\t%k0, %k0";
10723
10724     case TYPE_LEA:
10725       return "#";
10726
10727     default:
10728       if (REG_P (operands[2]))
10729         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10730       else if (operands[2] == const1_rtx
10731                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10732         return "sal{l}\t%k0";
10733       else
10734         return "sal{l}\t{%2, %k0|%k0, %2}";
10735     }
10736 }
10737   [(set (attr "type")
10738      (cond [(eq_attr "alternative" "1")
10739               (const_string "lea")
10740             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10741                      (const_int 0))
10742                  (match_operand 2 "const1_operand" ""))
10743               (const_string "alu")
10744            ]
10745            (const_string "ishift")))
10746    (set (attr "length_immediate")
10747      (if_then_else
10748        (ior (eq_attr "type" "alu")
10749             (and (eq_attr "type" "ishift")
10750                  (and (match_operand 2 "const1_operand" "")
10751                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10752                           (const_int 0)))))
10753        (const_string "0")
10754        (const_string "*")))
10755    (set_attr "mode" "SI")])
10756
10757 ;; Convert lea to the lea pattern to avoid flags dependency.
10758 (define_split
10759   [(set (match_operand:DI 0 "register_operand" "")
10760         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10761                                 (match_operand:QI 2 "const_int_operand" ""))))
10762    (clobber (reg:CC FLAGS_REG))]
10763   "TARGET_64BIT && reload_completed
10764    && true_regnum (operands[0]) != true_regnum (operands[1])"
10765   [(set (match_dup 0) (zero_extend:DI
10766                         (subreg:SI (mult:SI (match_dup 1)
10767                                             (match_dup 2)) 0)))]
10768 {
10769   operands[1] = gen_lowpart (Pmode, operands[1]);
10770   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10771 })
10772
10773 ;; This pattern can't accept a variable shift count, since shifts by
10774 ;; zero don't affect the flags.  We assume that shifts by constant
10775 ;; zero are optimized away.
10776 (define_insn "*ashlsi3_cmp"
10777   [(set (reg FLAGS_REG)
10778         (compare
10779           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10780                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10781           (const_int 0)))
10782    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10783         (ashift:SI (match_dup 1) (match_dup 2)))]
10784    "(optimize_function_for_size_p (cfun)
10785      || !TARGET_PARTIAL_FLAG_REG_STALL
10786      || (operands[2] == const1_rtx
10787          && (TARGET_SHIFT1
10788              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10789    && ix86_match_ccmode (insn, CCGOCmode)
10790    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10791 {
10792   switch (get_attr_type (insn))
10793     {
10794     case TYPE_ALU:
10795       gcc_assert (operands[2] == const1_rtx);
10796       return "add{l}\t%0, %0";
10797
10798     default:
10799       if (REG_P (operands[2]))
10800         return "sal{l}\t{%b2, %0|%0, %b2}";
10801       else if (operands[2] == const1_rtx
10802                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10803         return "sal{l}\t%0";
10804       else
10805         return "sal{l}\t{%2, %0|%0, %2}";
10806     }
10807 }
10808   [(set (attr "type")
10809      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10810                           (const_int 0))
10811                       (match_operand 0 "register_operand" ""))
10812                  (match_operand 2 "const1_operand" ""))
10813               (const_string "alu")
10814            ]
10815            (const_string "ishift")))
10816    (set (attr "length_immediate")
10817      (if_then_else
10818        (ior (eq_attr "type" "alu")
10819             (and (eq_attr "type" "ishift")
10820                  (and (match_operand 2 "const1_operand" "")
10821                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10822                           (const_int 0)))))
10823        (const_string "0")
10824        (const_string "*")))
10825    (set_attr "mode" "SI")])
10826
10827 (define_insn "*ashlsi3_cconly"
10828   [(set (reg FLAGS_REG)
10829         (compare
10830           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10831                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10832           (const_int 0)))
10833    (clobber (match_scratch:SI 0 "=r"))]
10834   "(optimize_function_for_size_p (cfun)
10835     || !TARGET_PARTIAL_FLAG_REG_STALL
10836     || (operands[2] == const1_rtx
10837         && (TARGET_SHIFT1
10838             || TARGET_DOUBLE_WITH_ADD)))
10839    && ix86_match_ccmode (insn, CCGOCmode)
10840    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10841 {
10842   switch (get_attr_type (insn))
10843     {
10844     case TYPE_ALU:
10845       gcc_assert (operands[2] == const1_rtx);
10846       return "add{l}\t%0, %0";
10847
10848     default:
10849       if (REG_P (operands[2]))
10850         return "sal{l}\t{%b2, %0|%0, %b2}";
10851       else if (operands[2] == const1_rtx
10852                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10853         return "sal{l}\t%0";
10854       else
10855         return "sal{l}\t{%2, %0|%0, %2}";
10856     }
10857 }
10858   [(set (attr "type")
10859      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10860                           (const_int 0))
10861                       (match_operand 0 "register_operand" ""))
10862                  (match_operand 2 "const1_operand" ""))
10863               (const_string "alu")
10864            ]
10865            (const_string "ishift")))
10866    (set (attr "length_immediate")
10867      (if_then_else
10868        (ior (eq_attr "type" "alu")
10869             (and (eq_attr "type" "ishift")
10870                  (and (match_operand 2 "const1_operand" "")
10871                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10872                           (const_int 0)))))
10873        (const_string "0")
10874        (const_string "*")))
10875    (set_attr "mode" "SI")])
10876
10877 (define_insn "*ashlsi3_cmp_zext"
10878   [(set (reg FLAGS_REG)
10879         (compare
10880           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10881                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10882           (const_int 0)))
10883    (set (match_operand:DI 0 "register_operand" "=r")
10884         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10885   "TARGET_64BIT
10886    && (optimize_function_for_size_p (cfun)
10887        || !TARGET_PARTIAL_FLAG_REG_STALL
10888        || (operands[2] == const1_rtx
10889            && (TARGET_SHIFT1
10890                || TARGET_DOUBLE_WITH_ADD)))
10891    && ix86_match_ccmode (insn, CCGOCmode)
10892    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10893 {
10894   switch (get_attr_type (insn))
10895     {
10896     case TYPE_ALU:
10897       gcc_assert (operands[2] == const1_rtx);
10898       return "add{l}\t%k0, %k0";
10899
10900     default:
10901       if (REG_P (operands[2]))
10902         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10903       else if (operands[2] == const1_rtx
10904                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10905         return "sal{l}\t%k0";
10906       else
10907         return "sal{l}\t{%2, %k0|%k0, %2}";
10908     }
10909 }
10910   [(set (attr "type")
10911      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10912                      (const_int 0))
10913                  (match_operand 2 "const1_operand" ""))
10914               (const_string "alu")
10915            ]
10916            (const_string "ishift")))
10917    (set (attr "length_immediate")
10918      (if_then_else
10919        (ior (eq_attr "type" "alu")
10920             (and (eq_attr "type" "ishift")
10921                  (and (match_operand 2 "const1_operand" "")
10922                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10923                           (const_int 0)))))
10924        (const_string "0")
10925        (const_string "*")))
10926    (set_attr "mode" "SI")])
10927
10928 (define_expand "ashlhi3"
10929   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10930         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10931                    (match_operand:QI 2 "nonmemory_operand" "")))]
10932   "TARGET_HIMODE_MATH"
10933   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10934
10935 (define_insn "*ashlhi3_1_lea"
10936   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10937         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10938                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10939    (clobber (reg:CC FLAGS_REG))]
10940   "!TARGET_PARTIAL_REG_STALL
10941    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10942 {
10943   switch (get_attr_type (insn))
10944     {
10945     case TYPE_LEA:
10946       return "#";
10947     case TYPE_ALU:
10948       gcc_assert (operands[2] == const1_rtx);
10949       return "add{w}\t%0, %0";
10950
10951     default:
10952       if (REG_P (operands[2]))
10953         return "sal{w}\t{%b2, %0|%0, %b2}";
10954       else if (operands[2] == const1_rtx
10955                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10956         return "sal{w}\t%0";
10957       else
10958         return "sal{w}\t{%2, %0|%0, %2}";
10959     }
10960 }
10961   [(set (attr "type")
10962      (cond [(eq_attr "alternative" "1")
10963               (const_string "lea")
10964             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10965                           (const_int 0))
10966                       (match_operand 0 "register_operand" ""))
10967                  (match_operand 2 "const1_operand" ""))
10968               (const_string "alu")
10969            ]
10970            (const_string "ishift")))
10971    (set (attr "length_immediate")
10972      (if_then_else
10973        (ior (eq_attr "type" "alu")
10974             (and (eq_attr "type" "ishift")
10975                  (and (match_operand 2 "const1_operand" "")
10976                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10977                           (const_int 0)))))
10978        (const_string "0")
10979        (const_string "*")))
10980    (set_attr "mode" "HI,SI")])
10981
10982 (define_insn "*ashlhi3_1"
10983   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10984         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10985                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10986    (clobber (reg:CC FLAGS_REG))]
10987   "TARGET_PARTIAL_REG_STALL
10988    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10989 {
10990   switch (get_attr_type (insn))
10991     {
10992     case TYPE_ALU:
10993       gcc_assert (operands[2] == const1_rtx);
10994       return "add{w}\t%0, %0";
10995
10996     default:
10997       if (REG_P (operands[2]))
10998         return "sal{w}\t{%b2, %0|%0, %b2}";
10999       else if (operands[2] == const1_rtx
11000                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11001         return "sal{w}\t%0";
11002       else
11003         return "sal{w}\t{%2, %0|%0, %2}";
11004     }
11005 }
11006   [(set (attr "type")
11007      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11008                           (const_int 0))
11009                       (match_operand 0 "register_operand" ""))
11010                  (match_operand 2 "const1_operand" ""))
11011               (const_string "alu")
11012            ]
11013            (const_string "ishift")))
11014    (set (attr "length_immediate")
11015      (if_then_else
11016        (ior (eq_attr "type" "alu")
11017             (and (eq_attr "type" "ishift")
11018                  (and (match_operand 2 "const1_operand" "")
11019                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11020                           (const_int 0)))))
11021        (const_string "0")
11022        (const_string "*")))
11023    (set_attr "mode" "HI")])
11024
11025 ;; This pattern can't accept a variable shift count, since shifts by
11026 ;; zero don't affect the flags.  We assume that shifts by constant
11027 ;; zero are optimized away.
11028 (define_insn "*ashlhi3_cmp"
11029   [(set (reg FLAGS_REG)
11030         (compare
11031           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11032                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11033           (const_int 0)))
11034    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11035         (ashift:HI (match_dup 1) (match_dup 2)))]
11036   "(optimize_function_for_size_p (cfun)
11037     || !TARGET_PARTIAL_FLAG_REG_STALL
11038     || (operands[2] == const1_rtx
11039         && (TARGET_SHIFT1
11040             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11041    && ix86_match_ccmode (insn, CCGOCmode)
11042    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11043 {
11044   switch (get_attr_type (insn))
11045     {
11046     case TYPE_ALU:
11047       gcc_assert (operands[2] == const1_rtx);
11048       return "add{w}\t%0, %0";
11049
11050     default:
11051       if (REG_P (operands[2]))
11052         return "sal{w}\t{%b2, %0|%0, %b2}";
11053       else if (operands[2] == const1_rtx
11054                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11055         return "sal{w}\t%0";
11056       else
11057         return "sal{w}\t{%2, %0|%0, %2}";
11058     }
11059 }
11060   [(set (attr "type")
11061      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11062                           (const_int 0))
11063                       (match_operand 0 "register_operand" ""))
11064                  (match_operand 2 "const1_operand" ""))
11065               (const_string "alu")
11066            ]
11067            (const_string "ishift")))
11068    (set (attr "length_immediate")
11069      (if_then_else
11070        (ior (eq_attr "type" "alu")
11071             (and (eq_attr "type" "ishift")
11072                  (and (match_operand 2 "const1_operand" "")
11073                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11074                           (const_int 0)))))
11075        (const_string "0")
11076        (const_string "*")))
11077    (set_attr "mode" "HI")])
11078
11079 (define_insn "*ashlhi3_cconly"
11080   [(set (reg FLAGS_REG)
11081         (compare
11082           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11083                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11084           (const_int 0)))
11085    (clobber (match_scratch:HI 0 "=r"))]
11086   "(optimize_function_for_size_p (cfun)
11087     || !TARGET_PARTIAL_FLAG_REG_STALL
11088     || (operands[2] == const1_rtx
11089         && (TARGET_SHIFT1
11090             || TARGET_DOUBLE_WITH_ADD)))
11091    && ix86_match_ccmode (insn, CCGOCmode)
11092    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11093 {
11094   switch (get_attr_type (insn))
11095     {
11096     case TYPE_ALU:
11097       gcc_assert (operands[2] == const1_rtx);
11098       return "add{w}\t%0, %0";
11099
11100     default:
11101       if (REG_P (operands[2]))
11102         return "sal{w}\t{%b2, %0|%0, %b2}";
11103       else if (operands[2] == const1_rtx
11104                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11105         return "sal{w}\t%0";
11106       else
11107         return "sal{w}\t{%2, %0|%0, %2}";
11108     }
11109 }
11110   [(set (attr "type")
11111      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11112                           (const_int 0))
11113                       (match_operand 0 "register_operand" ""))
11114                  (match_operand 2 "const1_operand" ""))
11115               (const_string "alu")
11116            ]
11117            (const_string "ishift")))
11118    (set (attr "length_immediate")
11119      (if_then_else
11120        (ior (eq_attr "type" "alu")
11121             (and (eq_attr "type" "ishift")
11122                  (and (match_operand 2 "const1_operand" "")
11123                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11124                           (const_int 0)))))
11125        (const_string "0")
11126        (const_string "*")))
11127    (set_attr "mode" "HI")])
11128
11129 (define_expand "ashlqi3"
11130   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11131         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11132                    (match_operand:QI 2 "nonmemory_operand" "")))]
11133   "TARGET_QIMODE_MATH"
11134   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11135
11136 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11137
11138 (define_insn "*ashlqi3_1_lea"
11139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11140         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11141                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11142    (clobber (reg:CC FLAGS_REG))]
11143   "!TARGET_PARTIAL_REG_STALL
11144    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11145 {
11146   switch (get_attr_type (insn))
11147     {
11148     case TYPE_LEA:
11149       return "#";
11150     case TYPE_ALU:
11151       gcc_assert (operands[2] == const1_rtx);
11152       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11153         return "add{l}\t%k0, %k0";
11154       else
11155         return "add{b}\t%0, %0";
11156
11157     default:
11158       if (REG_P (operands[2]))
11159         {
11160           if (get_attr_mode (insn) == MODE_SI)
11161             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11162           else
11163             return "sal{b}\t{%b2, %0|%0, %b2}";
11164         }
11165       else if (operands[2] == const1_rtx
11166                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11167         {
11168           if (get_attr_mode (insn) == MODE_SI)
11169             return "sal{l}\t%0";
11170           else
11171             return "sal{b}\t%0";
11172         }
11173       else
11174         {
11175           if (get_attr_mode (insn) == MODE_SI)
11176             return "sal{l}\t{%2, %k0|%k0, %2}";
11177           else
11178             return "sal{b}\t{%2, %0|%0, %2}";
11179         }
11180     }
11181 }
11182   [(set (attr "type")
11183      (cond [(eq_attr "alternative" "2")
11184               (const_string "lea")
11185             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11186                           (const_int 0))
11187                       (match_operand 0 "register_operand" ""))
11188                  (match_operand 2 "const1_operand" ""))
11189               (const_string "alu")
11190            ]
11191            (const_string "ishift")))
11192    (set (attr "length_immediate")
11193      (if_then_else
11194        (ior (eq_attr "type" "alu")
11195             (and (eq_attr "type" "ishift")
11196                  (and (match_operand 2 "const1_operand" "")
11197                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11198                           (const_int 0)))))
11199        (const_string "0")
11200        (const_string "*")))
11201    (set_attr "mode" "QI,SI,SI")])
11202
11203 (define_insn "*ashlqi3_1"
11204   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11205         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11206                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11207    (clobber (reg:CC FLAGS_REG))]
11208   "TARGET_PARTIAL_REG_STALL
11209    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11210 {
11211   switch (get_attr_type (insn))
11212     {
11213     case TYPE_ALU:
11214       gcc_assert (operands[2] == const1_rtx);
11215       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11216         return "add{l}\t%k0, %k0";
11217       else
11218         return "add{b}\t%0, %0";
11219
11220     default:
11221       if (REG_P (operands[2]))
11222         {
11223           if (get_attr_mode (insn) == MODE_SI)
11224             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11225           else
11226             return "sal{b}\t{%b2, %0|%0, %b2}";
11227         }
11228       else if (operands[2] == const1_rtx
11229                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11230         {
11231           if (get_attr_mode (insn) == MODE_SI)
11232             return "sal{l}\t%0";
11233           else
11234             return "sal{b}\t%0";
11235         }
11236       else
11237         {
11238           if (get_attr_mode (insn) == MODE_SI)
11239             return "sal{l}\t{%2, %k0|%k0, %2}";
11240           else
11241             return "sal{b}\t{%2, %0|%0, %2}";
11242         }
11243     }
11244 }
11245   [(set (attr "type")
11246      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11247                           (const_int 0))
11248                       (match_operand 0 "register_operand" ""))
11249                  (match_operand 2 "const1_operand" ""))
11250               (const_string "alu")
11251            ]
11252            (const_string "ishift")))
11253    (set (attr "length_immediate")
11254      (if_then_else
11255        (ior (eq_attr "type" "alu")
11256             (and (eq_attr "type" "ishift")
11257                  (and (match_operand 2 "const1_operand" "")
11258                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11259                           (const_int 0)))))
11260        (const_string "0")
11261        (const_string "*")))
11262    (set_attr "mode" "QI,SI")])
11263
11264 ;; This pattern can't accept a variable shift count, since shifts by
11265 ;; zero don't affect the flags.  We assume that shifts by constant
11266 ;; zero are optimized away.
11267 (define_insn "*ashlqi3_cmp"
11268   [(set (reg FLAGS_REG)
11269         (compare
11270           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11271                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11272           (const_int 0)))
11273    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11274         (ashift:QI (match_dup 1) (match_dup 2)))]
11275   "(optimize_function_for_size_p (cfun)
11276     || !TARGET_PARTIAL_FLAG_REG_STALL
11277     || (operands[2] == const1_rtx
11278         && (TARGET_SHIFT1
11279             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11280    && ix86_match_ccmode (insn, CCGOCmode)
11281    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11282 {
11283   switch (get_attr_type (insn))
11284     {
11285     case TYPE_ALU:
11286       gcc_assert (operands[2] == const1_rtx);
11287       return "add{b}\t%0, %0";
11288
11289     default:
11290       if (REG_P (operands[2]))
11291         return "sal{b}\t{%b2, %0|%0, %b2}";
11292       else if (operands[2] == const1_rtx
11293                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11294         return "sal{b}\t%0";
11295       else
11296         return "sal{b}\t{%2, %0|%0, %2}";
11297     }
11298 }
11299   [(set (attr "type")
11300      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11301                           (const_int 0))
11302                       (match_operand 0 "register_operand" ""))
11303                  (match_operand 2 "const1_operand" ""))
11304               (const_string "alu")
11305            ]
11306            (const_string "ishift")))
11307    (set (attr "length_immediate")
11308      (if_then_else
11309        (ior (eq_attr "type" "alu")
11310             (and (eq_attr "type" "ishift")
11311                  (and (match_operand 2 "const1_operand" "")
11312                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11313                           (const_int 0)))))
11314        (const_string "0")
11315        (const_string "*")))
11316    (set_attr "mode" "QI")])
11317
11318 (define_insn "*ashlqi3_cconly"
11319   [(set (reg FLAGS_REG)
11320         (compare
11321           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11322                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11323           (const_int 0)))
11324    (clobber (match_scratch:QI 0 "=q"))]
11325   "(optimize_function_for_size_p (cfun)
11326     || !TARGET_PARTIAL_FLAG_REG_STALL
11327     || (operands[2] == const1_rtx
11328         && (TARGET_SHIFT1
11329             || TARGET_DOUBLE_WITH_ADD)))
11330    && ix86_match_ccmode (insn, CCGOCmode)
11331    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11332 {
11333   switch (get_attr_type (insn))
11334     {
11335     case TYPE_ALU:
11336       gcc_assert (operands[2] == const1_rtx);
11337       return "add{b}\t%0, %0";
11338
11339     default:
11340       if (REG_P (operands[2]))
11341         return "sal{b}\t{%b2, %0|%0, %b2}";
11342       else if (operands[2] == const1_rtx
11343                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11344         return "sal{b}\t%0";
11345       else
11346         return "sal{b}\t{%2, %0|%0, %2}";
11347     }
11348 }
11349   [(set (attr "type")
11350      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11351                           (const_int 0))
11352                       (match_operand 0 "register_operand" ""))
11353                  (match_operand 2 "const1_operand" ""))
11354               (const_string "alu")
11355            ]
11356            (const_string "ishift")))
11357    (set (attr "length_immediate")
11358      (if_then_else
11359        (ior (eq_attr "type" "alu")
11360             (and (eq_attr "type" "ishift")
11361                  (and (match_operand 2 "const1_operand" "")
11362                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11363                           (const_int 0)))))
11364        (const_string "0")
11365        (const_string "*")))
11366    (set_attr "mode" "QI")])
11367
11368 ;; See comment above `ashldi3' about how this works.
11369
11370 (define_expand "ashrti3"
11371   [(set (match_operand:TI 0 "register_operand" "")
11372         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11373                      (match_operand:QI 2 "nonmemory_operand" "")))]
11374   "TARGET_64BIT"
11375   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11376
11377 (define_insn "*ashrti3_1"
11378   [(set (match_operand:TI 0 "register_operand" "=r")
11379         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11380                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11381    (clobber (reg:CC FLAGS_REG))]
11382   "TARGET_64BIT"
11383   "#"
11384   [(set_attr "type" "multi")])
11385
11386 (define_peephole2
11387   [(match_scratch:DI 3 "r")
11388    (parallel [(set (match_operand:TI 0 "register_operand" "")
11389                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11390                                 (match_operand:QI 2 "nonmemory_operand" "")))
11391               (clobber (reg:CC FLAGS_REG))])
11392    (match_dup 3)]
11393   "TARGET_64BIT"
11394   [(const_int 0)]
11395   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11396
11397 (define_split
11398   [(set (match_operand:TI 0 "register_operand" "")
11399         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11400                      (match_operand:QI 2 "nonmemory_operand" "")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11403                     ? epilogue_completed : reload_completed)"
11404   [(const_int 0)]
11405   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11406
11407 (define_insn "x86_64_shrd"
11408   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11409         (ior:DI (ashiftrt:DI (match_dup 0)
11410                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11411                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11412                   (minus:QI (const_int 64) (match_dup 2)))))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "TARGET_64BIT"
11415   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11416   [(set_attr "type" "ishift")
11417    (set_attr "prefix_0f" "1")
11418    (set_attr "mode" "DI")
11419    (set_attr "athlon_decode" "vector")
11420    (set_attr "amdfam10_decode" "vector")])
11421
11422 (define_expand "ashrdi3"
11423   [(set (match_operand:DI 0 "shiftdi_operand" "")
11424         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11425                      (match_operand:QI 2 "nonmemory_operand" "")))]
11426   ""
11427   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11428
11429 (define_expand "x86_64_shift_adj_3"
11430   [(use (match_operand:DI 0 "register_operand" ""))
11431    (use (match_operand:DI 1 "register_operand" ""))
11432    (use (match_operand:QI 2 "register_operand" ""))]
11433   ""
11434 {
11435   rtx label = gen_label_rtx ();
11436   rtx tmp;
11437
11438   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11439
11440   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11441   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11442   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11443                               gen_rtx_LABEL_REF (VOIDmode, label),
11444                               pc_rtx);
11445   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11446   JUMP_LABEL (tmp) = label;
11447
11448   emit_move_insn (operands[0], operands[1]);
11449   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11450
11451   emit_label (label);
11452   LABEL_NUSES (label) = 1;
11453
11454   DONE;
11455 })
11456
11457 (define_insn "ashrdi3_63_rex64"
11458   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11459         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11460                      (match_operand:DI 2 "const_int_operand" "i,i")))
11461    (clobber (reg:CC FLAGS_REG))]
11462   "TARGET_64BIT && INTVAL (operands[2]) == 63
11463    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11464    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11465   "@
11466    {cqto|cqo}
11467    sar{q}\t{%2, %0|%0, %2}"
11468   [(set_attr "type" "imovx,ishift")
11469    (set_attr "prefix_0f" "0,*")
11470    (set_attr "length_immediate" "0,*")
11471    (set_attr "modrm" "0,1")
11472    (set_attr "mode" "DI")])
11473
11474 (define_insn "*ashrdi3_1_one_bit_rex64"
11475   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11476         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477                      (match_operand:QI 2 "const1_operand" "")))
11478    (clobber (reg:CC FLAGS_REG))]
11479   "TARGET_64BIT
11480    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11481    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11482   "sar{q}\t%0"
11483   [(set_attr "type" "ishift")
11484    (set_attr "length_immediate" "0")
11485    (set_attr "mode" "DI")])
11486
11487 (define_insn "*ashrdi3_1_rex64"
11488   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11489         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11490                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11491    (clobber (reg:CC FLAGS_REG))]
11492   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11493   "@
11494    sar{q}\t{%2, %0|%0, %2}
11495    sar{q}\t{%b2, %0|%0, %b2}"
11496   [(set_attr "type" "ishift")
11497    (set_attr "mode" "DI")])
11498
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags.  We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11506                        (match_operand:QI 2 "const1_operand" ""))
11507           (const_int 0)))
11508    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11509         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11510   "TARGET_64BIT
11511    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11512    && ix86_match_ccmode (insn, CCGOCmode)
11513    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11514   "sar{q}\t%0"
11515   [(set_attr "type" "ishift")
11516    (set_attr "length_immediate" "0")
11517    (set_attr "mode" "DI")])
11518
11519 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11520   [(set (reg FLAGS_REG)
11521         (compare
11522           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11523                        (match_operand:QI 2 "const1_operand" ""))
11524           (const_int 0)))
11525    (clobber (match_scratch:DI 0 "=r"))]
11526   "TARGET_64BIT
11527    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11528    && ix86_match_ccmode (insn, CCGOCmode)
11529    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11530   "sar{q}\t%0"
11531   [(set_attr "type" "ishift")
11532    (set_attr "length_immediate" "0")
11533    (set_attr "mode" "DI")])
11534
11535 ;; This pattern can't accept a variable shift count, since shifts by
11536 ;; zero don't affect the flags.  We assume that shifts by constant
11537 ;; zero are optimized away.
11538 (define_insn "*ashrdi3_cmp_rex64"
11539   [(set (reg FLAGS_REG)
11540         (compare
11541           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11542                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11543           (const_int 0)))
11544    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11545         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11546   "TARGET_64BIT
11547    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11548    && ix86_match_ccmode (insn, CCGOCmode)
11549    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11550   "sar{q}\t{%2, %0|%0, %2}"
11551   [(set_attr "type" "ishift")
11552    (set_attr "mode" "DI")])
11553
11554 (define_insn "*ashrdi3_cconly_rex64"
11555   [(set (reg FLAGS_REG)
11556         (compare
11557           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11558                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11559           (const_int 0)))
11560    (clobber (match_scratch:DI 0 "=r"))]
11561   "TARGET_64BIT
11562    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11563    && ix86_match_ccmode (insn, CCGOCmode)
11564    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11565   "sar{q}\t{%2, %0|%0, %2}"
11566   [(set_attr "type" "ishift")
11567    (set_attr "mode" "DI")])
11568
11569 (define_insn "*ashrdi3_1"
11570   [(set (match_operand:DI 0 "register_operand" "=r")
11571         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11572                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11573    (clobber (reg:CC FLAGS_REG))]
11574   "!TARGET_64BIT"
11575   "#"
11576   [(set_attr "type" "multi")])
11577
11578 ;; By default we don't ask for a scratch register, because when DImode
11579 ;; values are manipulated, registers are already at a premium.  But if
11580 ;; we have one handy, we won't turn it away.
11581 (define_peephole2
11582   [(match_scratch:SI 3 "r")
11583    (parallel [(set (match_operand:DI 0 "register_operand" "")
11584                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11585                                 (match_operand:QI 2 "nonmemory_operand" "")))
11586               (clobber (reg:CC FLAGS_REG))])
11587    (match_dup 3)]
11588   "!TARGET_64BIT && TARGET_CMOVE"
11589   [(const_int 0)]
11590   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11591
11592 (define_split
11593   [(set (match_operand:DI 0 "register_operand" "")
11594         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11595                      (match_operand:QI 2 "nonmemory_operand" "")))
11596    (clobber (reg:CC FLAGS_REG))]
11597   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11598                      ? epilogue_completed : reload_completed)"
11599   [(const_int 0)]
11600   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11601
11602 (define_insn "x86_shrd"
11603   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11604         (ior:SI (ashiftrt:SI (match_dup 0)
11605                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11606                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11607                   (minus:QI (const_int 32) (match_dup 2)))))
11608    (clobber (reg:CC FLAGS_REG))]
11609   ""
11610   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11611   [(set_attr "type" "ishift")
11612    (set_attr "prefix_0f" "1")
11613    (set_attr "pent_pair" "np")
11614    (set_attr "mode" "SI")])
11615
11616 (define_expand "x86_shift_adj_3"
11617   [(use (match_operand:SI 0 "register_operand" ""))
11618    (use (match_operand:SI 1 "register_operand" ""))
11619    (use (match_operand:QI 2 "register_operand" ""))]
11620   ""
11621 {
11622   rtx label = gen_label_rtx ();
11623   rtx tmp;
11624
11625   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11626
11627   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11628   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11629   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11630                               gen_rtx_LABEL_REF (VOIDmode, label),
11631                               pc_rtx);
11632   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11633   JUMP_LABEL (tmp) = label;
11634
11635   emit_move_insn (operands[0], operands[1]);
11636   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11637
11638   emit_label (label);
11639   LABEL_NUSES (label) = 1;
11640
11641   DONE;
11642 })
11643
11644 (define_expand "ashrsi3_31"
11645   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11646                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11647                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11648               (clobber (reg:CC FLAGS_REG))])]
11649   "")
11650
11651 (define_insn "*ashrsi3_31"
11652   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11653         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11654                      (match_operand:SI 2 "const_int_operand" "i,i")))
11655    (clobber (reg:CC FLAGS_REG))]
11656   "INTVAL (operands[2]) == 31
11657    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11658    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11659   "@
11660    {cltd|cdq}
11661    sar{l}\t{%2, %0|%0, %2}"
11662   [(set_attr "type" "imovx,ishift")
11663    (set_attr "prefix_0f" "0,*")
11664    (set_attr "length_immediate" "0,*")
11665    (set_attr "modrm" "0,1")
11666    (set_attr "mode" "SI")])
11667
11668 (define_insn "*ashrsi3_31_zext"
11669   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11670         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11671                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11672    (clobber (reg:CC FLAGS_REG))]
11673   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11674    && INTVAL (operands[2]) == 31
11675    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11676   "@
11677    {cltd|cdq}
11678    sar{l}\t{%2, %k0|%k0, %2}"
11679   [(set_attr "type" "imovx,ishift")
11680    (set_attr "prefix_0f" "0,*")
11681    (set_attr "length_immediate" "0,*")
11682    (set_attr "modrm" "0,1")
11683    (set_attr "mode" "SI")])
11684
11685 (define_expand "ashrsi3"
11686   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11687         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11688                      (match_operand:QI 2 "nonmemory_operand" "")))]
11689   ""
11690   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11691
11692 (define_insn "*ashrsi3_1_one_bit"
11693   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11694         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11695                      (match_operand:QI 2 "const1_operand" "")))
11696    (clobber (reg:CC FLAGS_REG))]
11697   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11698    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11699   "sar{l}\t%0"
11700   [(set_attr "type" "ishift")
11701    (set_attr "length_immediate" "0")
11702    (set_attr "mode" "SI")])
11703
11704 (define_insn "*ashrsi3_1_one_bit_zext"
11705   [(set (match_operand:DI 0 "register_operand" "=r")
11706         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11707                                      (match_operand:QI 2 "const1_operand" ""))))
11708    (clobber (reg:CC FLAGS_REG))]
11709   "TARGET_64BIT
11710    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11711    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11712   "sar{l}\t%k0"
11713   [(set_attr "type" "ishift")
11714    (set_attr "length_immediate" "0")
11715    (set_attr "mode" "SI")])
11716
11717 (define_insn "*ashrsi3_1"
11718   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11719         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11720                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11723   "@
11724    sar{l}\t{%2, %0|%0, %2}
11725    sar{l}\t{%b2, %0|%0, %b2}"
11726   [(set_attr "type" "ishift")
11727    (set_attr "mode" "SI")])
11728
11729 (define_insn "*ashrsi3_1_zext"
11730   [(set (match_operand:DI 0 "register_operand" "=r,r")
11731         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11732                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11735   "@
11736    sar{l}\t{%2, %k0|%k0, %2}
11737    sar{l}\t{%b2, %k0|%k0, %b2}"
11738   [(set_attr "type" "ishift")
11739    (set_attr "mode" "SI")])
11740
11741 ;; This pattern can't accept a variable shift count, since shifts by
11742 ;; zero don't affect the flags.  We assume that shifts by constant
11743 ;; zero are optimized away.
11744 (define_insn "*ashrsi3_one_bit_cmp"
11745   [(set (reg FLAGS_REG)
11746         (compare
11747           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11748                        (match_operand:QI 2 "const1_operand" ""))
11749           (const_int 0)))
11750    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11751         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11752   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11753    && ix86_match_ccmode (insn, CCGOCmode)
11754    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11755   "sar{l}\t%0"
11756   [(set_attr "type" "ishift")
11757    (set_attr "length_immediate" "0")
11758    (set_attr "mode" "SI")])
11759
11760 (define_insn "*ashrsi3_one_bit_cconly"
11761   [(set (reg FLAGS_REG)
11762         (compare
11763           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11764                        (match_operand:QI 2 "const1_operand" ""))
11765           (const_int 0)))
11766    (clobber (match_scratch:SI 0 "=r"))]
11767   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11768    && ix86_match_ccmode (insn, CCGOCmode)
11769    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11770   "sar{l}\t%0"
11771   [(set_attr "type" "ishift")
11772    (set_attr "length_immediate" "0")
11773    (set_attr "mode" "SI")])
11774
11775 (define_insn "*ashrsi3_one_bit_cmp_zext"
11776   [(set (reg FLAGS_REG)
11777         (compare
11778           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11779                        (match_operand:QI 2 "const1_operand" ""))
11780           (const_int 0)))
11781    (set (match_operand:DI 0 "register_operand" "=r")
11782         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11783   "TARGET_64BIT
11784    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11785    && ix86_match_ccmode (insn, CCmode)
11786    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11787   "sar{l}\t%k0"
11788   [(set_attr "type" "ishift")
11789    (set_attr "length_immediate" "0")
11790    (set_attr "mode" "SI")])
11791
11792 ;; This pattern can't accept a variable shift count, since shifts by
11793 ;; zero don't affect the flags.  We assume that shifts by constant
11794 ;; zero are optimized away.
11795 (define_insn "*ashrsi3_cmp"
11796   [(set (reg FLAGS_REG)
11797         (compare
11798           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11799                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800           (const_int 0)))
11801    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11802         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11803   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11804    && ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11806   "sar{l}\t{%2, %0|%0, %2}"
11807   [(set_attr "type" "ishift")
11808    (set_attr "mode" "SI")])
11809
11810 (define_insn "*ashrsi3_cconly"
11811   [(set (reg FLAGS_REG)
11812         (compare
11813           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11815           (const_int 0)))
11816    (clobber (match_scratch:SI 0 "=r"))]
11817   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11818    && ix86_match_ccmode (insn, CCGOCmode)
11819    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11820   "sar{l}\t{%2, %0|%0, %2}"
11821   [(set_attr "type" "ishift")
11822    (set_attr "mode" "SI")])
11823
11824 (define_insn "*ashrsi3_cmp_zext"
11825   [(set (reg FLAGS_REG)
11826         (compare
11827           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11828                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11829           (const_int 0)))
11830    (set (match_operand:DI 0 "register_operand" "=r")
11831         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11832   "TARGET_64BIT
11833    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11834    && ix86_match_ccmode (insn, CCGOCmode)
11835    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11836   "sar{l}\t{%2, %k0|%k0, %2}"
11837   [(set_attr "type" "ishift")
11838    (set_attr "mode" "SI")])
11839
11840 (define_expand "ashrhi3"
11841   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11842         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11843                      (match_operand:QI 2 "nonmemory_operand" "")))]
11844   "TARGET_HIMODE_MATH"
11845   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11846
11847 (define_insn "*ashrhi3_1_one_bit"
11848   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11849         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11850                      (match_operand:QI 2 "const1_operand" "")))
11851    (clobber (reg:CC FLAGS_REG))]
11852   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11853    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11854   "sar{w}\t%0"
11855   [(set_attr "type" "ishift")
11856    (set_attr "length_immediate" "0")
11857    (set_attr "mode" "HI")])
11858
11859 (define_insn "*ashrhi3_1"
11860   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11861         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11862                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11863    (clobber (reg:CC FLAGS_REG))]
11864   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11865   "@
11866    sar{w}\t{%2, %0|%0, %2}
11867    sar{w}\t{%b2, %0|%0, %b2}"
11868   [(set_attr "type" "ishift")
11869    (set_attr "mode" "HI")])
11870
11871 ;; This pattern can't accept a variable shift count, since shifts by
11872 ;; zero don't affect the flags.  We assume that shifts by constant
11873 ;; zero are optimized away.
11874 (define_insn "*ashrhi3_one_bit_cmp"
11875   [(set (reg FLAGS_REG)
11876         (compare
11877           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11878                        (match_operand:QI 2 "const1_operand" ""))
11879           (const_int 0)))
11880    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11881         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11882   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11883    && ix86_match_ccmode (insn, CCGOCmode)
11884    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11885   "sar{w}\t%0"
11886   [(set_attr "type" "ishift")
11887    (set_attr "length_immediate" "0")
11888    (set_attr "mode" "HI")])
11889
11890 (define_insn "*ashrhi3_one_bit_cconly"
11891   [(set (reg FLAGS_REG)
11892         (compare
11893           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11894                        (match_operand:QI 2 "const1_operand" ""))
11895           (const_int 0)))
11896    (clobber (match_scratch:HI 0 "=r"))]
11897   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11898    && ix86_match_ccmode (insn, CCGOCmode)
11899    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11900   "sar{w}\t%0"
11901   [(set_attr "type" "ishift")
11902    (set_attr "length_immediate" "0")
11903    (set_attr "mode" "HI")])
11904
11905 ;; This pattern can't accept a variable shift count, since shifts by
11906 ;; zero don't affect the flags.  We assume that shifts by constant
11907 ;; zero are optimized away.
11908 (define_insn "*ashrhi3_cmp"
11909   [(set (reg FLAGS_REG)
11910         (compare
11911           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11912                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11913           (const_int 0)))
11914    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11915         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11916   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11917    && ix86_match_ccmode (insn, CCGOCmode)
11918    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11919   "sar{w}\t{%2, %0|%0, %2}"
11920   [(set_attr "type" "ishift")
11921    (set_attr "mode" "HI")])
11922
11923 (define_insn "*ashrhi3_cconly"
11924   [(set (reg FLAGS_REG)
11925         (compare
11926           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11927                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11928           (const_int 0)))
11929    (clobber (match_scratch:HI 0 "=r"))]
11930   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11931    && ix86_match_ccmode (insn, CCGOCmode)
11932    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11933   "sar{w}\t{%2, %0|%0, %2}"
11934   [(set_attr "type" "ishift")
11935    (set_attr "mode" "HI")])
11936
11937 (define_expand "ashrqi3"
11938   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11939         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11940                      (match_operand:QI 2 "nonmemory_operand" "")))]
11941   "TARGET_QIMODE_MATH"
11942   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11943
11944 (define_insn "*ashrqi3_1_one_bit"
11945   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947                      (match_operand:QI 2 "const1_operand" "")))
11948    (clobber (reg:CC FLAGS_REG))]
11949   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11950    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11951   "sar{b}\t%0"
11952   [(set_attr "type" "ishift")
11953    (set_attr "length_immediate" "0")
11954    (set_attr "mode" "QI")])
11955
11956 (define_insn "*ashrqi3_1_one_bit_slp"
11957   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11958         (ashiftrt:QI (match_dup 0)
11959                      (match_operand:QI 1 "const1_operand" "")))
11960    (clobber (reg:CC FLAGS_REG))]
11961   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11962    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11963    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11964   "sar{b}\t%0"
11965   [(set_attr "type" "ishift1")
11966    (set_attr "length_immediate" "0")
11967    (set_attr "mode" "QI")])
11968
11969 (define_insn "*ashrqi3_1"
11970   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11971         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11972                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11975   "@
11976    sar{b}\t{%2, %0|%0, %2}
11977    sar{b}\t{%b2, %0|%0, %b2}"
11978   [(set_attr "type" "ishift")
11979    (set_attr "mode" "QI")])
11980
11981 (define_insn "*ashrqi3_1_slp"
11982   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11983         (ashiftrt:QI (match_dup 0)
11984                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11985    (clobber (reg:CC FLAGS_REG))]
11986   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11987    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11988   "@
11989    sar{b}\t{%1, %0|%0, %1}
11990    sar{b}\t{%b1, %0|%0, %b1}"
11991   [(set_attr "type" "ishift1")
11992    (set_attr "mode" "QI")])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrqi3_one_bit_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const1_operand" "I"))
12002           (const_int 0)))
12003    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12005   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12006    && ix86_match_ccmode (insn, CCGOCmode)
12007    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12008   "sar{b}\t%0"
12009   [(set_attr "type" "ishift")
12010    (set_attr "length_immediate" "0")
12011    (set_attr "mode" "QI")])
12012
12013 (define_insn "*ashrqi3_one_bit_cconly"
12014   [(set (reg FLAGS_REG)
12015         (compare
12016           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12017                        (match_operand:QI 2 "const1_operand" ""))
12018           (const_int 0)))
12019    (clobber (match_scratch:QI 0 "=q"))]
12020   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12021    && ix86_match_ccmode (insn, CCGOCmode)
12022    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12023   "sar{b}\t%0"
12024   [(set_attr "type" "ishift")
12025    (set_attr "length_immediate" "0")
12026    (set_attr "mode" "QI")])
12027
12028 ;; This pattern can't accept a variable shift count, since shifts by
12029 ;; zero don't affect the flags.  We assume that shifts by constant
12030 ;; zero are optimized away.
12031 (define_insn "*ashrqi3_cmp"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036           (const_int 0)))
12037    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12038         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12039   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12040    && ix86_match_ccmode (insn, CCGOCmode)
12041    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12042   "sar{b}\t{%2, %0|%0, %2}"
12043   [(set_attr "type" "ishift")
12044    (set_attr "mode" "QI")])
12045
12046 (define_insn "*ashrqi3_cconly"
12047   [(set (reg FLAGS_REG)
12048         (compare
12049           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12050                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12051           (const_int 0)))
12052    (clobber (match_scratch:QI 0 "=q"))]
12053   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12054    && ix86_match_ccmode (insn, CCGOCmode)
12055    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12056   "sar{b}\t{%2, %0|%0, %2}"
12057   [(set_attr "type" "ishift")
12058    (set_attr "mode" "QI")])
12059
12060 \f
12061 ;; Logical shift instructions
12062
12063 ;; See comment above `ashldi3' about how this works.
12064
12065 (define_expand "lshrti3"
12066   [(set (match_operand:TI 0 "register_operand" "")
12067         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12068                      (match_operand:QI 2 "nonmemory_operand" "")))]
12069   "TARGET_64BIT"
12070   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12071
12072 ;; This pattern must be defined before *lshrti3_1 to prevent
12073 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12074
12075 (define_insn "*avx_lshrti3"
12076   [(set (match_operand:TI 0 "register_operand" "=x")
12077         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12078                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12079   "TARGET_AVX"
12080 {
12081   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12082   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12083 }
12084   [(set_attr "type" "sseishft")
12085    (set_attr "prefix" "vex")
12086    (set_attr "length_immediate" "1")
12087    (set_attr "mode" "TI")])
12088
12089 (define_insn "sse2_lshrti3"
12090   [(set (match_operand:TI 0 "register_operand" "=x")
12091         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12092                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12093   "TARGET_SSE2"
12094 {
12095   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12096   return "psrldq\t{%2, %0|%0, %2}";
12097 }
12098   [(set_attr "type" "sseishft")
12099    (set_attr "prefix_data16" "1")
12100    (set_attr "length_immediate" "1")
12101    (set_attr "mode" "TI")])
12102
12103 (define_insn "*lshrti3_1"
12104   [(set (match_operand:TI 0 "register_operand" "=r")
12105         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12106                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_64BIT"
12109   "#"
12110   [(set_attr "type" "multi")])
12111
12112 (define_peephole2
12113   [(match_scratch:DI 3 "r")
12114    (parallel [(set (match_operand:TI 0 "register_operand" "")
12115                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12116                                 (match_operand:QI 2 "nonmemory_operand" "")))
12117               (clobber (reg:CC FLAGS_REG))])
12118    (match_dup 3)]
12119   "TARGET_64BIT"
12120   [(const_int 0)]
12121   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12122
12123 (define_split
12124   [(set (match_operand:TI 0 "register_operand" "")
12125         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12126                      (match_operand:QI 2 "nonmemory_operand" "")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12129                     ? epilogue_completed : reload_completed)"
12130   [(const_int 0)]
12131   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12132
12133 (define_expand "lshrdi3"
12134   [(set (match_operand:DI 0 "shiftdi_operand" "")
12135         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12136                      (match_operand:QI 2 "nonmemory_operand" "")))]
12137   ""
12138   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12139
12140 (define_insn "*lshrdi3_1_one_bit_rex64"
12141   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12143                      (match_operand:QI 2 "const1_operand" "")))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_64BIT
12146    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12147    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12148   "shr{q}\t%0"
12149   [(set_attr "type" "ishift")
12150    (set_attr "length_immediate" "0")
12151    (set_attr "mode" "DI")])
12152
12153 (define_insn "*lshrdi3_1_rex64"
12154   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12155         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12156                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12159   "@
12160    shr{q}\t{%2, %0|%0, %2}
12161    shr{q}\t{%b2, %0|%0, %b2}"
12162   [(set_attr "type" "ishift")
12163    (set_attr "mode" "DI")])
12164
12165 ;; This pattern can't accept a variable shift count, since shifts by
12166 ;; zero don't affect the flags.  We assume that shifts by constant
12167 ;; zero are optimized away.
12168 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12169   [(set (reg FLAGS_REG)
12170         (compare
12171           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12172                        (match_operand:QI 2 "const1_operand" ""))
12173           (const_int 0)))
12174    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12175         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12176   "TARGET_64BIT
12177    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12178    && ix86_match_ccmode (insn, CCGOCmode)
12179    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12180   "shr{q}\t%0"
12181   [(set_attr "type" "ishift")
12182    (set_attr "length_immediate" "0")
12183    (set_attr "mode" "DI")])
12184
12185 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12186   [(set (reg FLAGS_REG)
12187         (compare
12188           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12189                        (match_operand:QI 2 "const1_operand" ""))
12190           (const_int 0)))
12191    (clobber (match_scratch:DI 0 "=r"))]
12192   "TARGET_64BIT
12193    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12194    && ix86_match_ccmode (insn, CCGOCmode)
12195    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12196   "shr{q}\t%0"
12197   [(set_attr "type" "ishift")
12198    (set_attr "length_immediate" "0")
12199    (set_attr "mode" "DI")])
12200
12201 ;; This pattern can't accept a variable shift count, since shifts by
12202 ;; zero don't affect the flags.  We assume that shifts by constant
12203 ;; zero are optimized away.
12204 (define_insn "*lshrdi3_cmp_rex64"
12205   [(set (reg FLAGS_REG)
12206         (compare
12207           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12208                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12209           (const_int 0)))
12210    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12211         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12212   "TARGET_64BIT
12213    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12214    && ix86_match_ccmode (insn, CCGOCmode)
12215    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12216   "shr{q}\t{%2, %0|%0, %2}"
12217   [(set_attr "type" "ishift")
12218    (set_attr "mode" "DI")])
12219
12220 (define_insn "*lshrdi3_cconly_rex64"
12221   [(set (reg FLAGS_REG)
12222         (compare
12223           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12224                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12225           (const_int 0)))
12226    (clobber (match_scratch:DI 0 "=r"))]
12227   "TARGET_64BIT
12228    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12229    && ix86_match_ccmode (insn, CCGOCmode)
12230    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12231   "shr{q}\t{%2, %0|%0, %2}"
12232   [(set_attr "type" "ishift")
12233    (set_attr "mode" "DI")])
12234
12235 (define_insn "*lshrdi3_1"
12236   [(set (match_operand:DI 0 "register_operand" "=r")
12237         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12238                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12239    (clobber (reg:CC FLAGS_REG))]
12240   "!TARGET_64BIT"
12241   "#"
12242   [(set_attr "type" "multi")])
12243
12244 ;; By default we don't ask for a scratch register, because when DImode
12245 ;; values are manipulated, registers are already at a premium.  But if
12246 ;; we have one handy, we won't turn it away.
12247 (define_peephole2
12248   [(match_scratch:SI 3 "r")
12249    (parallel [(set (match_operand:DI 0 "register_operand" "")
12250                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12251                                 (match_operand:QI 2 "nonmemory_operand" "")))
12252               (clobber (reg:CC FLAGS_REG))])
12253    (match_dup 3)]
12254   "!TARGET_64BIT && TARGET_CMOVE"
12255   [(const_int 0)]
12256   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12257
12258 (define_split
12259   [(set (match_operand:DI 0 "register_operand" "")
12260         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12261                      (match_operand:QI 2 "nonmemory_operand" "")))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12264                      ? epilogue_completed : reload_completed)"
12265   [(const_int 0)]
12266   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12267
12268 (define_expand "lshrsi3"
12269   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12270         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12271                      (match_operand:QI 2 "nonmemory_operand" "")))]
12272   ""
12273   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12274
12275 (define_insn "*lshrsi3_1_one_bit"
12276   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12277         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12278                      (match_operand:QI 2 "const1_operand" "")))
12279    (clobber (reg:CC FLAGS_REG))]
12280   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12281    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12282   "shr{l}\t%0"
12283   [(set_attr "type" "ishift")
12284    (set_attr "length_immediate" "0")
12285    (set_attr "mode" "SI")])
12286
12287 (define_insn "*lshrsi3_1_one_bit_zext"
12288   [(set (match_operand:DI 0 "register_operand" "=r")
12289         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12290                      (match_operand:QI 2 "const1_operand" "")))
12291    (clobber (reg:CC FLAGS_REG))]
12292   "TARGET_64BIT
12293    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12294    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12295   "shr{l}\t%k0"
12296   [(set_attr "type" "ishift")
12297    (set_attr "length_immediate" "0")
12298    (set_attr "mode" "SI")])
12299
12300 (define_insn "*lshrsi3_1"
12301   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12302         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12303                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12306   "@
12307    shr{l}\t{%2, %0|%0, %2}
12308    shr{l}\t{%b2, %0|%0, %b2}"
12309   [(set_attr "type" "ishift")
12310    (set_attr "mode" "SI")])
12311
12312 (define_insn "*lshrsi3_1_zext"
12313   [(set (match_operand:DI 0 "register_operand" "=r,r")
12314         (zero_extend:DI
12315           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12316                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12317    (clobber (reg:CC FLAGS_REG))]
12318   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12319   "@
12320    shr{l}\t{%2, %k0|%k0, %2}
12321    shr{l}\t{%b2, %k0|%k0, %b2}"
12322   [(set_attr "type" "ishift")
12323    (set_attr "mode" "SI")])
12324
12325 ;; This pattern can't accept a variable shift count, since shifts by
12326 ;; zero don't affect the flags.  We assume that shifts by constant
12327 ;; zero are optimized away.
12328 (define_insn "*lshrsi3_one_bit_cmp"
12329   [(set (reg FLAGS_REG)
12330         (compare
12331           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12332                        (match_operand:QI 2 "const1_operand" ""))
12333           (const_int 0)))
12334    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12335         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12336   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12337    && ix86_match_ccmode (insn, CCGOCmode)
12338    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12339   "shr{l}\t%0"
12340   [(set_attr "type" "ishift")
12341    (set_attr "length_immediate" "0")
12342    (set_attr "mode" "SI")])
12343
12344 (define_insn "*lshrsi3_one_bit_cconly"
12345   [(set (reg FLAGS_REG)
12346         (compare
12347           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12348                        (match_operand:QI 2 "const1_operand" ""))
12349           (const_int 0)))
12350    (clobber (match_scratch:SI 0 "=r"))]
12351   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12352    && ix86_match_ccmode (insn, CCGOCmode)
12353    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12354   "shr{l}\t%0"
12355   [(set_attr "type" "ishift")
12356    (set_attr "length_immediate" "0")
12357    (set_attr "mode" "SI")])
12358
12359 (define_insn "*lshrsi3_cmp_one_bit_zext"
12360   [(set (reg FLAGS_REG)
12361         (compare
12362           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12363                        (match_operand:QI 2 "const1_operand" ""))
12364           (const_int 0)))
12365    (set (match_operand:DI 0 "register_operand" "=r")
12366         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12367   "TARGET_64BIT
12368    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12369    && ix86_match_ccmode (insn, CCGOCmode)
12370    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12371   "shr{l}\t%k0"
12372   [(set_attr "type" "ishift")
12373    (set_attr "length_immediate" "0")
12374    (set_attr "mode" "SI")])
12375
12376 ;; This pattern can't accept a variable shift count, since shifts by
12377 ;; zero don't affect the flags.  We assume that shifts by constant
12378 ;; zero are optimized away.
12379 (define_insn "*lshrsi3_cmp"
12380   [(set (reg FLAGS_REG)
12381         (compare
12382           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12383                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12384           (const_int 0)))
12385    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12386         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12387   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12388    && ix86_match_ccmode (insn, CCGOCmode)
12389    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12390   "shr{l}\t{%2, %0|%0, %2}"
12391   [(set_attr "type" "ishift")
12392    (set_attr "mode" "SI")])
12393
12394 (define_insn "*lshrsi3_cconly"
12395   [(set (reg FLAGS_REG)
12396       (compare
12397         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12398                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12399         (const_int 0)))
12400    (clobber (match_scratch:SI 0 "=r"))]
12401   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12402    && ix86_match_ccmode (insn, CCGOCmode)
12403    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12404   "shr{l}\t{%2, %0|%0, %2}"
12405   [(set_attr "type" "ishift")
12406    (set_attr "mode" "SI")])
12407
12408 (define_insn "*lshrsi3_cmp_zext"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12412                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12413           (const_int 0)))
12414    (set (match_operand:DI 0 "register_operand" "=r")
12415         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12416   "TARGET_64BIT
12417    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12418    && ix86_match_ccmode (insn, CCGOCmode)
12419    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12420   "shr{l}\t{%2, %k0|%k0, %2}"
12421   [(set_attr "type" "ishift")
12422    (set_attr "mode" "SI")])
12423
12424 (define_expand "lshrhi3"
12425   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12426         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12427                      (match_operand:QI 2 "nonmemory_operand" "")))]
12428   "TARGET_HIMODE_MATH"
12429   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12430
12431 (define_insn "*lshrhi3_1_one_bit"
12432   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12433         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12434                      (match_operand:QI 2 "const1_operand" "")))
12435    (clobber (reg:CC FLAGS_REG))]
12436   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12437    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12438   "shr{w}\t%0"
12439   [(set_attr "type" "ishift")
12440    (set_attr "length_immediate" "0")
12441    (set_attr "mode" "HI")])
12442
12443 (define_insn "*lshrhi3_1"
12444   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12445         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12446                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12449   "@
12450    shr{w}\t{%2, %0|%0, %2}
12451    shr{w}\t{%b2, %0|%0, %b2}"
12452   [(set_attr "type" "ishift")
12453    (set_attr "mode" "HI")])
12454
12455 ;; This pattern can't accept a variable shift count, since shifts by
12456 ;; zero don't affect the flags.  We assume that shifts by constant
12457 ;; zero are optimized away.
12458 (define_insn "*lshrhi3_one_bit_cmp"
12459   [(set (reg FLAGS_REG)
12460         (compare
12461           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12462                        (match_operand:QI 2 "const1_operand" ""))
12463           (const_int 0)))
12464    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12465         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12466   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12467    && ix86_match_ccmode (insn, CCGOCmode)
12468    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12469   "shr{w}\t%0"
12470   [(set_attr "type" "ishift")
12471    (set_attr "length_immediate" "0")
12472    (set_attr "mode" "HI")])
12473
12474 (define_insn "*lshrhi3_one_bit_cconly"
12475   [(set (reg FLAGS_REG)
12476         (compare
12477           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12478                        (match_operand:QI 2 "const1_operand" ""))
12479           (const_int 0)))
12480    (clobber (match_scratch:HI 0 "=r"))]
12481   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12482    && ix86_match_ccmode (insn, CCGOCmode)
12483    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12484   "shr{w}\t%0"
12485   [(set_attr "type" "ishift")
12486    (set_attr "length_immediate" "0")
12487    (set_attr "mode" "HI")])
12488
12489 ;; This pattern can't accept a variable shift count, since shifts by
12490 ;; zero don't affect the flags.  We assume that shifts by constant
12491 ;; zero are optimized away.
12492 (define_insn "*lshrhi3_cmp"
12493   [(set (reg FLAGS_REG)
12494         (compare
12495           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12496                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12497           (const_int 0)))
12498    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12499         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12500   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12501    && ix86_match_ccmode (insn, CCGOCmode)
12502    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12503   "shr{w}\t{%2, %0|%0, %2}"
12504   [(set_attr "type" "ishift")
12505    (set_attr "mode" "HI")])
12506
12507 (define_insn "*lshrhi3_cconly"
12508   [(set (reg FLAGS_REG)
12509         (compare
12510           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12511                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12512           (const_int 0)))
12513    (clobber (match_scratch:HI 0 "=r"))]
12514   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515    && ix86_match_ccmode (insn, CCGOCmode)
12516    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12517   "shr{w}\t{%2, %0|%0, %2}"
12518   [(set_attr "type" "ishift")
12519    (set_attr "mode" "HI")])
12520
12521 (define_expand "lshrqi3"
12522   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12523         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12524                      (match_operand:QI 2 "nonmemory_operand" "")))]
12525   "TARGET_QIMODE_MATH"
12526   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12527
12528 (define_insn "*lshrqi3_1_one_bit"
12529   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12530         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12531                      (match_operand:QI 2 "const1_operand" "")))
12532    (clobber (reg:CC FLAGS_REG))]
12533   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12534    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12535   "shr{b}\t%0"
12536   [(set_attr "type" "ishift")
12537    (set_attr "length_immediate" "0")
12538    (set_attr "mode" "QI")])
12539
12540 (define_insn "*lshrqi3_1_one_bit_slp"
12541   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12542         (lshiftrt:QI (match_dup 0)
12543                      (match_operand:QI 1 "const1_operand" "")))
12544    (clobber (reg:CC FLAGS_REG))]
12545   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12546    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12547   "shr{b}\t%0"
12548   [(set_attr "type" "ishift1")
12549    (set_attr "length_immediate" "0")
12550    (set_attr "mode" "QI")])
12551
12552 (define_insn "*lshrqi3_1"
12553   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12554         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12555                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12556    (clobber (reg:CC FLAGS_REG))]
12557   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12558   "@
12559    shr{b}\t{%2, %0|%0, %2}
12560    shr{b}\t{%b2, %0|%0, %b2}"
12561   [(set_attr "type" "ishift")
12562    (set_attr "mode" "QI")])
12563
12564 (define_insn "*lshrqi3_1_slp"
12565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12566         (lshiftrt:QI (match_dup 0)
12567                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12568    (clobber (reg:CC FLAGS_REG))]
12569   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12570    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12571   "@
12572    shr{b}\t{%1, %0|%0, %1}
12573    shr{b}\t{%b1, %0|%0, %b1}"
12574   [(set_attr "type" "ishift1")
12575    (set_attr "mode" "QI")])
12576
12577 ;; This pattern can't accept a variable shift count, since shifts by
12578 ;; zero don't affect the flags.  We assume that shifts by constant
12579 ;; zero are optimized away.
12580 (define_insn "*lshrqi2_one_bit_cmp"
12581   [(set (reg FLAGS_REG)
12582         (compare
12583           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12584                        (match_operand:QI 2 "const1_operand" ""))
12585           (const_int 0)))
12586    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12587         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12588   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12589    && ix86_match_ccmode (insn, CCGOCmode)
12590    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12591   "shr{b}\t%0"
12592   [(set_attr "type" "ishift")
12593    (set_attr "length_immediate" "0")
12594    (set_attr "mode" "QI")])
12595
12596 (define_insn "*lshrqi2_one_bit_cconly"
12597   [(set (reg FLAGS_REG)
12598         (compare
12599           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12600                        (match_operand:QI 2 "const1_operand" ""))
12601           (const_int 0)))
12602    (clobber (match_scratch:QI 0 "=q"))]
12603   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12604    && ix86_match_ccmode (insn, CCGOCmode)
12605    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12606   "shr{b}\t%0"
12607   [(set_attr "type" "ishift")
12608    (set_attr "length_immediate" "0")
12609    (set_attr "mode" "QI")])
12610
12611 ;; This pattern can't accept a variable shift count, since shifts by
12612 ;; zero don't affect the flags.  We assume that shifts by constant
12613 ;; zero are optimized away.
12614 (define_insn "*lshrqi2_cmp"
12615   [(set (reg FLAGS_REG)
12616         (compare
12617           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12618                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12619           (const_int 0)))
12620    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12621         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12622   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12623    && ix86_match_ccmode (insn, CCGOCmode)
12624    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12625   "shr{b}\t{%2, %0|%0, %2}"
12626   [(set_attr "type" "ishift")
12627    (set_attr "mode" "QI")])
12628
12629 (define_insn "*lshrqi2_cconly"
12630   [(set (reg FLAGS_REG)
12631         (compare
12632           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12633                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12634           (const_int 0)))
12635    (clobber (match_scratch:QI 0 "=q"))]
12636   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12637    && ix86_match_ccmode (insn, CCGOCmode)
12638    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12639   "shr{b}\t{%2, %0|%0, %2}"
12640   [(set_attr "type" "ishift")
12641    (set_attr "mode" "QI")])
12642 \f
12643 ;; Rotate instructions
12644
12645 (define_expand "rotldi3"
12646   [(set (match_operand:DI 0 "shiftdi_operand" "")
12647         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12648                    (match_operand:QI 2 "nonmemory_operand" "")))]
12649  ""
12650 {
12651   if (TARGET_64BIT)
12652     {
12653       ix86_expand_binary_operator (ROTATE, DImode, operands);
12654       DONE;
12655     }
12656   if (!const_1_to_31_operand (operands[2], VOIDmode))
12657     FAIL;
12658   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12659   DONE;
12660 })
12661
12662 ;; Implement rotation using two double-precision shift instructions
12663 ;; and a scratch register.
12664 (define_insn_and_split "ix86_rotldi3"
12665  [(set (match_operand:DI 0 "register_operand" "=r")
12666        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12667                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12668   (clobber (reg:CC FLAGS_REG))
12669   (clobber (match_scratch:SI 3 "=&r"))]
12670  "!TARGET_64BIT"
12671  ""
12672  "&& reload_completed"
12673  [(set (match_dup 3) (match_dup 4))
12674   (parallel
12675    [(set (match_dup 4)
12676          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12677                  (lshiftrt:SI (match_dup 5)
12678                               (minus:QI (const_int 32) (match_dup 2)))))
12679     (clobber (reg:CC FLAGS_REG))])
12680   (parallel
12681    [(set (match_dup 5)
12682          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12683                  (lshiftrt:SI (match_dup 3)
12684                               (minus:QI (const_int 32) (match_dup 2)))))
12685     (clobber (reg:CC FLAGS_REG))])]
12686  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12687
12688 (define_insn "*rotlsi3_1_one_bit_rex64"
12689   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12690         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12691                    (match_operand:QI 2 "const1_operand" "")))
12692    (clobber (reg:CC FLAGS_REG))]
12693   "TARGET_64BIT
12694    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12695    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12696   "rol{q}\t%0"
12697   [(set_attr "type" "rotate")
12698    (set_attr "length_immediate" "0")
12699    (set_attr "mode" "DI")])
12700
12701 (define_insn "*rotldi3_1_rex64"
12702   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12703         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12704                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12705    (clobber (reg:CC FLAGS_REG))]
12706   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12707   "@
12708    rol{q}\t{%2, %0|%0, %2}
12709    rol{q}\t{%b2, %0|%0, %b2}"
12710   [(set_attr "type" "rotate")
12711    (set_attr "mode" "DI")])
12712
12713 (define_expand "rotlsi3"
12714   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12715         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12716                    (match_operand:QI 2 "nonmemory_operand" "")))]
12717   ""
12718   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12719
12720 (define_insn "*rotlsi3_1_one_bit"
12721   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12722         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12723                    (match_operand:QI 2 "const1_operand" "")))
12724    (clobber (reg:CC FLAGS_REG))]
12725   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12726    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12727   "rol{l}\t%0"
12728   [(set_attr "type" "rotate")
12729    (set_attr "length_immediate" "0")
12730    (set_attr "mode" "SI")])
12731
12732 (define_insn "*rotlsi3_1_one_bit_zext"
12733   [(set (match_operand:DI 0 "register_operand" "=r")
12734         (zero_extend:DI
12735           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12736                      (match_operand:QI 2 "const1_operand" ""))))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "TARGET_64BIT
12739    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12741   "rol{l}\t%k0"
12742   [(set_attr "type" "rotate")
12743    (set_attr "length_immediate" "0")
12744    (set_attr "mode" "SI")])
12745
12746 (define_insn "*rotlsi3_1"
12747   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12748         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12749                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12750    (clobber (reg:CC FLAGS_REG))]
12751   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12752   "@
12753    rol{l}\t{%2, %0|%0, %2}
12754    rol{l}\t{%b2, %0|%0, %b2}"
12755   [(set_attr "type" "rotate")
12756    (set_attr "mode" "SI")])
12757
12758 (define_insn "*rotlsi3_1_zext"
12759   [(set (match_operand:DI 0 "register_operand" "=r,r")
12760         (zero_extend:DI
12761           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12762                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12763    (clobber (reg:CC FLAGS_REG))]
12764   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12765   "@
12766    rol{l}\t{%2, %k0|%k0, %2}
12767    rol{l}\t{%b2, %k0|%k0, %b2}"
12768   [(set_attr "type" "rotate")
12769    (set_attr "mode" "SI")])
12770
12771 (define_expand "rotlhi3"
12772   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12773         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12774                    (match_operand:QI 2 "nonmemory_operand" "")))]
12775   "TARGET_HIMODE_MATH"
12776   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12777
12778 (define_insn "*rotlhi3_1_one_bit"
12779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12780         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12781                    (match_operand:QI 2 "const1_operand" "")))
12782    (clobber (reg:CC FLAGS_REG))]
12783   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12784    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12785   "rol{w}\t%0"
12786   [(set_attr "type" "rotate")
12787    (set_attr "length_immediate" "0")
12788    (set_attr "mode" "HI")])
12789
12790 (define_insn "*rotlhi3_1"
12791   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12792         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12793                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12794    (clobber (reg:CC FLAGS_REG))]
12795   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12796   "@
12797    rol{w}\t{%2, %0|%0, %2}
12798    rol{w}\t{%b2, %0|%0, %b2}"
12799   [(set_attr "type" "rotate")
12800    (set_attr "mode" "HI")])
12801
12802 (define_split
12803  [(set (match_operand:HI 0 "register_operand" "")
12804        (rotate:HI (match_dup 0) (const_int 8)))
12805   (clobber (reg:CC FLAGS_REG))]
12806  "reload_completed"
12807  [(parallel [(set (strict_low_part (match_dup 0))
12808                   (bswap:HI (match_dup 0)))
12809              (clobber (reg:CC FLAGS_REG))])]
12810  "")
12811
12812 (define_expand "rotlqi3"
12813   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12814         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12815                    (match_operand:QI 2 "nonmemory_operand" "")))]
12816   "TARGET_QIMODE_MATH"
12817   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12818
12819 (define_insn "*rotlqi3_1_one_bit_slp"
12820   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12821         (rotate:QI (match_dup 0)
12822                    (match_operand:QI 1 "const1_operand" "")))
12823    (clobber (reg:CC FLAGS_REG))]
12824   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12825    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12826   "rol{b}\t%0"
12827   [(set_attr "type" "rotate1")
12828    (set_attr "length_immediate" "0")
12829    (set_attr "mode" "QI")])
12830
12831 (define_insn "*rotlqi3_1_one_bit"
12832   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12833         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12834                    (match_operand:QI 2 "const1_operand" "")))
12835    (clobber (reg:CC FLAGS_REG))]
12836   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12837    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12838   "rol{b}\t%0"
12839   [(set_attr "type" "rotate")
12840    (set_attr "length_immediate" "0")
12841    (set_attr "mode" "QI")])
12842
12843 (define_insn "*rotlqi3_1_slp"
12844   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12845         (rotate:QI (match_dup 0)
12846                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12847    (clobber (reg:CC FLAGS_REG))]
12848   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12849    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12850   "@
12851    rol{b}\t{%1, %0|%0, %1}
12852    rol{b}\t{%b1, %0|%0, %b1}"
12853   [(set_attr "type" "rotate1")
12854    (set_attr "mode" "QI")])
12855
12856 (define_insn "*rotlqi3_1"
12857   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12858         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12859                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12860    (clobber (reg:CC FLAGS_REG))]
12861   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12862   "@
12863    rol{b}\t{%2, %0|%0, %2}
12864    rol{b}\t{%b2, %0|%0, %b2}"
12865   [(set_attr "type" "rotate")
12866    (set_attr "mode" "QI")])
12867
12868 (define_expand "rotrdi3"
12869   [(set (match_operand:DI 0 "shiftdi_operand" "")
12870         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12871                    (match_operand:QI 2 "nonmemory_operand" "")))]
12872  ""
12873 {
12874   if (TARGET_64BIT)
12875     {
12876       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12877       DONE;
12878     }
12879   if (!const_1_to_31_operand (operands[2], VOIDmode))
12880     FAIL;
12881   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12882   DONE;
12883 })
12884
12885 ;; Implement rotation using two double-precision shift instructions
12886 ;; and a scratch register.
12887 (define_insn_and_split "ix86_rotrdi3"
12888  [(set (match_operand:DI 0 "register_operand" "=r")
12889        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12890                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12891   (clobber (reg:CC FLAGS_REG))
12892   (clobber (match_scratch:SI 3 "=&r"))]
12893  "!TARGET_64BIT"
12894  ""
12895  "&& reload_completed"
12896  [(set (match_dup 3) (match_dup 4))
12897   (parallel
12898    [(set (match_dup 4)
12899          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12900                  (ashift:SI (match_dup 5)
12901                             (minus:QI (const_int 32) (match_dup 2)))))
12902     (clobber (reg:CC FLAGS_REG))])
12903   (parallel
12904    [(set (match_dup 5)
12905          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12906                  (ashift:SI (match_dup 3)
12907                             (minus:QI (const_int 32) (match_dup 2)))))
12908     (clobber (reg:CC FLAGS_REG))])]
12909  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12910
12911 (define_insn "*rotrdi3_1_one_bit_rex64"
12912   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12913         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12914                      (match_operand:QI 2 "const1_operand" "")))
12915    (clobber (reg:CC FLAGS_REG))]
12916   "TARGET_64BIT
12917    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12918    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12919   "ror{q}\t%0"
12920   [(set_attr "type" "rotate")
12921    (set_attr "length_immediate" "0")
12922    (set_attr "mode" "DI")])
12923
12924 (define_insn "*rotrdi3_1_rex64"
12925   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12926         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12927                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12928    (clobber (reg:CC FLAGS_REG))]
12929   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12930   "@
12931    ror{q}\t{%2, %0|%0, %2}
12932    ror{q}\t{%b2, %0|%0, %b2}"
12933   [(set_attr "type" "rotate")
12934    (set_attr "mode" "DI")])
12935
12936 (define_expand "rotrsi3"
12937   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12938         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12939                      (match_operand:QI 2 "nonmemory_operand" "")))]
12940   ""
12941   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12942
12943 (define_insn "*rotrsi3_1_one_bit"
12944   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12945         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12946                      (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12949    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12950   "ror{l}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set_attr "length_immediate" "0")
12953    (set_attr "mode" "SI")])
12954
12955 (define_insn "*rotrsi3_1_one_bit_zext"
12956   [(set (match_operand:DI 0 "register_operand" "=r")
12957         (zero_extend:DI
12958           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12959                        (match_operand:QI 2 "const1_operand" ""))))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "TARGET_64BIT
12962    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12963    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12964   "ror{l}\t%k0"
12965   [(set_attr "type" "rotate")
12966    (set_attr "length_immediate" "0")
12967    (set_attr "mode" "SI")])
12968
12969 (define_insn "*rotrsi3_1"
12970   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12971         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12972                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12975   "@
12976    ror{l}\t{%2, %0|%0, %2}
12977    ror{l}\t{%b2, %0|%0, %b2}"
12978   [(set_attr "type" "rotate")
12979    (set_attr "mode" "SI")])
12980
12981 (define_insn "*rotrsi3_1_zext"
12982   [(set (match_operand:DI 0 "register_operand" "=r,r")
12983         (zero_extend:DI
12984           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12985                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12988   "@
12989    ror{l}\t{%2, %k0|%k0, %2}
12990    ror{l}\t{%b2, %k0|%k0, %b2}"
12991   [(set_attr "type" "rotate")
12992    (set_attr "mode" "SI")])
12993
12994 (define_expand "rotrhi3"
12995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12996         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12997                      (match_operand:QI 2 "nonmemory_operand" "")))]
12998   "TARGET_HIMODE_MATH"
12999   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13000
13001 (define_insn "*rotrhi3_one_bit"
13002   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13003         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13004                      (match_operand:QI 2 "const1_operand" "")))
13005    (clobber (reg:CC FLAGS_REG))]
13006   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13007    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13008   "ror{w}\t%0"
13009   [(set_attr "type" "rotate")
13010    (set_attr "length_immediate" "0")
13011    (set_attr "mode" "HI")])
13012
13013 (define_insn "*rotrhi3_1"
13014   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13015         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13016                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13017    (clobber (reg:CC FLAGS_REG))]
13018   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13019   "@
13020    ror{w}\t{%2, %0|%0, %2}
13021    ror{w}\t{%b2, %0|%0, %b2}"
13022   [(set_attr "type" "rotate")
13023    (set_attr "mode" "HI")])
13024
13025 (define_split
13026  [(set (match_operand:HI 0 "register_operand" "")
13027        (rotatert:HI (match_dup 0) (const_int 8)))
13028   (clobber (reg:CC FLAGS_REG))]
13029  "reload_completed"
13030  [(parallel [(set (strict_low_part (match_dup 0))
13031                   (bswap:HI (match_dup 0)))
13032              (clobber (reg:CC FLAGS_REG))])]
13033  "")
13034
13035 (define_expand "rotrqi3"
13036   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13037         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13038                      (match_operand:QI 2 "nonmemory_operand" "")))]
13039   "TARGET_QIMODE_MATH"
13040   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13041
13042 (define_insn "*rotrqi3_1_one_bit"
13043   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13044         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13045                      (match_operand:QI 2 "const1_operand" "")))
13046    (clobber (reg:CC FLAGS_REG))]
13047   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13048    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13049   "ror{b}\t%0"
13050   [(set_attr "type" "rotate")
13051    (set_attr "length_immediate" "0")
13052    (set_attr "mode" "QI")])
13053
13054 (define_insn "*rotrqi3_1_one_bit_slp"
13055   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13056         (rotatert:QI (match_dup 0)
13057                      (match_operand:QI 1 "const1_operand" "")))
13058    (clobber (reg:CC FLAGS_REG))]
13059   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13060    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13061   "ror{b}\t%0"
13062   [(set_attr "type" "rotate1")
13063    (set_attr "length_immediate" "0")
13064    (set_attr "mode" "QI")])
13065
13066 (define_insn "*rotrqi3_1"
13067   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13068         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13069                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13070    (clobber (reg:CC FLAGS_REG))]
13071   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13072   "@
13073    ror{b}\t{%2, %0|%0, %2}
13074    ror{b}\t{%b2, %0|%0, %b2}"
13075   [(set_attr "type" "rotate")
13076    (set_attr "mode" "QI")])
13077
13078 (define_insn "*rotrqi3_1_slp"
13079   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13080         (rotatert:QI (match_dup 0)
13081                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13082    (clobber (reg:CC FLAGS_REG))]
13083   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13084    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13085   "@
13086    ror{b}\t{%1, %0|%0, %1}
13087    ror{b}\t{%b1, %0|%0, %b1}"
13088   [(set_attr "type" "rotate1")
13089    (set_attr "mode" "QI")])
13090 \f
13091 ;; Bit set / bit test instructions
13092
13093 (define_expand "extv"
13094   [(set (match_operand:SI 0 "register_operand" "")
13095         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13096                          (match_operand:SI 2 "const8_operand" "")
13097                          (match_operand:SI 3 "const8_operand" "")))]
13098   ""
13099 {
13100   /* Handle extractions from %ah et al.  */
13101   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13102     FAIL;
13103
13104   /* From mips.md: extract_bit_field doesn't verify that our source
13105      matches the predicate, so check it again here.  */
13106   if (! ext_register_operand (operands[1], VOIDmode))
13107     FAIL;
13108 })
13109
13110 (define_expand "extzv"
13111   [(set (match_operand:SI 0 "register_operand" "")
13112         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13113                          (match_operand:SI 2 "const8_operand" "")
13114                          (match_operand:SI 3 "const8_operand" "")))]
13115   ""
13116 {
13117   /* Handle extractions from %ah et al.  */
13118   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13119     FAIL;
13120
13121   /* From mips.md: extract_bit_field doesn't verify that our source
13122      matches the predicate, so check it again here.  */
13123   if (! ext_register_operand (operands[1], VOIDmode))
13124     FAIL;
13125 })
13126
13127 (define_expand "insv"
13128   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13129                       (match_operand 1 "const8_operand" "")
13130                       (match_operand 2 "const8_operand" ""))
13131         (match_operand 3 "register_operand" ""))]
13132   ""
13133 {
13134   /* Handle insertions to %ah et al.  */
13135   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13136     FAIL;
13137
13138   /* From mips.md: insert_bit_field doesn't verify that our source
13139      matches the predicate, so check it again here.  */
13140   if (! ext_register_operand (operands[0], VOIDmode))
13141     FAIL;
13142
13143   if (TARGET_64BIT)
13144     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13145   else
13146     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13147
13148   DONE;
13149 })
13150
13151 ;; %%% bts, btr, btc, bt.
13152 ;; In general these instructions are *slow* when applied to memory,
13153 ;; since they enforce atomic operation.  When applied to registers,
13154 ;; it depends on the cpu implementation.  They're never faster than
13155 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13156 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13157 ;; within the instruction itself, so operating on bits in the high
13158 ;; 32-bits of a register becomes easier.
13159 ;;
13160 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13161 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13162 ;; negdf respectively, so they can never be disabled entirely.
13163
13164 (define_insn "*btsq"
13165   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13166                          (const_int 1)
13167                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13168         (const_int 1))
13169    (clobber (reg:CC FLAGS_REG))]
13170   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13171   "bts{q}\t{%1, %0|%0, %1}"
13172   [(set_attr "type" "alu1")
13173    (set_attr "prefix_0f" "1")
13174    (set_attr "mode" "DI")])
13175
13176 (define_insn "*btrq"
13177   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13178                          (const_int 1)
13179                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13180         (const_int 0))
13181    (clobber (reg:CC FLAGS_REG))]
13182   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13183   "btr{q}\t{%1, %0|%0, %1}"
13184   [(set_attr "type" "alu1")
13185    (set_attr "prefix_0f" "1")
13186    (set_attr "mode" "DI")])
13187
13188 (define_insn "*btcq"
13189   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13190                          (const_int 1)
13191                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13192         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13193    (clobber (reg:CC FLAGS_REG))]
13194   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13195   "btc{q}\t{%1, %0|%0, %1}"
13196   [(set_attr "type" "alu1")
13197    (set_attr "prefix_0f" "1")
13198    (set_attr "mode" "DI")])
13199
13200 ;; Allow Nocona to avoid these instructions if a register is available.
13201
13202 (define_peephole2
13203   [(match_scratch:DI 2 "r")
13204    (parallel [(set (zero_extract:DI
13205                      (match_operand:DI 0 "register_operand" "")
13206                      (const_int 1)
13207                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13208                    (const_int 1))
13209               (clobber (reg:CC FLAGS_REG))])]
13210   "TARGET_64BIT && !TARGET_USE_BT"
13211   [(const_int 0)]
13212 {
13213   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13214   rtx op1;
13215
13216   if (HOST_BITS_PER_WIDE_INT >= 64)
13217     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13218   else if (i < HOST_BITS_PER_WIDE_INT)
13219     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13220   else
13221     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13222
13223   op1 = immed_double_const (lo, hi, DImode);
13224   if (i >= 31)
13225     {
13226       emit_move_insn (operands[2], op1);
13227       op1 = operands[2];
13228     }
13229
13230   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13231   DONE;
13232 })
13233
13234 (define_peephole2
13235   [(match_scratch:DI 2 "r")
13236    (parallel [(set (zero_extract:DI
13237                      (match_operand:DI 0 "register_operand" "")
13238                      (const_int 1)
13239                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13240                    (const_int 0))
13241               (clobber (reg:CC FLAGS_REG))])]
13242   "TARGET_64BIT && !TARGET_USE_BT"
13243   [(const_int 0)]
13244 {
13245   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13246   rtx op1;
13247
13248   if (HOST_BITS_PER_WIDE_INT >= 64)
13249     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13250   else if (i < HOST_BITS_PER_WIDE_INT)
13251     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13252   else
13253     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13254
13255   op1 = immed_double_const (~lo, ~hi, DImode);
13256   if (i >= 32)
13257     {
13258       emit_move_insn (operands[2], op1);
13259       op1 = operands[2];
13260     }
13261
13262   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13263   DONE;
13264 })
13265
13266 (define_peephole2
13267   [(match_scratch:DI 2 "r")
13268    (parallel [(set (zero_extract:DI
13269                      (match_operand:DI 0 "register_operand" "")
13270                      (const_int 1)
13271                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13272               (not:DI (zero_extract:DI
13273                         (match_dup 0) (const_int 1) (match_dup 1))))
13274               (clobber (reg:CC FLAGS_REG))])]
13275   "TARGET_64BIT && !TARGET_USE_BT"
13276   [(const_int 0)]
13277 {
13278   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13279   rtx op1;
13280
13281   if (HOST_BITS_PER_WIDE_INT >= 64)
13282     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13283   else if (i < HOST_BITS_PER_WIDE_INT)
13284     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13285   else
13286     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13287
13288   op1 = immed_double_const (lo, hi, DImode);
13289   if (i >= 31)
13290     {
13291       emit_move_insn (operands[2], op1);
13292       op1 = operands[2];
13293     }
13294
13295   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13296   DONE;
13297 })
13298
13299 (define_insn "*btdi_rex64"
13300   [(set (reg:CCC FLAGS_REG)
13301         (compare:CCC
13302           (zero_extract:DI
13303             (match_operand:DI 0 "register_operand" "r")
13304             (const_int 1)
13305             (match_operand:DI 1 "nonmemory_operand" "rN"))
13306           (const_int 0)))]
13307   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13308   "bt{q}\t{%1, %0|%0, %1}"
13309   [(set_attr "type" "alu1")
13310    (set_attr "prefix_0f" "1")
13311    (set_attr "mode" "DI")])
13312
13313 (define_insn "*btsi"
13314   [(set (reg:CCC FLAGS_REG)
13315         (compare:CCC
13316           (zero_extract:SI
13317             (match_operand:SI 0 "register_operand" "r")
13318             (const_int 1)
13319             (match_operand:SI 1 "nonmemory_operand" "rN"))
13320           (const_int 0)))]
13321   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13322   "bt{l}\t{%1, %0|%0, %1}"
13323   [(set_attr "type" "alu1")
13324    (set_attr "prefix_0f" "1")
13325    (set_attr "mode" "SI")])
13326 \f
13327 ;; Store-flag instructions.
13328
13329 ;; For all sCOND expanders, also expand the compare or test insn that
13330 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13331
13332 (define_insn_and_split "*setcc_di_1"
13333   [(set (match_operand:DI 0 "register_operand" "=q")
13334         (match_operator:DI 1 "ix86_comparison_operator"
13335           [(reg FLAGS_REG) (const_int 0)]))]
13336   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13337   "#"
13338   "&& reload_completed"
13339   [(set (match_dup 2) (match_dup 1))
13340    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13341 {
13342   PUT_MODE (operands[1], QImode);
13343   operands[2] = gen_lowpart (QImode, operands[0]);
13344 })
13345
13346 (define_insn_and_split "*setcc_si_1_and"
13347   [(set (match_operand:SI 0 "register_operand" "=q")
13348         (match_operator:SI 1 "ix86_comparison_operator"
13349           [(reg FLAGS_REG) (const_int 0)]))
13350    (clobber (reg:CC FLAGS_REG))]
13351   "!TARGET_PARTIAL_REG_STALL
13352    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13353   "#"
13354   "&& reload_completed"
13355   [(set (match_dup 2) (match_dup 1))
13356    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13357               (clobber (reg:CC FLAGS_REG))])]
13358 {
13359   PUT_MODE (operands[1], QImode);
13360   operands[2] = gen_lowpart (QImode, operands[0]);
13361 })
13362
13363 (define_insn_and_split "*setcc_si_1_movzbl"
13364   [(set (match_operand:SI 0 "register_operand" "=q")
13365         (match_operator:SI 1 "ix86_comparison_operator"
13366           [(reg FLAGS_REG) (const_int 0)]))]
13367   "!TARGET_PARTIAL_REG_STALL
13368    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13369   "#"
13370   "&& reload_completed"
13371   [(set (match_dup 2) (match_dup 1))
13372    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13373 {
13374   PUT_MODE (operands[1], QImode);
13375   operands[2] = gen_lowpart (QImode, operands[0]);
13376 })
13377
13378 (define_insn "*setcc_qi"
13379   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13380         (match_operator:QI 1 "ix86_comparison_operator"
13381           [(reg FLAGS_REG) (const_int 0)]))]
13382   ""
13383   "set%C1\t%0"
13384   [(set_attr "type" "setcc")
13385    (set_attr "mode" "QI")])
13386
13387 (define_insn "*setcc_qi_slp"
13388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13389         (match_operator:QI 1 "ix86_comparison_operator"
13390           [(reg FLAGS_REG) (const_int 0)]))]
13391   ""
13392   "set%C1\t%0"
13393   [(set_attr "type" "setcc")
13394    (set_attr "mode" "QI")])
13395
13396 ;; In general it is not safe to assume too much about CCmode registers,
13397 ;; so simplify-rtx stops when it sees a second one.  Under certain
13398 ;; conditions this is safe on x86, so help combine not create
13399 ;;
13400 ;;      seta    %al
13401 ;;      testb   %al, %al
13402 ;;      sete    %al
13403
13404 (define_split
13405   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13406         (ne:QI (match_operator 1 "ix86_comparison_operator"
13407                  [(reg FLAGS_REG) (const_int 0)])
13408             (const_int 0)))]
13409   ""
13410   [(set (match_dup 0) (match_dup 1))]
13411 {
13412   PUT_MODE (operands[1], QImode);
13413 })
13414
13415 (define_split
13416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13417         (ne:QI (match_operator 1 "ix86_comparison_operator"
13418                  [(reg FLAGS_REG) (const_int 0)])
13419             (const_int 0)))]
13420   ""
13421   [(set (match_dup 0) (match_dup 1))]
13422 {
13423   PUT_MODE (operands[1], QImode);
13424 })
13425
13426 (define_split
13427   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13428         (eq:QI (match_operator 1 "ix86_comparison_operator"
13429                  [(reg FLAGS_REG) (const_int 0)])
13430             (const_int 0)))]
13431   ""
13432   [(set (match_dup 0) (match_dup 1))]
13433 {
13434   rtx new_op1 = copy_rtx (operands[1]);
13435   operands[1] = new_op1;
13436   PUT_MODE (new_op1, QImode);
13437   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13438                                              GET_MODE (XEXP (new_op1, 0))));
13439
13440   /* Make sure that (a) the CCmode we have for the flags is strong
13441      enough for the reversed compare or (b) we have a valid FP compare.  */
13442   if (! ix86_comparison_operator (new_op1, VOIDmode))
13443     FAIL;
13444 })
13445
13446 (define_split
13447   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13448         (eq:QI (match_operator 1 "ix86_comparison_operator"
13449                  [(reg FLAGS_REG) (const_int 0)])
13450             (const_int 0)))]
13451   ""
13452   [(set (match_dup 0) (match_dup 1))]
13453 {
13454   rtx new_op1 = copy_rtx (operands[1]);
13455   operands[1] = new_op1;
13456   PUT_MODE (new_op1, QImode);
13457   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13458                                              GET_MODE (XEXP (new_op1, 0))));
13459
13460   /* Make sure that (a) the CCmode we have for the flags is strong
13461      enough for the reversed compare or (b) we have a valid FP compare.  */
13462   if (! ix86_comparison_operator (new_op1, VOIDmode))
13463     FAIL;
13464 })
13465
13466 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13467 ;; subsequent logical operations are used to imitate conditional moves.
13468 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13469 ;; it directly.
13470
13471 (define_insn "*avx_setcc<mode>"
13472   [(set (match_operand:MODEF 0 "register_operand" "=x")
13473         (match_operator:MODEF 1 "avx_comparison_float_operator"
13474           [(match_operand:MODEF 2 "register_operand" "x")
13475            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13476   "TARGET_AVX"
13477   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13478   [(set_attr "type" "ssecmp")
13479    (set_attr "prefix" "vex")
13480    (set_attr "length_immediate" "1")
13481    (set_attr "mode" "<MODE>")])
13482
13483 (define_insn "*sse_setcc<mode>"
13484   [(set (match_operand:MODEF 0 "register_operand" "=x")
13485         (match_operator:MODEF 1 "sse_comparison_operator"
13486           [(match_operand:MODEF 2 "register_operand" "0")
13487            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13488   "SSE_FLOAT_MODE_P (<MODE>mode)"
13489   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13490   [(set_attr "type" "ssecmp")
13491    (set_attr "length_immediate" "1")
13492    (set_attr "mode" "<MODE>")])
13493 \f
13494 ;; Basic conditional jump instructions.
13495 ;; We ignore the overflow flag for signed branch instructions.
13496
13497 (define_insn "*jcc_1"
13498   [(set (pc)
13499         (if_then_else (match_operator 1 "ix86_comparison_operator"
13500                                       [(reg FLAGS_REG) (const_int 0)])
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   ""
13504   "%+j%C1\t%l0"
13505   [(set_attr "type" "ibr")
13506    (set_attr "modrm" "0")
13507    (set (attr "length")
13508            (if_then_else (and (ge (minus (match_dup 0) (pc))
13509                                   (const_int -126))
13510                               (lt (minus (match_dup 0) (pc))
13511                                   (const_int 128)))
13512              (const_int 2)
13513              (const_int 6)))])
13514
13515 (define_insn "*jcc_2"
13516   [(set (pc)
13517         (if_then_else (match_operator 1 "ix86_comparison_operator"
13518                                       [(reg FLAGS_REG) (const_int 0)])
13519                       (pc)
13520                       (label_ref (match_operand 0 "" ""))))]
13521   ""
13522   "%+j%c1\t%l0"
13523   [(set_attr "type" "ibr")
13524    (set_attr "modrm" "0")
13525    (set (attr "length")
13526            (if_then_else (and (ge (minus (match_dup 0) (pc))
13527                                   (const_int -126))
13528                               (lt (minus (match_dup 0) (pc))
13529                                   (const_int 128)))
13530              (const_int 2)
13531              (const_int 6)))])
13532
13533 ;; In general it is not safe to assume too much about CCmode registers,
13534 ;; so simplify-rtx stops when it sees a second one.  Under certain
13535 ;; conditions this is safe on x86, so help combine not create
13536 ;;
13537 ;;      seta    %al
13538 ;;      testb   %al, %al
13539 ;;      je      Lfoo
13540
13541 (define_split
13542   [(set (pc)
13543         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13544                                       [(reg FLAGS_REG) (const_int 0)])
13545                           (const_int 0))
13546                       (label_ref (match_operand 1 "" ""))
13547                       (pc)))]
13548   ""
13549   [(set (pc)
13550         (if_then_else (match_dup 0)
13551                       (label_ref (match_dup 1))
13552                       (pc)))]
13553 {
13554   PUT_MODE (operands[0], VOIDmode);
13555 })
13556
13557 (define_split
13558   [(set (pc)
13559         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13560                                       [(reg FLAGS_REG) (const_int 0)])
13561                           (const_int 0))
13562                       (label_ref (match_operand 1 "" ""))
13563                       (pc)))]
13564   ""
13565   [(set (pc)
13566         (if_then_else (match_dup 0)
13567                       (label_ref (match_dup 1))
13568                       (pc)))]
13569 {
13570   rtx new_op0 = copy_rtx (operands[0]);
13571   operands[0] = new_op0;
13572   PUT_MODE (new_op0, VOIDmode);
13573   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13574                                              GET_MODE (XEXP (new_op0, 0))));
13575
13576   /* Make sure that (a) the CCmode we have for the flags is strong
13577      enough for the reversed compare or (b) we have a valid FP compare.  */
13578   if (! ix86_comparison_operator (new_op0, VOIDmode))
13579     FAIL;
13580 })
13581
13582 ;; zero_extend in SImode is correct, since this is what combine pass
13583 ;; generates from shift insn with QImode operand.  Actually, the mode of
13584 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13585 ;; appropriate modulo of the bit offset value.
13586
13587 (define_insn_and_split "*jcc_btdi_rex64"
13588   [(set (pc)
13589         (if_then_else (match_operator 0 "bt_comparison_operator"
13590                         [(zero_extract:DI
13591                            (match_operand:DI 1 "register_operand" "r")
13592                            (const_int 1)
13593                            (zero_extend:SI
13594                              (match_operand:QI 2 "register_operand" "r")))
13595                          (const_int 0)])
13596                       (label_ref (match_operand 3 "" ""))
13597                       (pc)))
13598    (clobber (reg:CC FLAGS_REG))]
13599   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13600   "#"
13601   "&& 1"
13602   [(set (reg:CCC FLAGS_REG)
13603         (compare:CCC
13604           (zero_extract:DI
13605             (match_dup 1)
13606             (const_int 1)
13607             (match_dup 2))
13608           (const_int 0)))
13609    (set (pc)
13610         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13611                       (label_ref (match_dup 3))
13612                       (pc)))]
13613 {
13614   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13615
13616   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13617 })
13618
13619 ;; avoid useless masking of bit offset operand
13620 (define_insn_and_split "*jcc_btdi_mask_rex64"
13621   [(set (pc)
13622         (if_then_else (match_operator 0 "bt_comparison_operator"
13623                         [(zero_extract:DI
13624                            (match_operand:DI 1 "register_operand" "r")
13625                            (const_int 1)
13626                            (and:SI
13627                              (match_operand:SI 2 "register_operand" "r")
13628                              (match_operand:SI 3 "const_int_operand" "n")))])
13629                       (label_ref (match_operand 4 "" ""))
13630                       (pc)))
13631    (clobber (reg:CC FLAGS_REG))]
13632   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13633    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13634   "#"
13635   "&& 1"
13636   [(set (reg:CCC FLAGS_REG)
13637         (compare:CCC
13638           (zero_extract:DI
13639             (match_dup 1)
13640             (const_int 1)
13641             (match_dup 2))
13642           (const_int 0)))
13643    (set (pc)
13644         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13645                       (label_ref (match_dup 4))
13646                       (pc)))]
13647 {
13648   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13649
13650   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13651 })
13652
13653 (define_insn_and_split "*jcc_btsi"
13654   [(set (pc)
13655         (if_then_else (match_operator 0 "bt_comparison_operator"
13656                         [(zero_extract:SI
13657                            (match_operand:SI 1 "register_operand" "r")
13658                            (const_int 1)
13659                            (zero_extend:SI
13660                              (match_operand:QI 2 "register_operand" "r")))
13661                          (const_int 0)])
13662                       (label_ref (match_operand 3 "" ""))
13663                       (pc)))
13664    (clobber (reg:CC FLAGS_REG))]
13665   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13666   "#"
13667   "&& 1"
13668   [(set (reg:CCC FLAGS_REG)
13669         (compare:CCC
13670           (zero_extract:SI
13671             (match_dup 1)
13672             (const_int 1)
13673             (match_dup 2))
13674           (const_int 0)))
13675    (set (pc)
13676         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13677                       (label_ref (match_dup 3))
13678                       (pc)))]
13679 {
13680   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13681
13682   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13683 })
13684
13685 ;; avoid useless masking of bit offset operand
13686 (define_insn_and_split "*jcc_btsi_mask"
13687   [(set (pc)
13688         (if_then_else (match_operator 0 "bt_comparison_operator"
13689                         [(zero_extract:SI
13690                            (match_operand:SI 1 "register_operand" "r")
13691                            (const_int 1)
13692                            (and:SI
13693                              (match_operand:SI 2 "register_operand" "r")
13694                              (match_operand:SI 3 "const_int_operand" "n")))])
13695                       (label_ref (match_operand 4 "" ""))
13696                       (pc)))
13697    (clobber (reg:CC FLAGS_REG))]
13698   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13699    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13700   "#"
13701   "&& 1"
13702   [(set (reg:CCC FLAGS_REG)
13703         (compare:CCC
13704           (zero_extract:SI
13705             (match_dup 1)
13706             (const_int 1)
13707             (match_dup 2))
13708           (const_int 0)))
13709    (set (pc)
13710         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13711                       (label_ref (match_dup 4))
13712                       (pc)))]
13713   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13714
13715 (define_insn_and_split "*jcc_btsi_1"
13716   [(set (pc)
13717         (if_then_else (match_operator 0 "bt_comparison_operator"
13718                         [(and:SI
13719                            (lshiftrt:SI
13720                              (match_operand:SI 1 "register_operand" "r")
13721                              (match_operand:QI 2 "register_operand" "r"))
13722                            (const_int 1))
13723                          (const_int 0)])
13724                       (label_ref (match_operand 3 "" ""))
13725                       (pc)))
13726    (clobber (reg:CC FLAGS_REG))]
13727   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13728   "#"
13729   "&& 1"
13730   [(set (reg:CCC FLAGS_REG)
13731         (compare:CCC
13732           (zero_extract:SI
13733             (match_dup 1)
13734             (const_int 1)
13735             (match_dup 2))
13736           (const_int 0)))
13737    (set (pc)
13738         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13739                       (label_ref (match_dup 3))
13740                       (pc)))]
13741 {
13742   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13743
13744   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13745 })
13746
13747 ;; avoid useless masking of bit offset operand
13748 (define_insn_and_split "*jcc_btsi_mask_1"
13749   [(set (pc)
13750         (if_then_else
13751           (match_operator 0 "bt_comparison_operator"
13752             [(and:SI
13753                (lshiftrt:SI
13754                  (match_operand:SI 1 "register_operand" "r")
13755                  (subreg:QI
13756                    (and:SI
13757                      (match_operand:SI 2 "register_operand" "r")
13758                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13759                (const_int 1))
13760              (const_int 0)])
13761           (label_ref (match_operand 4 "" ""))
13762           (pc)))
13763    (clobber (reg:CC FLAGS_REG))]
13764   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13765    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13766   "#"
13767   "&& 1"
13768   [(set (reg:CCC FLAGS_REG)
13769         (compare:CCC
13770           (zero_extract:SI
13771             (match_dup 1)
13772             (const_int 1)
13773             (match_dup 2))
13774           (const_int 0)))
13775    (set (pc)
13776         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13777                       (label_ref (match_dup 4))
13778                       (pc)))]
13779   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13780
13781 ;; Define combination compare-and-branch fp compare instructions to help
13782 ;; combine.
13783
13784 (define_insn "*fp_jcc_3_387"
13785   [(set (pc)
13786         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13787                         [(match_operand 1 "register_operand" "f")
13788                          (match_operand 2 "nonimmediate_operand" "fm")])
13789           (label_ref (match_operand 3 "" ""))
13790           (pc)))
13791    (clobber (reg:CCFP FPSR_REG))
13792    (clobber (reg:CCFP FLAGS_REG))
13793    (clobber (match_scratch:HI 4 "=a"))]
13794   "TARGET_80387
13795    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13796    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13797    && SELECT_CC_MODE (GET_CODE (operands[0]),
13798                       operands[1], operands[2]) == CCFPmode
13799    && !TARGET_CMOVE"
13800   "#")
13801
13802 (define_insn "*fp_jcc_4_387"
13803   [(set (pc)
13804         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13805                         [(match_operand 1 "register_operand" "f")
13806                          (match_operand 2 "nonimmediate_operand" "fm")])
13807           (pc)
13808           (label_ref (match_operand 3 "" ""))))
13809    (clobber (reg:CCFP FPSR_REG))
13810    (clobber (reg:CCFP FLAGS_REG))
13811    (clobber (match_scratch:HI 4 "=a"))]
13812   "TARGET_80387
13813    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13814    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13815    && SELECT_CC_MODE (GET_CODE (operands[0]),
13816                       operands[1], operands[2]) == CCFPmode
13817    && !TARGET_CMOVE"
13818   "#")
13819
13820 (define_insn "*fp_jcc_5_387"
13821   [(set (pc)
13822         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13823                         [(match_operand 1 "register_operand" "f")
13824                          (match_operand 2 "register_operand" "f")])
13825           (label_ref (match_operand 3 "" ""))
13826           (pc)))
13827    (clobber (reg:CCFP FPSR_REG))
13828    (clobber (reg:CCFP FLAGS_REG))
13829    (clobber (match_scratch:HI 4 "=a"))]
13830   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13831    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13832    && !TARGET_CMOVE"
13833   "#")
13834
13835 (define_insn "*fp_jcc_6_387"
13836   [(set (pc)
13837         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13838                         [(match_operand 1 "register_operand" "f")
13839                          (match_operand 2 "register_operand" "f")])
13840           (pc)
13841           (label_ref (match_operand 3 "" ""))))
13842    (clobber (reg:CCFP FPSR_REG))
13843    (clobber (reg:CCFP FLAGS_REG))
13844    (clobber (match_scratch:HI 4 "=a"))]
13845   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13846    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13847    && !TARGET_CMOVE"
13848   "#")
13849
13850 (define_insn "*fp_jcc_7_387"
13851   [(set (pc)
13852         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13853                         [(match_operand 1 "register_operand" "f")
13854                          (match_operand 2 "const0_operand" "")])
13855           (label_ref (match_operand 3 "" ""))
13856           (pc)))
13857    (clobber (reg:CCFP FPSR_REG))
13858    (clobber (reg:CCFP FLAGS_REG))
13859    (clobber (match_scratch:HI 4 "=a"))]
13860   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13861    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13862    && SELECT_CC_MODE (GET_CODE (operands[0]),
13863                       operands[1], operands[2]) == CCFPmode
13864    && !TARGET_CMOVE"
13865   "#")
13866
13867 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13868 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13869 ;; with a precedence over other operators and is always put in the first
13870 ;; place. Swap condition and operands to match ficom instruction.
13871
13872 (define_insn "*fp_jcc_8<mode>_387"
13873   [(set (pc)
13874         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13875                         [(match_operator 1 "float_operator"
13876                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13877                            (match_operand 3 "register_operand" "f,f")])
13878           (label_ref (match_operand 4 "" ""))
13879           (pc)))
13880    (clobber (reg:CCFP FPSR_REG))
13881    (clobber (reg:CCFP FLAGS_REG))
13882    (clobber (match_scratch:HI 5 "=a,a"))]
13883   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13884    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13885    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13886    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13887    && !TARGET_CMOVE"
13888   "#")
13889
13890 (define_split
13891   [(set (pc)
13892         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13893                         [(match_operand 1 "register_operand" "")
13894                          (match_operand 2 "nonimmediate_operand" "")])
13895           (match_operand 3 "" "")
13896           (match_operand 4 "" "")))
13897    (clobber (reg:CCFP FPSR_REG))
13898    (clobber (reg:CCFP FLAGS_REG))]
13899   "reload_completed"
13900   [(const_int 0)]
13901 {
13902   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13903                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13904   DONE;
13905 })
13906
13907 (define_split
13908   [(set (pc)
13909         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13910                         [(match_operand 1 "register_operand" "")
13911                          (match_operand 2 "general_operand" "")])
13912           (match_operand 3 "" "")
13913           (match_operand 4 "" "")))
13914    (clobber (reg:CCFP FPSR_REG))
13915    (clobber (reg:CCFP FLAGS_REG))
13916    (clobber (match_scratch:HI 5 "=a"))]
13917   "reload_completed"
13918   [(const_int 0)]
13919 {
13920   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13921                         operands[3], operands[4], operands[5], NULL_RTX);
13922   DONE;
13923 })
13924
13925 (define_split
13926   [(set (pc)
13927         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13928                         [(match_operator 1 "float_operator"
13929                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13930                            (match_operand 3 "register_operand" "")])
13931           (match_operand 4 "" "")
13932           (match_operand 5 "" "")))
13933    (clobber (reg:CCFP FPSR_REG))
13934    (clobber (reg:CCFP FLAGS_REG))
13935    (clobber (match_scratch:HI 6 "=a"))]
13936   "reload_completed"
13937   [(const_int 0)]
13938 {
13939   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13940   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13941                         operands[3], operands[7],
13942                         operands[4], operands[5], operands[6], NULL_RTX);
13943   DONE;
13944 })
13945
13946 ;; %%% Kill this when reload knows how to do it.
13947 (define_split
13948   [(set (pc)
13949         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13950                         [(match_operator 1 "float_operator"
13951                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13952                            (match_operand 3 "register_operand" "")])
13953           (match_operand 4 "" "")
13954           (match_operand 5 "" "")))
13955    (clobber (reg:CCFP FPSR_REG))
13956    (clobber (reg:CCFP FLAGS_REG))
13957    (clobber (match_scratch:HI 6 "=a"))]
13958   "reload_completed"
13959   [(const_int 0)]
13960 {
13961   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13962   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13963   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13964                         operands[3], operands[7],
13965                         operands[4], operands[5], operands[6], operands[2]);
13966   DONE;
13967 })
13968 \f
13969 ;; Unconditional and other jump instructions
13970
13971 (define_insn "jump"
13972   [(set (pc)
13973         (label_ref (match_operand 0 "" "")))]
13974   ""
13975   "jmp\t%l0"
13976   [(set_attr "type" "ibr")
13977    (set (attr "length")
13978            (if_then_else (and (ge (minus (match_dup 0) (pc))
13979                                   (const_int -126))
13980                               (lt (minus (match_dup 0) (pc))
13981                                   (const_int 128)))
13982              (const_int 2)
13983              (const_int 5)))
13984    (set_attr "modrm" "0")])
13985
13986 (define_expand "indirect_jump"
13987   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13988   ""
13989   "")
13990
13991 (define_insn "*indirect_jump"
13992   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13993   ""
13994   "jmp\t%A0"
13995   [(set_attr "type" "ibr")
13996    (set_attr "length_immediate" "0")])
13997
13998 (define_expand "tablejump"
13999   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14000               (use (label_ref (match_operand 1 "" "")))])]
14001   ""
14002 {
14003   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14004      relative.  Convert the relative address to an absolute address.  */
14005   if (flag_pic)
14006     {
14007       rtx op0, op1;
14008       enum rtx_code code;
14009
14010       /* We can't use @GOTOFF for text labels on VxWorks;
14011          see gotoff_operand.  */
14012       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14013         {
14014           code = PLUS;
14015           op0 = operands[0];
14016           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14017         }
14018       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14019         {
14020           code = PLUS;
14021           op0 = operands[0];
14022           op1 = pic_offset_table_rtx;
14023         }
14024       else
14025         {
14026           code = MINUS;
14027           op0 = pic_offset_table_rtx;
14028           op1 = operands[0];
14029         }
14030
14031       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14032                                          OPTAB_DIRECT);
14033     }
14034 })
14035
14036 (define_insn "*tablejump_1"
14037   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14038    (use (label_ref (match_operand 1 "" "")))]
14039   ""
14040   "jmp\t%A0"
14041   [(set_attr "type" "ibr")
14042    (set_attr "length_immediate" "0")])
14043 \f
14044 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14045
14046 (define_peephole2
14047   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14048    (set (match_operand:QI 1 "register_operand" "")
14049         (match_operator:QI 2 "ix86_comparison_operator"
14050           [(reg FLAGS_REG) (const_int 0)]))
14051    (set (match_operand 3 "q_regs_operand" "")
14052         (zero_extend (match_dup 1)))]
14053   "(peep2_reg_dead_p (3, operands[1])
14054     || operands_match_p (operands[1], operands[3]))
14055    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14056   [(set (match_dup 4) (match_dup 0))
14057    (set (strict_low_part (match_dup 5))
14058         (match_dup 2))]
14059 {
14060   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14061   operands[5] = gen_lowpart (QImode, operands[3]);
14062   ix86_expand_clear (operands[3]);
14063 })
14064
14065 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14066
14067 (define_peephole2
14068   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14069    (set (match_operand:QI 1 "register_operand" "")
14070         (match_operator:QI 2 "ix86_comparison_operator"
14071           [(reg FLAGS_REG) (const_int 0)]))
14072    (parallel [(set (match_operand 3 "q_regs_operand" "")
14073                    (zero_extend (match_dup 1)))
14074               (clobber (reg:CC FLAGS_REG))])]
14075   "(peep2_reg_dead_p (3, operands[1])
14076     || operands_match_p (operands[1], operands[3]))
14077    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14078   [(set (match_dup 4) (match_dup 0))
14079    (set (strict_low_part (match_dup 5))
14080         (match_dup 2))]
14081 {
14082   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14083   operands[5] = gen_lowpart (QImode, operands[3]);
14084   ix86_expand_clear (operands[3]);
14085 })
14086 \f
14087 ;; Call instructions.
14088
14089 ;; The predicates normally associated with named expanders are not properly
14090 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14091 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14092
14093 ;; P6 processors will jump to the address after the decrement when %esp
14094 ;; is used as a call operand, so they will execute return address as a code.
14095 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14096  
14097 ;; Call subroutine returning no value.
14098
14099 (define_expand "call_pop"
14100   [(parallel [(call (match_operand:QI 0 "" "")
14101                     (match_operand:SI 1 "" ""))
14102               (set (reg:SI SP_REG)
14103                    (plus:SI (reg:SI SP_REG)
14104                             (match_operand:SI 3 "" "")))])]
14105   "!TARGET_64BIT"
14106 {
14107   ix86_expand_call (NULL, operands[0], operands[1],
14108                     operands[2], operands[3], 0);
14109   DONE;
14110 })
14111
14112 (define_insn "*call_pop_0"
14113   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14114          (match_operand:SI 1 "" ""))
14115    (set (reg:SI SP_REG)
14116         (plus:SI (reg:SI SP_REG)
14117                  (match_operand:SI 2 "immediate_operand" "")))]
14118   "!TARGET_64BIT"
14119 {
14120   if (SIBLING_CALL_P (insn))
14121     return "jmp\t%P0";
14122   else
14123     return "call\t%P0";
14124 }
14125   [(set_attr "type" "call")])
14126
14127 (define_insn "*call_pop_1"
14128   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14129          (match_operand:SI 1 "" ""))
14130    (set (reg:SI SP_REG)
14131         (plus:SI (reg:SI SP_REG)
14132                  (match_operand:SI 2 "immediate_operand" "i")))]
14133   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14134 {
14135   if (constant_call_address_operand (operands[0], Pmode))
14136     return "call\t%P0";
14137   return "call\t%A0";
14138 }
14139   [(set_attr "type" "call")])
14140
14141 (define_insn "*sibcall_pop_1"
14142   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14143          (match_operand:SI 1 "" ""))
14144    (set (reg:SI SP_REG)
14145         (plus:SI (reg:SI SP_REG)
14146                  (match_operand:SI 2 "immediate_operand" "i,i")))]
14147   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14148   "@
14149    jmp\t%P0
14150    jmp\t%A0"
14151   [(set_attr "type" "call")])
14152
14153 (define_expand "call"
14154   [(call (match_operand:QI 0 "" "")
14155          (match_operand 1 "" ""))
14156    (use (match_operand 2 "" ""))]
14157   ""
14158 {
14159   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14160   DONE;
14161 })
14162
14163 (define_expand "sibcall"
14164   [(call (match_operand:QI 0 "" "")
14165          (match_operand 1 "" ""))
14166    (use (match_operand 2 "" ""))]
14167   ""
14168 {
14169   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14170   DONE;
14171 })
14172
14173 (define_insn "*call_0"
14174   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14175          (match_operand 1 "" ""))]
14176   ""
14177 {
14178   if (SIBLING_CALL_P (insn))
14179     return "jmp\t%P0";
14180   else
14181     return "call\t%P0";
14182 }
14183   [(set_attr "type" "call")])
14184
14185 (define_insn "*call_1"
14186   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14187          (match_operand 1 "" ""))]
14188   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14189 {
14190   if (constant_call_address_operand (operands[0], Pmode))
14191     return "call\t%P0";
14192   return "call\t%A0";
14193 }
14194   [(set_attr "type" "call")])
14195
14196 (define_insn "*sibcall_1"
14197   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14198          (match_operand 1 "" ""))]
14199   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14200   "@
14201    jmp\t%P0
14202    jmp\t%A0"
14203   [(set_attr "type" "call")])
14204
14205 (define_insn "*call_1_rex64"
14206   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14207          (match_operand 1 "" ""))]
14208   "TARGET_64BIT && !SIBLING_CALL_P (insn)
14209    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14210 {
14211   if (constant_call_address_operand (operands[0], Pmode))
14212     return "call\t%P0";
14213   return "call\t%A0";
14214 }
14215   [(set_attr "type" "call")])
14216
14217 (define_insn "*call_1_rex64_ms_sysv"
14218   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14219          (match_operand 1 "" ""))
14220    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14221    (clobber (reg:TI XMM6_REG))
14222    (clobber (reg:TI XMM7_REG))
14223    (clobber (reg:TI XMM8_REG))
14224    (clobber (reg:TI XMM9_REG))
14225    (clobber (reg:TI XMM10_REG))
14226    (clobber (reg:TI XMM11_REG))
14227    (clobber (reg:TI XMM12_REG))
14228    (clobber (reg:TI XMM13_REG))
14229    (clobber (reg:TI XMM14_REG))
14230    (clobber (reg:TI XMM15_REG))
14231    (clobber (reg:DI SI_REG))
14232    (clobber (reg:DI DI_REG))]
14233   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14234 {
14235   if (constant_call_address_operand (operands[0], Pmode))
14236     return "call\t%P0";
14237   return "call\t%A0";
14238 }
14239   [(set_attr "type" "call")])
14240
14241 (define_insn "*call_1_rex64_large"
14242   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14243          (match_operand 1 "" ""))]
14244   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14245   "call\t%A0"
14246   [(set_attr "type" "call")])
14247
14248 (define_insn "*sibcall_1_rex64"
14249   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14250          (match_operand 1 "" ""))]
14251   "TARGET_64BIT && SIBLING_CALL_P (insn)"
14252   "@
14253    jmp\t%P0
14254    jmp\t%A0"
14255   [(set_attr "type" "call")])
14256
14257 ;; Call subroutine, returning value in operand 0
14258 (define_expand "call_value_pop"
14259   [(parallel [(set (match_operand 0 "" "")
14260                    (call (match_operand:QI 1 "" "")
14261                          (match_operand:SI 2 "" "")))
14262               (set (reg:SI SP_REG)
14263                    (plus:SI (reg:SI SP_REG)
14264                             (match_operand:SI 4 "" "")))])]
14265   "!TARGET_64BIT"
14266 {
14267   ix86_expand_call (operands[0], operands[1], operands[2],
14268                     operands[3], operands[4], 0);
14269   DONE;
14270 })
14271
14272 (define_expand "call_value"
14273   [(set (match_operand 0 "" "")
14274         (call (match_operand:QI 1 "" "")
14275               (match_operand:SI 2 "" "")))
14276    (use (match_operand:SI 3 "" ""))]
14277   ;; Operand 3 is not used on the i386.
14278   ""
14279 {
14280   ix86_expand_call (operands[0], operands[1], operands[2],
14281                     operands[3], NULL, 0);
14282   DONE;
14283 })
14284
14285 (define_expand "sibcall_value"
14286   [(set (match_operand 0 "" "")
14287         (call (match_operand:QI 1 "" "")
14288               (match_operand:SI 2 "" "")))
14289    (use (match_operand:SI 3 "" ""))]
14290   ;; Operand 3 is not used on the i386.
14291   ""
14292 {
14293   ix86_expand_call (operands[0], operands[1], operands[2],
14294                     operands[3], NULL, 1);
14295   DONE;
14296 })
14297
14298 ;; Call subroutine returning any type.
14299
14300 (define_expand "untyped_call"
14301   [(parallel [(call (match_operand 0 "" "")
14302                     (const_int 0))
14303               (match_operand 1 "" "")
14304               (match_operand 2 "" "")])]
14305   ""
14306 {
14307   int i;
14308
14309   /* In order to give reg-stack an easier job in validating two
14310      coprocessor registers as containing a possible return value,
14311      simply pretend the untyped call returns a complex long double
14312      value. 
14313
14314      We can't use SSE_REGPARM_MAX here since callee is unprototyped
14315      and should have the default ABI.  */
14316
14317   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14318                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14319                     operands[0], const0_rtx,
14320                     GEN_INT ((TARGET_64BIT
14321                               ? (ix86_abi == SYSV_ABI
14322                                  ? X86_64_SSE_REGPARM_MAX
14323                                  : X86_64_MS_SSE_REGPARM_MAX)
14324                               : X86_32_SSE_REGPARM_MAX)
14325                              - 1),
14326                     NULL, 0);
14327
14328   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14329     {
14330       rtx set = XVECEXP (operands[2], 0, i);
14331       emit_move_insn (SET_DEST (set), SET_SRC (set));
14332     }
14333
14334   /* The optimizer does not know that the call sets the function value
14335      registers we stored in the result block.  We avoid problems by
14336      claiming that all hard registers are used and clobbered at this
14337      point.  */
14338   emit_insn (gen_blockage ());
14339
14340   DONE;
14341 })
14342 \f
14343 ;; Prologue and epilogue instructions
14344
14345 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14346 ;; all of memory.  This blocks insns from being moved across this point.
14347
14348 (define_insn "blockage"
14349   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14350   ""
14351   ""
14352   [(set_attr "length" "0")])
14353
14354 ;; Do not schedule instructions accessing memory across this point.
14355
14356 (define_expand "memory_blockage"
14357   [(set (match_dup 0)
14358         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14359   ""
14360 {
14361   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14362   MEM_VOLATILE_P (operands[0]) = 1;
14363 })
14364
14365 (define_insn "*memory_blockage"
14366   [(set (match_operand:BLK 0 "" "")
14367         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14368   ""
14369   ""
14370   [(set_attr "length" "0")])
14371
14372 ;; As USE insns aren't meaningful after reload, this is used instead
14373 ;; to prevent deleting instructions setting registers for PIC code
14374 (define_insn "prologue_use"
14375   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14376   ""
14377   ""
14378   [(set_attr "length" "0")])
14379
14380 ;; Insn emitted into the body of a function to return from a function.
14381 ;; This is only done if the function's epilogue is known to be simple.
14382 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14383
14384 (define_expand "return"
14385   [(return)]
14386   "ix86_can_use_return_insn_p ()"
14387 {
14388   if (crtl->args.pops_args)
14389     {
14390       rtx popc = GEN_INT (crtl->args.pops_args);
14391       emit_jump_insn (gen_return_pop_internal (popc));
14392       DONE;
14393     }
14394 })
14395
14396 (define_insn "return_internal"
14397   [(return)]
14398   "reload_completed"
14399   "ret"
14400   [(set_attr "length" "1")
14401    (set_attr "atom_unit" "jeu")
14402    (set_attr "length_immediate" "0")
14403    (set_attr "modrm" "0")])
14404
14405 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14406 ;; instruction Athlon and K8 have.
14407
14408 (define_insn "return_internal_long"
14409   [(return)
14410    (unspec [(const_int 0)] UNSPEC_REP)]
14411   "reload_completed"
14412   "rep\;ret"
14413   [(set_attr "length" "2")
14414    (set_attr "atom_unit" "jeu")
14415    (set_attr "length_immediate" "0")
14416    (set_attr "prefix_rep" "1")
14417    (set_attr "modrm" "0")])
14418
14419 (define_insn "return_pop_internal"
14420   [(return)
14421    (use (match_operand:SI 0 "const_int_operand" ""))]
14422   "reload_completed"
14423   "ret\t%0"
14424   [(set_attr "length" "3")
14425    (set_attr "atom_unit" "jeu")
14426    (set_attr "length_immediate" "2")
14427    (set_attr "modrm" "0")])
14428
14429 (define_insn "return_indirect_internal"
14430   [(return)
14431    (use (match_operand:SI 0 "register_operand" "r"))]
14432   "reload_completed"
14433   "jmp\t%A0"
14434   [(set_attr "type" "ibr")
14435    (set_attr "length_immediate" "0")])
14436
14437 (define_insn "nop"
14438   [(const_int 0)]
14439   ""
14440   "nop"
14441   [(set_attr "length" "1")
14442    (set_attr "length_immediate" "0")
14443    (set_attr "modrm" "0")])
14444
14445 (define_insn "vswapmov"
14446   [(set (match_operand:SI 0 "register_operand" "=r")
14447         (match_operand:SI 1 "register_operand" "r"))
14448    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14449   ""
14450   "movl.s\t{%1, %0|%0, %1}"
14451   [(set_attr "length" "2")
14452    (set_attr "length_immediate" "0")
14453    (set_attr "modrm" "0")])
14454
14455 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
14456 ;; branch prediction penalty for the third jump in a 16-byte
14457 ;; block on K8.
14458
14459 (define_insn "pad"
14460   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14461   ""
14462 {
14463 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14464   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14465 #else
14466   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14467      The align insn is used to avoid 3 jump instructions in the row to improve
14468      branch prediction and the benefits hardly outweigh the cost of extra 8
14469      nops on the average inserted by full alignment pseudo operation.  */
14470 #endif
14471   return "";
14472 }
14473   [(set_attr "length" "16")])
14474
14475 (define_expand "prologue"
14476   [(const_int 0)]
14477   ""
14478   "ix86_expand_prologue (); DONE;")
14479
14480 (define_insn "set_got"
14481   [(set (match_operand:SI 0 "register_operand" "=r")
14482         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14483    (clobber (reg:CC FLAGS_REG))]
14484   "!TARGET_64BIT"
14485   { return output_set_got (operands[0], NULL_RTX); }
14486   [(set_attr "type" "multi")
14487    (set_attr "length" "12")])
14488
14489 (define_insn "set_got_labelled"
14490   [(set (match_operand:SI 0 "register_operand" "=r")
14491         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14492          UNSPEC_SET_GOT))
14493    (clobber (reg:CC FLAGS_REG))]
14494   "!TARGET_64BIT"
14495   { return output_set_got (operands[0], operands[1]); }
14496   [(set_attr "type" "multi")
14497    (set_attr "length" "12")])
14498
14499 (define_insn "set_got_rex64"
14500   [(set (match_operand:DI 0 "register_operand" "=r")
14501         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14502   "TARGET_64BIT"
14503   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14504   [(set_attr "type" "lea")
14505    (set_attr "length_address" "4")
14506    (set_attr "mode" "DI")])
14507
14508 (define_insn "set_rip_rex64"
14509   [(set (match_operand:DI 0 "register_operand" "=r")
14510         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14511   "TARGET_64BIT"
14512   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14513   [(set_attr "type" "lea")
14514    (set_attr "length_address" "4")
14515    (set_attr "mode" "DI")])
14516
14517 (define_insn "set_got_offset_rex64"
14518   [(set (match_operand:DI 0 "register_operand" "=r")
14519         (unspec:DI
14520           [(label_ref (match_operand 1 "" ""))]
14521           UNSPEC_SET_GOT_OFFSET))]
14522   "TARGET_64BIT"
14523   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14524   [(set_attr "type" "imov")
14525    (set_attr "length_immediate" "0")
14526    (set_attr "length_address" "8")
14527    (set_attr "mode" "DI")])
14528
14529 (define_expand "epilogue"
14530   [(const_int 0)]
14531   ""
14532   "ix86_expand_epilogue (1); DONE;")
14533
14534 (define_expand "sibcall_epilogue"
14535   [(const_int 0)]
14536   ""
14537   "ix86_expand_epilogue (0); DONE;")
14538
14539 (define_expand "eh_return"
14540   [(use (match_operand 0 "register_operand" ""))]
14541   ""
14542 {
14543   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14544
14545   /* Tricky bit: we write the address of the handler to which we will
14546      be returning into someone else's stack frame, one word below the
14547      stack address we wish to restore.  */
14548   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14549   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14550   tmp = gen_rtx_MEM (Pmode, tmp);
14551   emit_move_insn (tmp, ra);
14552
14553   emit_jump_insn (gen_eh_return_internal ());
14554   emit_barrier ();
14555   DONE;
14556 })
14557
14558 (define_insn_and_split "eh_return_internal"
14559   [(eh_return)]
14560   ""
14561   "#"
14562   "epilogue_completed"
14563   [(const_int 0)]
14564   "ix86_expand_epilogue (2); DONE;")
14565
14566 (define_insn "leave"
14567   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14568    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14569    (clobber (mem:BLK (scratch)))]
14570   "!TARGET_64BIT"
14571   "leave"
14572   [(set_attr "type" "leave")])
14573
14574 (define_insn "leave_rex64"
14575   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14576    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14577    (clobber (mem:BLK (scratch)))]
14578   "TARGET_64BIT"
14579   "leave"
14580   [(set_attr "type" "leave")])
14581 \f
14582 (define_expand "ffssi2"
14583   [(parallel
14584      [(set (match_operand:SI 0 "register_operand" "")
14585            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14586       (clobber (match_scratch:SI 2 ""))
14587       (clobber (reg:CC FLAGS_REG))])]
14588   ""
14589 {
14590   if (TARGET_CMOVE)
14591     {
14592       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14593       DONE;
14594     }
14595 })
14596
14597 (define_expand "ffs_cmove"
14598   [(set (match_dup 2) (const_int -1))
14599    (parallel [(set (reg:CCZ FLAGS_REG)
14600                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14601                                 (const_int 0)))
14602               (set (match_operand:SI 0 "register_operand" "")
14603                    (ctz:SI (match_dup 1)))])
14604    (set (match_dup 0) (if_then_else:SI
14605                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14606                         (match_dup 2)
14607                         (match_dup 0)))
14608    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14609               (clobber (reg:CC FLAGS_REG))])]
14610   "TARGET_CMOVE"
14611   "operands[2] = gen_reg_rtx (SImode);")
14612
14613 (define_insn_and_split "*ffs_no_cmove"
14614   [(set (match_operand:SI 0 "register_operand" "=r")
14615         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14616    (clobber (match_scratch:SI 2 "=&q"))
14617    (clobber (reg:CC FLAGS_REG))]
14618   "!TARGET_CMOVE"
14619   "#"
14620   "&& reload_completed"
14621   [(parallel [(set (reg:CCZ FLAGS_REG)
14622                    (compare:CCZ (match_dup 1) (const_int 0)))
14623               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14624    (set (strict_low_part (match_dup 3))
14625         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14626    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14627               (clobber (reg:CC FLAGS_REG))])
14628    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14629               (clobber (reg:CC FLAGS_REG))])
14630    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14631               (clobber (reg:CC FLAGS_REG))])]
14632 {
14633   operands[3] = gen_lowpart (QImode, operands[2]);
14634   ix86_expand_clear (operands[2]);
14635 })
14636
14637 (define_insn "*ffssi_1"
14638   [(set (reg:CCZ FLAGS_REG)
14639         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14640                      (const_int 0)))
14641    (set (match_operand:SI 0 "register_operand" "=r")
14642         (ctz:SI (match_dup 1)))]
14643   ""
14644   "bsf{l}\t{%1, %0|%0, %1}"
14645   [(set_attr "type" "alu1")
14646    (set_attr "prefix_0f" "1")
14647    (set_attr "mode" "SI")])
14648
14649 (define_expand "ffsdi2"
14650   [(set (match_dup 2) (const_int -1))
14651    (parallel [(set (reg:CCZ FLAGS_REG)
14652                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14653                                 (const_int 0)))
14654               (set (match_operand:DI 0 "register_operand" "")
14655                    (ctz:DI (match_dup 1)))])
14656    (set (match_dup 0) (if_then_else:DI
14657                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14658                         (match_dup 2)
14659                         (match_dup 0)))
14660    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14661               (clobber (reg:CC FLAGS_REG))])]
14662   "TARGET_64BIT"
14663   "operands[2] = gen_reg_rtx (DImode);")
14664
14665 (define_insn "*ffsdi_1"
14666   [(set (reg:CCZ FLAGS_REG)
14667         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14668                      (const_int 0)))
14669    (set (match_operand:DI 0 "register_operand" "=r")
14670         (ctz:DI (match_dup 1)))]
14671   "TARGET_64BIT"
14672   "bsf{q}\t{%1, %0|%0, %1}"
14673   [(set_attr "type" "alu1")
14674    (set_attr "prefix_0f" "1")
14675    (set_attr "mode" "DI")])
14676
14677 (define_insn "ctzsi2"
14678   [(set (match_operand:SI 0 "register_operand" "=r")
14679         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14680    (clobber (reg:CC FLAGS_REG))]
14681   ""
14682   "bsf{l}\t{%1, %0|%0, %1}"
14683   [(set_attr "type" "alu1")
14684    (set_attr "prefix_0f" "1")
14685    (set_attr "mode" "SI")])
14686
14687 (define_insn "ctzdi2"
14688   [(set (match_operand:DI 0 "register_operand" "=r")
14689         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14690    (clobber (reg:CC FLAGS_REG))]
14691   "TARGET_64BIT"
14692   "bsf{q}\t{%1, %0|%0, %1}"
14693   [(set_attr "type" "alu1")
14694    (set_attr "prefix_0f" "1")
14695    (set_attr "mode" "DI")])
14696
14697 (define_expand "clzsi2"
14698   [(parallel
14699      [(set (match_operand:SI 0 "register_operand" "")
14700            (minus:SI (const_int 31)
14701                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14702       (clobber (reg:CC FLAGS_REG))])
14703    (parallel
14704      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14705       (clobber (reg:CC FLAGS_REG))])]
14706   ""
14707 {
14708   if (TARGET_ABM)
14709     {
14710       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14711       DONE;
14712     }
14713 })
14714
14715 (define_insn "clzsi2_abm"
14716   [(set (match_operand:SI 0 "register_operand" "=r")
14717         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14718    (clobber (reg:CC FLAGS_REG))]
14719   "TARGET_ABM"
14720   "lzcnt{l}\t{%1, %0|%0, %1}"
14721   [(set_attr "prefix_rep" "1")
14722    (set_attr "type" "bitmanip")
14723    (set_attr "mode" "SI")])
14724
14725 (define_insn "bsr"
14726   [(set (match_operand:SI 0 "register_operand" "=r")
14727         (minus:SI (const_int 31)
14728                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14729    (clobber (reg:CC FLAGS_REG))]
14730   ""
14731   "bsr{l}\t{%1, %0|%0, %1}"
14732   [(set_attr "type" "alu1")
14733    (set_attr "prefix_0f" "1")
14734    (set_attr "mode" "SI")])
14735
14736 (define_insn "popcount<mode>2"
14737   [(set (match_operand:SWI248 0 "register_operand" "=r")
14738         (popcount:SWI248
14739           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14740    (clobber (reg:CC FLAGS_REG))]
14741   "TARGET_POPCNT"
14742 {
14743 #if TARGET_MACHO
14744   return "popcnt\t{%1, %0|%0, %1}";
14745 #else
14746   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14747 #endif
14748 }
14749   [(set_attr "prefix_rep" "1")
14750    (set_attr "type" "bitmanip")
14751    (set_attr "mode" "<MODE>")])
14752
14753 (define_insn "*popcount<mode>2_cmp"
14754   [(set (reg FLAGS_REG)
14755         (compare
14756           (popcount:SWI248
14757             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14758           (const_int 0)))
14759    (set (match_operand:SWI248 0 "register_operand" "=r")
14760         (popcount:SWI248 (match_dup 1)))]
14761   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14762 {
14763 #if TARGET_MACHO
14764   return "popcnt\t{%1, %0|%0, %1}";
14765 #else
14766   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14767 #endif
14768 }
14769   [(set_attr "prefix_rep" "1")
14770    (set_attr "type" "bitmanip")
14771    (set_attr "mode" "<MODE>")])
14772
14773 (define_insn "*popcountsi2_cmp_zext"
14774   [(set (reg FLAGS_REG)
14775         (compare
14776           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14777           (const_int 0)))
14778    (set (match_operand:DI 0 "register_operand" "=r")
14779         (zero_extend:DI(popcount:SI (match_dup 1))))]
14780   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14781 {
14782 #if TARGET_MACHO
14783   return "popcnt\t{%1, %0|%0, %1}";
14784 #else
14785   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14786 #endif
14787 }
14788   [(set_attr "prefix_rep" "1")
14789    (set_attr "type" "bitmanip")
14790    (set_attr "mode" "SI")])
14791
14792 (define_expand "bswapsi2"
14793   [(set (match_operand:SI 0 "register_operand" "")
14794         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14795   ""
14796 {
14797   if (!(TARGET_BSWAP || TARGET_MOVBE))
14798     {
14799       rtx x = operands[0];
14800
14801       emit_move_insn (x, operands[1]);
14802       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14803       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14804       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14805       DONE;
14806     }
14807 })
14808
14809 (define_insn "*bswapsi_movbe"
14810   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14811         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14812   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14813   "@
14814     bswap\t%0
14815     movbe\t{%1, %0|%0, %1}
14816     movbe\t{%1, %0|%0, %1}"
14817   [(set_attr "type" "*,imov,imov")
14818    (set_attr "modrm" "*,1,1")
14819    (set_attr "prefix_0f" "1")
14820    (set_attr "prefix_extra" "*,1,1")
14821    (set_attr "length" "2,*,*")
14822    (set_attr "mode" "SI")])
14823
14824 (define_insn "*bswapsi_1"
14825   [(set (match_operand:SI 0 "register_operand" "=r")
14826         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14827   "TARGET_BSWAP"
14828   "bswap\t%0"
14829   [(set_attr "prefix_0f" "1")
14830    (set_attr "length" "2")])
14831
14832 (define_insn "*bswaphi_lowpart_1"
14833   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14834         (bswap:HI (match_dup 0)))
14835    (clobber (reg:CC FLAGS_REG))]
14836   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14837   "@
14838     xchg{b}\t{%h0, %b0|%b0, %h0}
14839     rol{w}\t{$8, %0|%0, 8}"
14840   [(set_attr "length" "2,4")
14841    (set_attr "mode" "QI,HI")])
14842
14843 (define_insn "bswaphi_lowpart"
14844   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14845         (bswap:HI (match_dup 0)))
14846    (clobber (reg:CC FLAGS_REG))]
14847   ""
14848   "rol{w}\t{$8, %0|%0, 8}"
14849   [(set_attr "length" "4")
14850    (set_attr "mode" "HI")])
14851
14852 (define_expand "bswapdi2"
14853   [(set (match_operand:DI 0 "register_operand" "")
14854         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14855   "TARGET_64BIT"
14856   "")
14857
14858 (define_insn "*bswapdi_movbe"
14859   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14860         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14861   "TARGET_64BIT && TARGET_MOVBE
14862    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14863   "@
14864     bswap\t%0
14865     movbe\t{%1, %0|%0, %1}
14866     movbe\t{%1, %0|%0, %1}"
14867   [(set_attr "type" "*,imov,imov")
14868    (set_attr "modrm" "*,1,1")
14869    (set_attr "prefix_0f" "1")
14870    (set_attr "prefix_extra" "*,1,1")
14871    (set_attr "length" "3,*,*")
14872    (set_attr "mode" "DI")])
14873
14874 (define_insn "*bswapdi_1"
14875   [(set (match_operand:DI 0 "register_operand" "=r")
14876         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14877   "TARGET_64BIT"
14878   "bswap\t%0"
14879   [(set_attr "prefix_0f" "1")
14880    (set_attr "length" "3")])
14881
14882 (define_expand "clzdi2"
14883   [(parallel
14884      [(set (match_operand:DI 0 "register_operand" "")
14885            (minus:DI (const_int 63)
14886                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14887       (clobber (reg:CC FLAGS_REG))])
14888    (parallel
14889      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14890       (clobber (reg:CC FLAGS_REG))])]
14891   "TARGET_64BIT"
14892 {
14893   if (TARGET_ABM)
14894     {
14895       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14896       DONE;
14897     }
14898 })
14899
14900 (define_insn "clzdi2_abm"
14901   [(set (match_operand:DI 0 "register_operand" "=r")
14902         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14903    (clobber (reg:CC FLAGS_REG))]
14904   "TARGET_64BIT && TARGET_ABM"
14905   "lzcnt{q}\t{%1, %0|%0, %1}"
14906   [(set_attr "prefix_rep" "1")
14907    (set_attr "type" "bitmanip")
14908    (set_attr "mode" "DI")])
14909
14910 (define_insn "bsr_rex64"
14911   [(set (match_operand:DI 0 "register_operand" "=r")
14912         (minus:DI (const_int 63)
14913                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14914    (clobber (reg:CC FLAGS_REG))]
14915   "TARGET_64BIT"
14916   "bsr{q}\t{%1, %0|%0, %1}"
14917   [(set_attr "type" "alu1")
14918    (set_attr "prefix_0f" "1")
14919    (set_attr "mode" "DI")])
14920
14921 (define_expand "clzhi2"
14922   [(parallel
14923      [(set (match_operand:HI 0 "register_operand" "")
14924            (minus:HI (const_int 15)
14925                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14926       (clobber (reg:CC FLAGS_REG))])
14927    (parallel
14928      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14929       (clobber (reg:CC FLAGS_REG))])]
14930   ""
14931 {
14932   if (TARGET_ABM)
14933     {
14934       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14935       DONE;
14936     }
14937 })
14938
14939 (define_insn "clzhi2_abm"
14940   [(set (match_operand:HI 0 "register_operand" "=r")
14941         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14942    (clobber (reg:CC FLAGS_REG))]
14943   "TARGET_ABM"
14944   "lzcnt{w}\t{%1, %0|%0, %1}"
14945   [(set_attr "prefix_rep" "1")
14946    (set_attr "type" "bitmanip")
14947    (set_attr "mode" "HI")])
14948
14949 (define_insn "*bsrhi"
14950   [(set (match_operand:HI 0 "register_operand" "=r")
14951         (minus:HI (const_int 15)
14952                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14953    (clobber (reg:CC FLAGS_REG))]
14954   ""
14955   "bsr{w}\t{%1, %0|%0, %1}"
14956   [(set_attr "type" "alu1")
14957    (set_attr "prefix_0f" "1")
14958    (set_attr "mode" "HI")])
14959
14960 (define_expand "paritydi2"
14961   [(set (match_operand:DI 0 "register_operand" "")
14962         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14963   "! TARGET_POPCNT"
14964 {
14965   rtx scratch = gen_reg_rtx (QImode);
14966   rtx cond;
14967
14968   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14969                                 NULL_RTX, operands[1]));
14970
14971   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14972                          gen_rtx_REG (CCmode, FLAGS_REG),
14973                          const0_rtx);
14974   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14975
14976   if (TARGET_64BIT)
14977     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14978   else
14979     {
14980       rtx tmp = gen_reg_rtx (SImode);
14981
14982       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14983       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14984     }
14985   DONE;
14986 })
14987
14988 (define_insn_and_split "paritydi2_cmp"
14989   [(set (reg:CC FLAGS_REG)
14990         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14991    (clobber (match_scratch:DI 0 "=r"))
14992    (clobber (match_scratch:SI 1 "=&r"))
14993    (clobber (match_scratch:HI 2 "=Q"))]
14994   "! TARGET_POPCNT"
14995   "#"
14996   "&& reload_completed"
14997   [(parallel
14998      [(set (match_dup 1)
14999            (xor:SI (match_dup 1) (match_dup 4)))
15000       (clobber (reg:CC FLAGS_REG))])
15001    (parallel
15002      [(set (reg:CC FLAGS_REG)
15003            (parity:CC (match_dup 1)))
15004       (clobber (match_dup 1))
15005       (clobber (match_dup 2))])]
15006 {
15007   operands[4] = gen_lowpart (SImode, operands[3]);
15008
15009   if (TARGET_64BIT)
15010     {
15011       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15012       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15013     }
15014   else
15015     operands[1] = gen_highpart (SImode, operands[3]);
15016 })
15017
15018 (define_expand "paritysi2"
15019   [(set (match_operand:SI 0 "register_operand" "")
15020         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15021   "! TARGET_POPCNT"
15022 {
15023   rtx scratch = gen_reg_rtx (QImode);
15024   rtx cond;
15025
15026   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15027
15028   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15029                          gen_rtx_REG (CCmode, FLAGS_REG),
15030                          const0_rtx);
15031   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15032
15033   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15034   DONE;
15035 })
15036
15037 (define_insn_and_split "paritysi2_cmp"
15038   [(set (reg:CC FLAGS_REG)
15039         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15040    (clobber (match_scratch:SI 0 "=r"))
15041    (clobber (match_scratch:HI 1 "=&Q"))]
15042   "! TARGET_POPCNT"
15043   "#"
15044   "&& reload_completed"
15045   [(parallel
15046      [(set (match_dup 1)
15047            (xor:HI (match_dup 1) (match_dup 3)))
15048       (clobber (reg:CC FLAGS_REG))])
15049    (parallel
15050      [(set (reg:CC FLAGS_REG)
15051            (parity:CC (match_dup 1)))
15052       (clobber (match_dup 1))])]
15053 {
15054   operands[3] = gen_lowpart (HImode, operands[2]);
15055
15056   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15057   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15058 })
15059
15060 (define_insn "*parityhi2_cmp"
15061   [(set (reg:CC FLAGS_REG)
15062         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15063    (clobber (match_scratch:HI 0 "=Q"))]
15064   "! TARGET_POPCNT"
15065   "xor{b}\t{%h0, %b0|%b0, %h0}"
15066   [(set_attr "length" "2")
15067    (set_attr "mode" "HI")])
15068
15069 (define_insn "*parityqi2_cmp"
15070   [(set (reg:CC FLAGS_REG)
15071         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15072   "! TARGET_POPCNT"
15073   "test{b}\t%0, %0"
15074   [(set_attr "length" "2")
15075    (set_attr "mode" "QI")])
15076 \f
15077 ;; Thread-local storage patterns for ELF.
15078 ;;
15079 ;; Note that these code sequences must appear exactly as shown
15080 ;; in order to allow linker relaxation.
15081
15082 (define_insn "*tls_global_dynamic_32_gnu"
15083   [(set (match_operand:SI 0 "register_operand" "=a")
15084         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15085                     (match_operand:SI 2 "tls_symbolic_operand" "")
15086                     (match_operand:SI 3 "call_insn_operand" "")]
15087                     UNSPEC_TLS_GD))
15088    (clobber (match_scratch:SI 4 "=d"))
15089    (clobber (match_scratch:SI 5 "=c"))
15090    (clobber (reg:CC FLAGS_REG))]
15091   "!TARGET_64BIT && TARGET_GNU_TLS"
15092   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15093   [(set_attr "type" "multi")
15094    (set_attr "length" "12")])
15095
15096 (define_insn "*tls_global_dynamic_32_sun"
15097   [(set (match_operand:SI 0 "register_operand" "=a")
15098         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15099                     (match_operand:SI 2 "tls_symbolic_operand" "")
15100                     (match_operand:SI 3 "call_insn_operand" "")]
15101                     UNSPEC_TLS_GD))
15102    (clobber (match_scratch:SI 4 "=d"))
15103    (clobber (match_scratch:SI 5 "=c"))
15104    (clobber (reg:CC FLAGS_REG))]
15105   "!TARGET_64BIT && TARGET_SUN_TLS"
15106   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15107         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15108   [(set_attr "type" "multi")
15109    (set_attr "length" "14")])
15110
15111 (define_expand "tls_global_dynamic_32"
15112   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15113                    (unspec:SI
15114                     [(match_dup 2)
15115                      (match_operand:SI 1 "tls_symbolic_operand" "")
15116                      (match_dup 3)]
15117                     UNSPEC_TLS_GD))
15118               (clobber (match_scratch:SI 4 ""))
15119               (clobber (match_scratch:SI 5 ""))
15120               (clobber (reg:CC FLAGS_REG))])]
15121   ""
15122 {
15123   if (flag_pic)
15124     operands[2] = pic_offset_table_rtx;
15125   else
15126     {
15127       operands[2] = gen_reg_rtx (Pmode);
15128       emit_insn (gen_set_got (operands[2]));
15129     }
15130   if (TARGET_GNU2_TLS)
15131     {
15132        emit_insn (gen_tls_dynamic_gnu2_32
15133                   (operands[0], operands[1], operands[2]));
15134        DONE;
15135     }
15136   operands[3] = ix86_tls_get_addr ();
15137 })
15138
15139 (define_insn "*tls_global_dynamic_64"
15140   [(set (match_operand:DI 0 "register_operand" "=a")
15141         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15142                  (match_operand:DI 3 "" "")))
15143    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15144               UNSPEC_TLS_GD)]
15145   "TARGET_64BIT"
15146   { 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"; }
15147   [(set_attr "type" "multi")
15148    (set_attr "length" "16")])
15149
15150 (define_expand "tls_global_dynamic_64"
15151   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15152                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15153               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15154                          UNSPEC_TLS_GD)])]
15155   ""
15156 {
15157   if (TARGET_GNU2_TLS)
15158     {
15159        emit_insn (gen_tls_dynamic_gnu2_64
15160                   (operands[0], operands[1]));
15161        DONE;
15162     }
15163   operands[2] = ix86_tls_get_addr ();
15164 })
15165
15166 (define_insn "*tls_local_dynamic_base_32_gnu"
15167   [(set (match_operand:SI 0 "register_operand" "=a")
15168         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15169                     (match_operand:SI 2 "call_insn_operand" "")]
15170                    UNSPEC_TLS_LD_BASE))
15171    (clobber (match_scratch:SI 3 "=d"))
15172    (clobber (match_scratch:SI 4 "=c"))
15173    (clobber (reg:CC FLAGS_REG))]
15174   "!TARGET_64BIT && TARGET_GNU_TLS"
15175   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15176   [(set_attr "type" "multi")
15177    (set_attr "length" "11")])
15178
15179 (define_insn "*tls_local_dynamic_base_32_sun"
15180   [(set (match_operand:SI 0 "register_operand" "=a")
15181         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15182                     (match_operand:SI 2 "call_insn_operand" "")]
15183                    UNSPEC_TLS_LD_BASE))
15184    (clobber (match_scratch:SI 3 "=d"))
15185    (clobber (match_scratch:SI 4 "=c"))
15186    (clobber (reg:CC FLAGS_REG))]
15187   "!TARGET_64BIT && TARGET_SUN_TLS"
15188   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15189         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15190   [(set_attr "type" "multi")
15191    (set_attr "length" "13")])
15192
15193 (define_expand "tls_local_dynamic_base_32"
15194   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15195                    (unspec:SI [(match_dup 1) (match_dup 2)]
15196                               UNSPEC_TLS_LD_BASE))
15197               (clobber (match_scratch:SI 3 ""))
15198               (clobber (match_scratch:SI 4 ""))
15199               (clobber (reg:CC FLAGS_REG))])]
15200   ""
15201 {
15202   if (flag_pic)
15203     operands[1] = pic_offset_table_rtx;
15204   else
15205     {
15206       operands[1] = gen_reg_rtx (Pmode);
15207       emit_insn (gen_set_got (operands[1]));
15208     }
15209   if (TARGET_GNU2_TLS)
15210     {
15211        emit_insn (gen_tls_dynamic_gnu2_32
15212                   (operands[0], ix86_tls_module_base (), operands[1]));
15213        DONE;
15214     }
15215   operands[2] = ix86_tls_get_addr ();
15216 })
15217
15218 (define_insn "*tls_local_dynamic_base_64"
15219   [(set (match_operand:DI 0 "register_operand" "=a")
15220         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15221                  (match_operand:DI 2 "" "")))
15222    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15223   "TARGET_64BIT"
15224   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15225   [(set_attr "type" "multi")
15226    (set_attr "length" "12")])
15227
15228 (define_expand "tls_local_dynamic_base_64"
15229   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15230                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15231               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15232   ""
15233 {
15234   if (TARGET_GNU2_TLS)
15235     {
15236        emit_insn (gen_tls_dynamic_gnu2_64
15237                   (operands[0], ix86_tls_module_base ()));
15238        DONE;
15239     }
15240   operands[1] = ix86_tls_get_addr ();
15241 })
15242
15243 ;; Local dynamic of a single variable is a lose.  Show combine how
15244 ;; to convert that back to global dynamic.
15245
15246 (define_insn_and_split "*tls_local_dynamic_32_once"
15247   [(set (match_operand:SI 0 "register_operand" "=a")
15248         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15249                              (match_operand:SI 2 "call_insn_operand" "")]
15250                             UNSPEC_TLS_LD_BASE)
15251                  (const:SI (unspec:SI
15252                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15253                             UNSPEC_DTPOFF))))
15254    (clobber (match_scratch:SI 4 "=d"))
15255    (clobber (match_scratch:SI 5 "=c"))
15256    (clobber (reg:CC FLAGS_REG))]
15257   ""
15258   "#"
15259   ""
15260   [(parallel [(set (match_dup 0)
15261                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15262                               UNSPEC_TLS_GD))
15263               (clobber (match_dup 4))
15264               (clobber (match_dup 5))
15265               (clobber (reg:CC FLAGS_REG))])]
15266   "")
15267
15268 ;; Load and add the thread base pointer from %gs:0.
15269
15270 (define_insn "*load_tp_si"
15271   [(set (match_operand:SI 0 "register_operand" "=r")
15272         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15273   "!TARGET_64BIT"
15274   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15275   [(set_attr "type" "imov")
15276    (set_attr "modrm" "0")
15277    (set_attr "length" "7")
15278    (set_attr "memory" "load")
15279    (set_attr "imm_disp" "false")])
15280
15281 (define_insn "*add_tp_si"
15282   [(set (match_operand:SI 0 "register_operand" "=r")
15283         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15284                  (match_operand:SI 1 "register_operand" "0")))
15285    (clobber (reg:CC FLAGS_REG))]
15286   "!TARGET_64BIT"
15287   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15288   [(set_attr "type" "alu")
15289    (set_attr "modrm" "0")
15290    (set_attr "length" "7")
15291    (set_attr "memory" "load")
15292    (set_attr "imm_disp" "false")])
15293
15294 (define_insn "*load_tp_di"
15295   [(set (match_operand:DI 0 "register_operand" "=r")
15296         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15297   "TARGET_64BIT"
15298   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15299   [(set_attr "type" "imov")
15300    (set_attr "modrm" "0")
15301    (set_attr "length" "7")
15302    (set_attr "memory" "load")
15303    (set_attr "imm_disp" "false")])
15304
15305 (define_insn "*add_tp_di"
15306   [(set (match_operand:DI 0 "register_operand" "=r")
15307         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15308                  (match_operand:DI 1 "register_operand" "0")))
15309    (clobber (reg:CC FLAGS_REG))]
15310   "TARGET_64BIT"
15311   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15312   [(set_attr "type" "alu")
15313    (set_attr "modrm" "0")
15314    (set_attr "length" "7")
15315    (set_attr "memory" "load")
15316    (set_attr "imm_disp" "false")])
15317
15318 ;; GNU2 TLS patterns can be split.
15319
15320 (define_expand "tls_dynamic_gnu2_32"
15321   [(set (match_dup 3)
15322         (plus:SI (match_operand:SI 2 "register_operand" "")
15323                  (const:SI
15324                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15325                              UNSPEC_TLSDESC))))
15326    (parallel
15327     [(set (match_operand:SI 0 "register_operand" "")
15328           (unspec:SI [(match_dup 1) (match_dup 3)
15329                       (match_dup 2) (reg:SI SP_REG)]
15330                       UNSPEC_TLSDESC))
15331      (clobber (reg:CC FLAGS_REG))])]
15332   "!TARGET_64BIT && TARGET_GNU2_TLS"
15333 {
15334   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15335   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15336 })
15337
15338 (define_insn "*tls_dynamic_lea_32"
15339   [(set (match_operand:SI 0 "register_operand" "=r")
15340         (plus:SI (match_operand:SI 1 "register_operand" "b")
15341                  (const:SI
15342                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15343                               UNSPEC_TLSDESC))))]
15344   "!TARGET_64BIT && TARGET_GNU2_TLS"
15345   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15346   [(set_attr "type" "lea")
15347    (set_attr "mode" "SI")
15348    (set_attr "length" "6")
15349    (set_attr "length_address" "4")])
15350
15351 (define_insn "*tls_dynamic_call_32"
15352   [(set (match_operand:SI 0 "register_operand" "=a")
15353         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15354                     (match_operand:SI 2 "register_operand" "0")
15355                     ;; we have to make sure %ebx still points to the GOT
15356                     (match_operand:SI 3 "register_operand" "b")
15357                     (reg:SI SP_REG)]
15358                    UNSPEC_TLSDESC))
15359    (clobber (reg:CC FLAGS_REG))]
15360   "!TARGET_64BIT && TARGET_GNU2_TLS"
15361   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15362   [(set_attr "type" "call")
15363    (set_attr "length" "2")
15364    (set_attr "length_address" "0")])
15365
15366 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15367   [(set (match_operand:SI 0 "register_operand" "=&a")
15368         (plus:SI
15369          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15370                      (match_operand:SI 4 "" "")
15371                      (match_operand:SI 2 "register_operand" "b")
15372                      (reg:SI SP_REG)]
15373                     UNSPEC_TLSDESC)
15374          (const:SI (unspec:SI
15375                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15376                     UNSPEC_DTPOFF))))
15377    (clobber (reg:CC FLAGS_REG))]
15378   "!TARGET_64BIT && TARGET_GNU2_TLS"
15379   "#"
15380   ""
15381   [(set (match_dup 0) (match_dup 5))]
15382 {
15383   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15384   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15385 })
15386
15387 (define_expand "tls_dynamic_gnu2_64"
15388   [(set (match_dup 2)
15389         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15390                    UNSPEC_TLSDESC))
15391    (parallel
15392     [(set (match_operand:DI 0 "register_operand" "")
15393           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15394                      UNSPEC_TLSDESC))
15395      (clobber (reg:CC FLAGS_REG))])]
15396   "TARGET_64BIT && TARGET_GNU2_TLS"
15397 {
15398   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15399   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15400 })
15401
15402 (define_insn "*tls_dynamic_lea_64"
15403   [(set (match_operand:DI 0 "register_operand" "=r")
15404         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15405                    UNSPEC_TLSDESC))]
15406   "TARGET_64BIT && TARGET_GNU2_TLS"
15407   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15408   [(set_attr "type" "lea")
15409    (set_attr "mode" "DI")
15410    (set_attr "length" "7")
15411    (set_attr "length_address" "4")])
15412
15413 (define_insn "*tls_dynamic_call_64"
15414   [(set (match_operand:DI 0 "register_operand" "=a")
15415         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15416                     (match_operand:DI 2 "register_operand" "0")
15417                     (reg:DI SP_REG)]
15418                    UNSPEC_TLSDESC))
15419    (clobber (reg:CC FLAGS_REG))]
15420   "TARGET_64BIT && TARGET_GNU2_TLS"
15421   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15422   [(set_attr "type" "call")
15423    (set_attr "length" "2")
15424    (set_attr "length_address" "0")])
15425
15426 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15427   [(set (match_operand:DI 0 "register_operand" "=&a")
15428         (plus:DI
15429          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15430                      (match_operand:DI 3 "" "")
15431                      (reg:DI SP_REG)]
15432                     UNSPEC_TLSDESC)
15433          (const:DI (unspec:DI
15434                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15435                     UNSPEC_DTPOFF))))
15436    (clobber (reg:CC FLAGS_REG))]
15437   "TARGET_64BIT && TARGET_GNU2_TLS"
15438   "#"
15439   ""
15440   [(set (match_dup 0) (match_dup 4))]
15441 {
15442   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15443   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15444 })
15445
15446 ;;
15447 \f
15448 ;; These patterns match the binary 387 instructions for addM3, subM3,
15449 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15450 ;; SFmode.  The first is the normal insn, the second the same insn but
15451 ;; with one operand a conversion, and the third the same insn but with
15452 ;; the other operand a conversion.  The conversion may be SFmode or
15453 ;; SImode if the target mode DFmode, but only SImode if the target mode
15454 ;; is SFmode.
15455
15456 ;; Gcc is slightly more smart about handling normal two address instructions
15457 ;; so use special patterns for add and mull.
15458
15459 (define_insn "*fop_<mode>_comm_mixed_avx"
15460   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15461         (match_operator:MODEF 3 "binary_fp_operator"
15462           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15463            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15464   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15465    && COMMUTATIVE_ARITH_P (operands[3])
15466    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15467   "* return output_387_binary_op (insn, operands);"
15468   [(set (attr "type")
15469         (if_then_else (eq_attr "alternative" "1")
15470            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15471               (const_string "ssemul")
15472               (const_string "sseadd"))
15473            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15474               (const_string "fmul")
15475               (const_string "fop"))))
15476    (set_attr "prefix" "orig,maybe_vex")
15477    (set_attr "mode" "<MODE>")])
15478
15479 (define_insn "*fop_<mode>_comm_mixed"
15480   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15481         (match_operator:MODEF 3 "binary_fp_operator"
15482           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15483            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15484   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15485    && COMMUTATIVE_ARITH_P (operands[3])
15486    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15487   "* return output_387_binary_op (insn, operands);"
15488   [(set (attr "type")
15489         (if_then_else (eq_attr "alternative" "1")
15490            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15491               (const_string "ssemul")
15492               (const_string "sseadd"))
15493            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15494               (const_string "fmul")
15495               (const_string "fop"))))
15496    (set_attr "mode" "<MODE>")])
15497
15498 (define_insn "*fop_<mode>_comm_avx"
15499   [(set (match_operand:MODEF 0 "register_operand" "=x")
15500         (match_operator:MODEF 3 "binary_fp_operator"
15501           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15502            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15503   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15504    && COMMUTATIVE_ARITH_P (operands[3])
15505    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15506   "* return output_387_binary_op (insn, operands);"
15507   [(set (attr "type")
15508         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15509            (const_string "ssemul")
15510            (const_string "sseadd")))
15511    (set_attr "prefix" "vex")
15512    (set_attr "mode" "<MODE>")])
15513
15514 (define_insn "*fop_<mode>_comm_sse"
15515   [(set (match_operand:MODEF 0 "register_operand" "=x")
15516         (match_operator:MODEF 3 "binary_fp_operator"
15517           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15518            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15519   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15520    && COMMUTATIVE_ARITH_P (operands[3])
15521    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15522   "* return output_387_binary_op (insn, operands);"
15523   [(set (attr "type")
15524         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15525            (const_string "ssemul")
15526            (const_string "sseadd")))
15527    (set_attr "mode" "<MODE>")])
15528
15529 (define_insn "*fop_<mode>_comm_i387"
15530   [(set (match_operand:MODEF 0 "register_operand" "=f")
15531         (match_operator:MODEF 3 "binary_fp_operator"
15532           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15533            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15534   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15535    && COMMUTATIVE_ARITH_P (operands[3])
15536    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15537   "* return output_387_binary_op (insn, operands);"
15538   [(set (attr "type")
15539         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15540            (const_string "fmul")
15541            (const_string "fop")))
15542    (set_attr "mode" "<MODE>")])
15543
15544 (define_insn "*fop_<mode>_1_mixed_avx"
15545   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15546         (match_operator:MODEF 3 "binary_fp_operator"
15547           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15548            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15549   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15550    && !COMMUTATIVE_ARITH_P (operands[3])
15551    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15552   "* return output_387_binary_op (insn, operands);"
15553   [(set (attr "type")
15554         (cond [(and (eq_attr "alternative" "2")
15555                     (match_operand:MODEF 3 "mult_operator" ""))
15556                  (const_string "ssemul")
15557                (and (eq_attr "alternative" "2")
15558                     (match_operand:MODEF 3 "div_operator" ""))
15559                  (const_string "ssediv")
15560                (eq_attr "alternative" "2")
15561                  (const_string "sseadd")
15562                (match_operand:MODEF 3 "mult_operator" "")
15563                  (const_string "fmul")
15564                (match_operand:MODEF 3 "div_operator" "")
15565                  (const_string "fdiv")
15566               ]
15567               (const_string "fop")))
15568    (set_attr "prefix" "orig,orig,maybe_vex")
15569    (set_attr "mode" "<MODE>")])
15570
15571 (define_insn "*fop_<mode>_1_mixed"
15572   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15573         (match_operator:MODEF 3 "binary_fp_operator"
15574           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15575            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15576   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15577    && !COMMUTATIVE_ARITH_P (operands[3])
15578    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15579   "* return output_387_binary_op (insn, operands);"
15580   [(set (attr "type")
15581         (cond [(and (eq_attr "alternative" "2")
15582                     (match_operand:MODEF 3 "mult_operator" ""))
15583                  (const_string "ssemul")
15584                (and (eq_attr "alternative" "2")
15585                     (match_operand:MODEF 3 "div_operator" ""))
15586                  (const_string "ssediv")
15587                (eq_attr "alternative" "2")
15588                  (const_string "sseadd")
15589                (match_operand:MODEF 3 "mult_operator" "")
15590                  (const_string "fmul")
15591                (match_operand:MODEF 3 "div_operator" "")
15592                  (const_string "fdiv")
15593               ]
15594               (const_string "fop")))
15595    (set_attr "mode" "<MODE>")])
15596
15597 (define_insn "*rcpsf2_sse"
15598   [(set (match_operand:SF 0 "register_operand" "=x")
15599         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15600                    UNSPEC_RCP))]
15601   "TARGET_SSE_MATH"
15602   "%vrcpss\t{%1, %d0|%d0, %1}"
15603   [(set_attr "type" "sse")
15604    (set_attr "atom_sse_attr" "rcp")
15605    (set_attr "prefix" "maybe_vex")
15606    (set_attr "mode" "SF")])
15607
15608 (define_insn "*fop_<mode>_1_avx"
15609   [(set (match_operand:MODEF 0 "register_operand" "=x")
15610         (match_operator:MODEF 3 "binary_fp_operator"
15611           [(match_operand:MODEF 1 "register_operand" "x")
15612            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15613   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15614    && !COMMUTATIVE_ARITH_P (operands[3])"
15615   "* return output_387_binary_op (insn, operands);"
15616   [(set (attr "type")
15617         (cond [(match_operand:MODEF 3 "mult_operator" "")
15618                  (const_string "ssemul")
15619                (match_operand:MODEF 3 "div_operator" "")
15620                  (const_string "ssediv")
15621               ]
15622               (const_string "sseadd")))
15623    (set_attr "prefix" "vex")
15624    (set_attr "mode" "<MODE>")])
15625
15626 (define_insn "*fop_<mode>_1_sse"
15627   [(set (match_operand:MODEF 0 "register_operand" "=x")
15628         (match_operator:MODEF 3 "binary_fp_operator"
15629           [(match_operand:MODEF 1 "register_operand" "0")
15630            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15631   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15632    && !COMMUTATIVE_ARITH_P (operands[3])"
15633   "* return output_387_binary_op (insn, operands);"
15634   [(set (attr "type")
15635         (cond [(match_operand:MODEF 3 "mult_operator" "")
15636                  (const_string "ssemul")
15637                (match_operand:MODEF 3 "div_operator" "")
15638                  (const_string "ssediv")
15639               ]
15640               (const_string "sseadd")))
15641    (set_attr "mode" "<MODE>")])
15642
15643 ;; This pattern is not fully shadowed by the pattern above.
15644 (define_insn "*fop_<mode>_1_i387"
15645   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15646         (match_operator:MODEF 3 "binary_fp_operator"
15647           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15648            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15649   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15650    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15651    && !COMMUTATIVE_ARITH_P (operands[3])
15652    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15653   "* return output_387_binary_op (insn, operands);"
15654   [(set (attr "type")
15655         (cond [(match_operand:MODEF 3 "mult_operator" "")
15656                  (const_string "fmul")
15657                (match_operand:MODEF 3 "div_operator" "")
15658                  (const_string "fdiv")
15659               ]
15660               (const_string "fop")))
15661    (set_attr "mode" "<MODE>")])
15662
15663 ;; ??? Add SSE splitters for these!
15664 (define_insn "*fop_<MODEF:mode>_2_i387"
15665   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15666         (match_operator:MODEF 3 "binary_fp_operator"
15667           [(float:MODEF
15668              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15669            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15670   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15671    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15672    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15673   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15674   [(set (attr "type")
15675         (cond [(match_operand:MODEF 3 "mult_operator" "")
15676                  (const_string "fmul")
15677                (match_operand:MODEF 3 "div_operator" "")
15678                  (const_string "fdiv")
15679               ]
15680               (const_string "fop")))
15681    (set_attr "fp_int_src" "true")
15682    (set_attr "mode" "<X87MODEI12:MODE>")])
15683
15684 (define_insn "*fop_<MODEF:mode>_3_i387"
15685   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15686         (match_operator:MODEF 3 "binary_fp_operator"
15687           [(match_operand:MODEF 1 "register_operand" "0,0")
15688            (float:MODEF
15689              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15690   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15691    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15692    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15693   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15694   [(set (attr "type")
15695         (cond [(match_operand:MODEF 3 "mult_operator" "")
15696                  (const_string "fmul")
15697                (match_operand:MODEF 3 "div_operator" "")
15698                  (const_string "fdiv")
15699               ]
15700               (const_string "fop")))
15701    (set_attr "fp_int_src" "true")
15702    (set_attr "mode" "<MODE>")])
15703
15704 (define_insn "*fop_df_4_i387"
15705   [(set (match_operand:DF 0 "register_operand" "=f,f")
15706         (match_operator:DF 3 "binary_fp_operator"
15707            [(float_extend:DF
15708              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15709             (match_operand:DF 2 "register_operand" "0,f")]))]
15710   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15711    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15712    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15713   "* return output_387_binary_op (insn, operands);"
15714   [(set (attr "type")
15715         (cond [(match_operand:DF 3 "mult_operator" "")
15716                  (const_string "fmul")
15717                (match_operand:DF 3 "div_operator" "")
15718                  (const_string "fdiv")
15719               ]
15720               (const_string "fop")))
15721    (set_attr "mode" "SF")])
15722
15723 (define_insn "*fop_df_5_i387"
15724   [(set (match_operand:DF 0 "register_operand" "=f,f")
15725         (match_operator:DF 3 "binary_fp_operator"
15726           [(match_operand:DF 1 "register_operand" "0,f")
15727            (float_extend:DF
15728             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15729   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15730    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15731   "* return output_387_binary_op (insn, operands);"
15732   [(set (attr "type")
15733         (cond [(match_operand:DF 3 "mult_operator" "")
15734                  (const_string "fmul")
15735                (match_operand:DF 3 "div_operator" "")
15736                  (const_string "fdiv")
15737               ]
15738               (const_string "fop")))
15739    (set_attr "mode" "SF")])
15740
15741 (define_insn "*fop_df_6_i387"
15742   [(set (match_operand:DF 0 "register_operand" "=f,f")
15743         (match_operator:DF 3 "binary_fp_operator"
15744           [(float_extend:DF
15745             (match_operand:SF 1 "register_operand" "0,f"))
15746            (float_extend:DF
15747             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15748   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15749    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15750   "* return output_387_binary_op (insn, operands);"
15751   [(set (attr "type")
15752         (cond [(match_operand:DF 3 "mult_operator" "")
15753                  (const_string "fmul")
15754                (match_operand:DF 3 "div_operator" "")
15755                  (const_string "fdiv")
15756               ]
15757               (const_string "fop")))
15758    (set_attr "mode" "SF")])
15759
15760 (define_insn "*fop_xf_comm_i387"
15761   [(set (match_operand:XF 0 "register_operand" "=f")
15762         (match_operator:XF 3 "binary_fp_operator"
15763                         [(match_operand:XF 1 "register_operand" "%0")
15764                          (match_operand:XF 2 "register_operand" "f")]))]
15765   "TARGET_80387
15766    && COMMUTATIVE_ARITH_P (operands[3])"
15767   "* return output_387_binary_op (insn, operands);"
15768   [(set (attr "type")
15769         (if_then_else (match_operand:XF 3 "mult_operator" "")
15770            (const_string "fmul")
15771            (const_string "fop")))
15772    (set_attr "mode" "XF")])
15773
15774 (define_insn "*fop_xf_1_i387"
15775   [(set (match_operand:XF 0 "register_operand" "=f,f")
15776         (match_operator:XF 3 "binary_fp_operator"
15777                         [(match_operand:XF 1 "register_operand" "0,f")
15778                          (match_operand:XF 2 "register_operand" "f,0")]))]
15779   "TARGET_80387
15780    && !COMMUTATIVE_ARITH_P (operands[3])"
15781   "* return output_387_binary_op (insn, operands);"
15782   [(set (attr "type")
15783         (cond [(match_operand:XF 3 "mult_operator" "")
15784                  (const_string "fmul")
15785                (match_operand:XF 3 "div_operator" "")
15786                  (const_string "fdiv")
15787               ]
15788               (const_string "fop")))
15789    (set_attr "mode" "XF")])
15790
15791 (define_insn "*fop_xf_2_i387"
15792   [(set (match_operand:XF 0 "register_operand" "=f,f")
15793         (match_operator:XF 3 "binary_fp_operator"
15794           [(float:XF
15795              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15796            (match_operand:XF 2 "register_operand" "0,0")]))]
15797   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15798   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15799   [(set (attr "type")
15800         (cond [(match_operand:XF 3 "mult_operator" "")
15801                  (const_string "fmul")
15802                (match_operand:XF 3 "div_operator" "")
15803                  (const_string "fdiv")
15804               ]
15805               (const_string "fop")))
15806    (set_attr "fp_int_src" "true")
15807    (set_attr "mode" "<MODE>")])
15808
15809 (define_insn "*fop_xf_3_i387"
15810   [(set (match_operand:XF 0 "register_operand" "=f,f")
15811         (match_operator:XF 3 "binary_fp_operator"
15812           [(match_operand:XF 1 "register_operand" "0,0")
15813            (float:XF
15814              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15815   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15816   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15817   [(set (attr "type")
15818         (cond [(match_operand:XF 3 "mult_operator" "")
15819                  (const_string "fmul")
15820                (match_operand:XF 3 "div_operator" "")
15821                  (const_string "fdiv")
15822               ]
15823               (const_string "fop")))
15824    (set_attr "fp_int_src" "true")
15825    (set_attr "mode" "<MODE>")])
15826
15827 (define_insn "*fop_xf_4_i387"
15828   [(set (match_operand:XF 0 "register_operand" "=f,f")
15829         (match_operator:XF 3 "binary_fp_operator"
15830            [(float_extend:XF
15831               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15832             (match_operand:XF 2 "register_operand" "0,f")]))]
15833   "TARGET_80387"
15834   "* return output_387_binary_op (insn, operands);"
15835   [(set (attr "type")
15836         (cond [(match_operand:XF 3 "mult_operator" "")
15837                  (const_string "fmul")
15838                (match_operand:XF 3 "div_operator" "")
15839                  (const_string "fdiv")
15840               ]
15841               (const_string "fop")))
15842    (set_attr "mode" "<MODE>")])
15843
15844 (define_insn "*fop_xf_5_i387"
15845   [(set (match_operand:XF 0 "register_operand" "=f,f")
15846         (match_operator:XF 3 "binary_fp_operator"
15847           [(match_operand:XF 1 "register_operand" "0,f")
15848            (float_extend:XF
15849              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15850   "TARGET_80387"
15851   "* return output_387_binary_op (insn, operands);"
15852   [(set (attr "type")
15853         (cond [(match_operand:XF 3 "mult_operator" "")
15854                  (const_string "fmul")
15855                (match_operand:XF 3 "div_operator" "")
15856                  (const_string "fdiv")
15857               ]
15858               (const_string "fop")))
15859    (set_attr "mode" "<MODE>")])
15860
15861 (define_insn "*fop_xf_6_i387"
15862   [(set (match_operand:XF 0 "register_operand" "=f,f")
15863         (match_operator:XF 3 "binary_fp_operator"
15864           [(float_extend:XF
15865              (match_operand:MODEF 1 "register_operand" "0,f"))
15866            (float_extend:XF
15867              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15868   "TARGET_80387"
15869   "* return output_387_binary_op (insn, operands);"
15870   [(set (attr "type")
15871         (cond [(match_operand:XF 3 "mult_operator" "")
15872                  (const_string "fmul")
15873                (match_operand:XF 3 "div_operator" "")
15874                  (const_string "fdiv")
15875               ]
15876               (const_string "fop")))
15877    (set_attr "mode" "<MODE>")])
15878
15879 (define_split
15880   [(set (match_operand 0 "register_operand" "")
15881         (match_operator 3 "binary_fp_operator"
15882            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15883             (match_operand 2 "register_operand" "")]))]
15884   "reload_completed
15885    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15886    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15887   [(const_int 0)]
15888 {
15889   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15890   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15891   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15892                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15893                                           GET_MODE (operands[3]),
15894                                           operands[4],
15895                                           operands[2])));
15896   ix86_free_from_memory (GET_MODE (operands[1]));
15897   DONE;
15898 })
15899
15900 (define_split
15901   [(set (match_operand 0 "register_operand" "")
15902         (match_operator 3 "binary_fp_operator"
15903            [(match_operand 1 "register_operand" "")
15904             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15905   "reload_completed
15906    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15907    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15908   [(const_int 0)]
15909 {
15910   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15911   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15912   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15913                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15914                                           GET_MODE (operands[3]),
15915                                           operands[1],
15916                                           operands[4])));
15917   ix86_free_from_memory (GET_MODE (operands[2]));
15918   DONE;
15919 })
15920 \f
15921 ;; FPU special functions.
15922
15923 ;; This pattern implements a no-op XFmode truncation for
15924 ;; all fancy i386 XFmode math functions.
15925
15926 (define_insn "truncxf<mode>2_i387_noop_unspec"
15927   [(set (match_operand:MODEF 0 "register_operand" "=f")
15928         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15929         UNSPEC_TRUNC_NOOP))]
15930   "TARGET_USE_FANCY_MATH_387"
15931   "* return output_387_reg_move (insn, operands);"
15932   [(set_attr "type" "fmov")
15933    (set_attr "mode" "<MODE>")])
15934
15935 (define_insn "sqrtxf2"
15936   [(set (match_operand:XF 0 "register_operand" "=f")
15937         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15938   "TARGET_USE_FANCY_MATH_387"
15939   "fsqrt"
15940   [(set_attr "type" "fpspc")
15941    (set_attr "mode" "XF")
15942    (set_attr "athlon_decode" "direct")
15943    (set_attr "amdfam10_decode" "direct")])
15944
15945 (define_insn "sqrt_extend<mode>xf2_i387"
15946   [(set (match_operand:XF 0 "register_operand" "=f")
15947         (sqrt:XF
15948           (float_extend:XF
15949             (match_operand:MODEF 1 "register_operand" "0"))))]
15950   "TARGET_USE_FANCY_MATH_387"
15951   "fsqrt"
15952   [(set_attr "type" "fpspc")
15953    (set_attr "mode" "XF")
15954    (set_attr "athlon_decode" "direct")
15955    (set_attr "amdfam10_decode" "direct")])
15956
15957 (define_insn "*rsqrtsf2_sse"
15958   [(set (match_operand:SF 0 "register_operand" "=x")
15959         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15960                    UNSPEC_RSQRT))]
15961   "TARGET_SSE_MATH"
15962   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15963   [(set_attr "type" "sse")
15964    (set_attr "atom_sse_attr" "rcp")
15965    (set_attr "prefix" "maybe_vex")
15966    (set_attr "mode" "SF")])
15967
15968 (define_expand "rsqrtsf2"
15969   [(set (match_operand:SF 0 "register_operand" "")
15970         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15971                    UNSPEC_RSQRT))]
15972   "TARGET_SSE_MATH"
15973 {
15974   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15975   DONE;
15976 })
15977
15978 (define_insn "*sqrt<mode>2_sse"
15979   [(set (match_operand:MODEF 0 "register_operand" "=x")
15980         (sqrt:MODEF
15981           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15982   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15983   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15984   [(set_attr "type" "sse")
15985    (set_attr "atom_sse_attr" "sqrt")
15986    (set_attr "prefix" "maybe_vex")
15987    (set_attr "mode" "<MODE>")
15988    (set_attr "athlon_decode" "*")
15989    (set_attr "amdfam10_decode" "*")])
15990
15991 (define_expand "sqrt<mode>2"
15992   [(set (match_operand:MODEF 0 "register_operand" "")
15993         (sqrt:MODEF
15994           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15995   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15996    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15997 {
15998   if (<MODE>mode == SFmode
15999       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16000       && flag_finite_math_only && !flag_trapping_math
16001       && flag_unsafe_math_optimizations)
16002     {
16003       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16004       DONE;
16005     }
16006
16007   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16008     {
16009       rtx op0 = gen_reg_rtx (XFmode);
16010       rtx op1 = force_reg (<MODE>mode, operands[1]);
16011
16012       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16013       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16014       DONE;
16015    }
16016 })
16017
16018 (define_insn "fpremxf4_i387"
16019   [(set (match_operand:XF 0 "register_operand" "=f")
16020         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16021                     (match_operand:XF 3 "register_operand" "1")]
16022                    UNSPEC_FPREM_F))
16023    (set (match_operand:XF 1 "register_operand" "=u")
16024         (unspec:XF [(match_dup 2) (match_dup 3)]
16025                    UNSPEC_FPREM_U))
16026    (set (reg:CCFP FPSR_REG)
16027         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16028                      UNSPEC_C2_FLAG))]
16029   "TARGET_USE_FANCY_MATH_387"
16030   "fprem"
16031   [(set_attr "type" "fpspc")
16032    (set_attr "mode" "XF")])
16033
16034 (define_expand "fmodxf3"
16035   [(use (match_operand:XF 0 "register_operand" ""))
16036    (use (match_operand:XF 1 "general_operand" ""))
16037    (use (match_operand:XF 2 "general_operand" ""))]
16038   "TARGET_USE_FANCY_MATH_387"
16039 {
16040   rtx label = gen_label_rtx ();
16041
16042   rtx op1 = gen_reg_rtx (XFmode);
16043   rtx op2 = gen_reg_rtx (XFmode);
16044
16045   emit_move_insn (op2, operands[2]);
16046   emit_move_insn (op1, operands[1]);
16047
16048   emit_label (label);
16049   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16050   ix86_emit_fp_unordered_jump (label);
16051   LABEL_NUSES (label) = 1;
16052
16053   emit_move_insn (operands[0], op1);
16054   DONE;
16055 })
16056
16057 (define_expand "fmod<mode>3"
16058   [(use (match_operand:MODEF 0 "register_operand" ""))
16059    (use (match_operand:MODEF 1 "general_operand" ""))
16060    (use (match_operand:MODEF 2 "general_operand" ""))]
16061   "TARGET_USE_FANCY_MATH_387"
16062 {
16063   rtx label = gen_label_rtx ();
16064
16065   rtx op1 = gen_reg_rtx (XFmode);
16066   rtx op2 = gen_reg_rtx (XFmode);
16067
16068   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16069   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16070
16071   emit_label (label);
16072   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16073   ix86_emit_fp_unordered_jump (label);
16074   LABEL_NUSES (label) = 1;
16075
16076   /* Truncate the result properly for strict SSE math.  */
16077   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16078       && !TARGET_MIX_SSE_I387)
16079     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16080   else
16081     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16082
16083   DONE;
16084 })
16085
16086 (define_insn "fprem1xf4_i387"
16087   [(set (match_operand:XF 0 "register_operand" "=f")
16088         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16089                     (match_operand:XF 3 "register_operand" "1")]
16090                    UNSPEC_FPREM1_F))
16091    (set (match_operand:XF 1 "register_operand" "=u")
16092         (unspec:XF [(match_dup 2) (match_dup 3)]
16093                    UNSPEC_FPREM1_U))
16094    (set (reg:CCFP FPSR_REG)
16095         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16096                      UNSPEC_C2_FLAG))]
16097   "TARGET_USE_FANCY_MATH_387"
16098   "fprem1"
16099   [(set_attr "type" "fpspc")
16100    (set_attr "mode" "XF")])
16101
16102 (define_expand "remainderxf3"
16103   [(use (match_operand:XF 0 "register_operand" ""))
16104    (use (match_operand:XF 1 "general_operand" ""))
16105    (use (match_operand:XF 2 "general_operand" ""))]
16106   "TARGET_USE_FANCY_MATH_387"
16107 {
16108   rtx label = gen_label_rtx ();
16109
16110   rtx op1 = gen_reg_rtx (XFmode);
16111   rtx op2 = gen_reg_rtx (XFmode);
16112
16113   emit_move_insn (op2, operands[2]);
16114   emit_move_insn (op1, operands[1]);
16115
16116   emit_label (label);
16117   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16118   ix86_emit_fp_unordered_jump (label);
16119   LABEL_NUSES (label) = 1;
16120
16121   emit_move_insn (operands[0], op1);
16122   DONE;
16123 })
16124
16125 (define_expand "remainder<mode>3"
16126   [(use (match_operand:MODEF 0 "register_operand" ""))
16127    (use (match_operand:MODEF 1 "general_operand" ""))
16128    (use (match_operand:MODEF 2 "general_operand" ""))]
16129   "TARGET_USE_FANCY_MATH_387"
16130 {
16131   rtx label = gen_label_rtx ();
16132
16133   rtx op1 = gen_reg_rtx (XFmode);
16134   rtx op2 = gen_reg_rtx (XFmode);
16135
16136   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16137   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16138
16139   emit_label (label);
16140
16141   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16142   ix86_emit_fp_unordered_jump (label);
16143   LABEL_NUSES (label) = 1;
16144
16145   /* Truncate the result properly for strict SSE math.  */
16146   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16147       && !TARGET_MIX_SSE_I387)
16148     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16149   else
16150     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16151
16152   DONE;
16153 })
16154
16155 (define_insn "*sinxf2_i387"
16156   [(set (match_operand:XF 0 "register_operand" "=f")
16157         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16158   "TARGET_USE_FANCY_MATH_387
16159    && flag_unsafe_math_optimizations"
16160   "fsin"
16161   [(set_attr "type" "fpspc")
16162    (set_attr "mode" "XF")])
16163
16164 (define_insn "*sin_extend<mode>xf2_i387"
16165   [(set (match_operand:XF 0 "register_operand" "=f")
16166         (unspec:XF [(float_extend:XF
16167                       (match_operand:MODEF 1 "register_operand" "0"))]
16168                    UNSPEC_SIN))]
16169   "TARGET_USE_FANCY_MATH_387
16170    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16171        || TARGET_MIX_SSE_I387)
16172    && flag_unsafe_math_optimizations"
16173   "fsin"
16174   [(set_attr "type" "fpspc")
16175    (set_attr "mode" "XF")])
16176
16177 (define_insn "*cosxf2_i387"
16178   [(set (match_operand:XF 0 "register_operand" "=f")
16179         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16180   "TARGET_USE_FANCY_MATH_387
16181    && flag_unsafe_math_optimizations"
16182   "fcos"
16183   [(set_attr "type" "fpspc")
16184    (set_attr "mode" "XF")])
16185
16186 (define_insn "*cos_extend<mode>xf2_i387"
16187   [(set (match_operand:XF 0 "register_operand" "=f")
16188         (unspec:XF [(float_extend:XF
16189                       (match_operand:MODEF 1 "register_operand" "0"))]
16190                    UNSPEC_COS))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16193        || TARGET_MIX_SSE_I387)
16194    && flag_unsafe_math_optimizations"
16195   "fcos"
16196   [(set_attr "type" "fpspc")
16197    (set_attr "mode" "XF")])
16198
16199 ;; When sincos pattern is defined, sin and cos builtin functions will be
16200 ;; expanded to sincos pattern with one of its outputs left unused.
16201 ;; CSE pass will figure out if two sincos patterns can be combined,
16202 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16203 ;; depending on the unused output.
16204
16205 (define_insn "sincosxf3"
16206   [(set (match_operand:XF 0 "register_operand" "=f")
16207         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16208                    UNSPEC_SINCOS_COS))
16209    (set (match_operand:XF 1 "register_operand" "=u")
16210         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16211   "TARGET_USE_FANCY_MATH_387
16212    && flag_unsafe_math_optimizations"
16213   "fsincos"
16214   [(set_attr "type" "fpspc")
16215    (set_attr "mode" "XF")])
16216
16217 (define_split
16218   [(set (match_operand:XF 0 "register_operand" "")
16219         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16220                    UNSPEC_SINCOS_COS))
16221    (set (match_operand:XF 1 "register_operand" "")
16222         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16223   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16224    && !(reload_completed || reload_in_progress)"
16225   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16226   "")
16227
16228 (define_split
16229   [(set (match_operand:XF 0 "register_operand" "")
16230         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16231                    UNSPEC_SINCOS_COS))
16232    (set (match_operand:XF 1 "register_operand" "")
16233         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16234   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16235    && !(reload_completed || reload_in_progress)"
16236   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16237   "")
16238
16239 (define_insn "sincos_extend<mode>xf3_i387"
16240   [(set (match_operand:XF 0 "register_operand" "=f")
16241         (unspec:XF [(float_extend:XF
16242                       (match_operand:MODEF 2 "register_operand" "0"))]
16243                    UNSPEC_SINCOS_COS))
16244    (set (match_operand:XF 1 "register_operand" "=u")
16245         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16246   "TARGET_USE_FANCY_MATH_387
16247    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16248        || TARGET_MIX_SSE_I387)
16249    && flag_unsafe_math_optimizations"
16250   "fsincos"
16251   [(set_attr "type" "fpspc")
16252    (set_attr "mode" "XF")])
16253
16254 (define_split
16255   [(set (match_operand:XF 0 "register_operand" "")
16256         (unspec:XF [(float_extend:XF
16257                       (match_operand:MODEF 2 "register_operand" ""))]
16258                    UNSPEC_SINCOS_COS))
16259    (set (match_operand:XF 1 "register_operand" "")
16260         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16261   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16262    && !(reload_completed || reload_in_progress)"
16263   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16264   "")
16265
16266 (define_split
16267   [(set (match_operand:XF 0 "register_operand" "")
16268         (unspec:XF [(float_extend:XF
16269                       (match_operand:MODEF 2 "register_operand" ""))]
16270                    UNSPEC_SINCOS_COS))
16271    (set (match_operand:XF 1 "register_operand" "")
16272         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16273   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16274    && !(reload_completed || reload_in_progress)"
16275   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16276   "")
16277
16278 (define_expand "sincos<mode>3"
16279   [(use (match_operand:MODEF 0 "register_operand" ""))
16280    (use (match_operand:MODEF 1 "register_operand" ""))
16281    (use (match_operand:MODEF 2 "register_operand" ""))]
16282   "TARGET_USE_FANCY_MATH_387
16283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16284        || TARGET_MIX_SSE_I387)
16285    && flag_unsafe_math_optimizations"
16286 {
16287   rtx op0 = gen_reg_rtx (XFmode);
16288   rtx op1 = gen_reg_rtx (XFmode);
16289
16290   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16291   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16293   DONE;
16294 })
16295
16296 (define_insn "fptanxf4_i387"
16297   [(set (match_operand:XF 0 "register_operand" "=f")
16298         (match_operand:XF 3 "const_double_operand" "F"))
16299    (set (match_operand:XF 1 "register_operand" "=u")
16300         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16301                    UNSPEC_TAN))]
16302   "TARGET_USE_FANCY_MATH_387
16303    && flag_unsafe_math_optimizations
16304    && standard_80387_constant_p (operands[3]) == 2"
16305   "fptan"
16306   [(set_attr "type" "fpspc")
16307    (set_attr "mode" "XF")])
16308
16309 (define_insn "fptan_extend<mode>xf4_i387"
16310   [(set (match_operand:MODEF 0 "register_operand" "=f")
16311         (match_operand:MODEF 3 "const_double_operand" "F"))
16312    (set (match_operand:XF 1 "register_operand" "=u")
16313         (unspec:XF [(float_extend:XF
16314                       (match_operand:MODEF 2 "register_operand" "0"))]
16315                    UNSPEC_TAN))]
16316   "TARGET_USE_FANCY_MATH_387
16317    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16318        || TARGET_MIX_SSE_I387)
16319    && flag_unsafe_math_optimizations
16320    && standard_80387_constant_p (operands[3]) == 2"
16321   "fptan"
16322   [(set_attr "type" "fpspc")
16323    (set_attr "mode" "XF")])
16324
16325 (define_expand "tanxf2"
16326   [(use (match_operand:XF 0 "register_operand" ""))
16327    (use (match_operand:XF 1 "register_operand" ""))]
16328   "TARGET_USE_FANCY_MATH_387
16329    && flag_unsafe_math_optimizations"
16330 {
16331   rtx one = gen_reg_rtx (XFmode);
16332   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16333
16334   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16335   DONE;
16336 })
16337
16338 (define_expand "tan<mode>2"
16339   [(use (match_operand:MODEF 0 "register_operand" ""))
16340    (use (match_operand:MODEF 1 "register_operand" ""))]
16341   "TARGET_USE_FANCY_MATH_387
16342    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16343        || TARGET_MIX_SSE_I387)
16344    && flag_unsafe_math_optimizations"
16345 {
16346   rtx op0 = gen_reg_rtx (XFmode);
16347
16348   rtx one = gen_reg_rtx (<MODE>mode);
16349   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16350
16351   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16352                                              operands[1], op2));
16353   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16354   DONE;
16355 })
16356
16357 (define_insn "*fpatanxf3_i387"
16358   [(set (match_operand:XF 0 "register_operand" "=f")
16359         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16360                     (match_operand:XF 2 "register_operand" "u")]
16361                    UNSPEC_FPATAN))
16362    (clobber (match_scratch:XF 3 "=2"))]
16363   "TARGET_USE_FANCY_MATH_387
16364    && flag_unsafe_math_optimizations"
16365   "fpatan"
16366   [(set_attr "type" "fpspc")
16367    (set_attr "mode" "XF")])
16368
16369 (define_insn "fpatan_extend<mode>xf3_i387"
16370   [(set (match_operand:XF 0 "register_operand" "=f")
16371         (unspec:XF [(float_extend:XF
16372                       (match_operand:MODEF 1 "register_operand" "0"))
16373                     (float_extend:XF
16374                       (match_operand:MODEF 2 "register_operand" "u"))]
16375                    UNSPEC_FPATAN))
16376    (clobber (match_scratch:XF 3 "=2"))]
16377   "TARGET_USE_FANCY_MATH_387
16378    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16379        || TARGET_MIX_SSE_I387)
16380    && flag_unsafe_math_optimizations"
16381   "fpatan"
16382   [(set_attr "type" "fpspc")
16383    (set_attr "mode" "XF")])
16384
16385 (define_expand "atan2xf3"
16386   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16387                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16388                                (match_operand:XF 1 "register_operand" "")]
16389                               UNSPEC_FPATAN))
16390               (clobber (match_scratch:XF 3 ""))])]
16391   "TARGET_USE_FANCY_MATH_387
16392    && flag_unsafe_math_optimizations"
16393   "")
16394
16395 (define_expand "atan2<mode>3"
16396   [(use (match_operand:MODEF 0 "register_operand" ""))
16397    (use (match_operand:MODEF 1 "register_operand" ""))
16398    (use (match_operand:MODEF 2 "register_operand" ""))]
16399   "TARGET_USE_FANCY_MATH_387
16400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401        || TARGET_MIX_SSE_I387)
16402    && flag_unsafe_math_optimizations"
16403 {
16404   rtx op0 = gen_reg_rtx (XFmode);
16405
16406   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16407   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16408   DONE;
16409 })
16410
16411 (define_expand "atanxf2"
16412   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16413                    (unspec:XF [(match_dup 2)
16414                                (match_operand:XF 1 "register_operand" "")]
16415                               UNSPEC_FPATAN))
16416               (clobber (match_scratch:XF 3 ""))])]
16417   "TARGET_USE_FANCY_MATH_387
16418    && flag_unsafe_math_optimizations"
16419 {
16420   operands[2] = gen_reg_rtx (XFmode);
16421   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16422 })
16423
16424 (define_expand "atan<mode>2"
16425   [(use (match_operand:MODEF 0 "register_operand" ""))
16426    (use (match_operand:MODEF 1 "register_operand" ""))]
16427   "TARGET_USE_FANCY_MATH_387
16428    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429        || TARGET_MIX_SSE_I387)
16430    && flag_unsafe_math_optimizations"
16431 {
16432   rtx op0 = gen_reg_rtx (XFmode);
16433
16434   rtx op2 = gen_reg_rtx (<MODE>mode);
16435   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16436
16437   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16438   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16439   DONE;
16440 })
16441
16442 (define_expand "asinxf2"
16443   [(set (match_dup 2)
16444         (mult:XF (match_operand:XF 1 "register_operand" "")
16445                  (match_dup 1)))
16446    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16447    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16448    (parallel [(set (match_operand:XF 0 "register_operand" "")
16449                    (unspec:XF [(match_dup 5) (match_dup 1)]
16450                               UNSPEC_FPATAN))
16451               (clobber (match_scratch:XF 6 ""))])]
16452   "TARGET_USE_FANCY_MATH_387
16453    && flag_unsafe_math_optimizations"
16454 {
16455   int i;
16456
16457   if (optimize_insn_for_size_p ())
16458     FAIL;
16459
16460   for (i = 2; i < 6; i++)
16461     operands[i] = gen_reg_rtx (XFmode);
16462
16463   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16464 })
16465
16466 (define_expand "asin<mode>2"
16467   [(use (match_operand:MODEF 0 "register_operand" ""))
16468    (use (match_operand:MODEF 1 "general_operand" ""))]
16469  "TARGET_USE_FANCY_MATH_387
16470    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16471        || TARGET_MIX_SSE_I387)
16472    && flag_unsafe_math_optimizations"
16473 {
16474   rtx op0 = gen_reg_rtx (XFmode);
16475   rtx op1 = gen_reg_rtx (XFmode);
16476
16477   if (optimize_insn_for_size_p ())
16478     FAIL;
16479
16480   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16481   emit_insn (gen_asinxf2 (op0, op1));
16482   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16483   DONE;
16484 })
16485
16486 (define_expand "acosxf2"
16487   [(set (match_dup 2)
16488         (mult:XF (match_operand:XF 1 "register_operand" "")
16489                  (match_dup 1)))
16490    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16491    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16492    (parallel [(set (match_operand:XF 0 "register_operand" "")
16493                    (unspec:XF [(match_dup 1) (match_dup 5)]
16494                               UNSPEC_FPATAN))
16495               (clobber (match_scratch:XF 6 ""))])]
16496   "TARGET_USE_FANCY_MATH_387
16497    && flag_unsafe_math_optimizations"
16498 {
16499   int i;
16500
16501   if (optimize_insn_for_size_p ())
16502     FAIL;
16503
16504   for (i = 2; i < 6; i++)
16505     operands[i] = gen_reg_rtx (XFmode);
16506
16507   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16508 })
16509
16510 (define_expand "acos<mode>2"
16511   [(use (match_operand:MODEF 0 "register_operand" ""))
16512    (use (match_operand:MODEF 1 "general_operand" ""))]
16513  "TARGET_USE_FANCY_MATH_387
16514    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515        || TARGET_MIX_SSE_I387)
16516    && flag_unsafe_math_optimizations"
16517 {
16518   rtx op0 = gen_reg_rtx (XFmode);
16519   rtx op1 = gen_reg_rtx (XFmode);
16520
16521   if (optimize_insn_for_size_p ())
16522     FAIL;
16523
16524   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16525   emit_insn (gen_acosxf2 (op0, op1));
16526   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16527   DONE;
16528 })
16529
16530 (define_insn "fyl2xxf3_i387"
16531   [(set (match_operand:XF 0 "register_operand" "=f")
16532         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16533                     (match_operand:XF 2 "register_operand" "u")]
16534                    UNSPEC_FYL2X))
16535    (clobber (match_scratch:XF 3 "=2"))]
16536   "TARGET_USE_FANCY_MATH_387
16537    && flag_unsafe_math_optimizations"
16538   "fyl2x"
16539   [(set_attr "type" "fpspc")
16540    (set_attr "mode" "XF")])
16541
16542 (define_insn "fyl2x_extend<mode>xf3_i387"
16543   [(set (match_operand:XF 0 "register_operand" "=f")
16544         (unspec:XF [(float_extend:XF
16545                       (match_operand:MODEF 1 "register_operand" "0"))
16546                     (match_operand:XF 2 "register_operand" "u")]
16547                    UNSPEC_FYL2X))
16548    (clobber (match_scratch:XF 3 "=2"))]
16549   "TARGET_USE_FANCY_MATH_387
16550    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16551        || TARGET_MIX_SSE_I387)
16552    && flag_unsafe_math_optimizations"
16553   "fyl2x"
16554   [(set_attr "type" "fpspc")
16555    (set_attr "mode" "XF")])
16556
16557 (define_expand "logxf2"
16558   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16559                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16560                                (match_dup 2)] UNSPEC_FYL2X))
16561               (clobber (match_scratch:XF 3 ""))])]
16562   "TARGET_USE_FANCY_MATH_387
16563    && flag_unsafe_math_optimizations"
16564 {
16565   operands[2] = gen_reg_rtx (XFmode);
16566   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16567 })
16568
16569 (define_expand "log<mode>2"
16570   [(use (match_operand:MODEF 0 "register_operand" ""))
16571    (use (match_operand:MODEF 1 "register_operand" ""))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574        || TARGET_MIX_SSE_I387)
16575    && flag_unsafe_math_optimizations"
16576 {
16577   rtx op0 = gen_reg_rtx (XFmode);
16578
16579   rtx op2 = gen_reg_rtx (XFmode);
16580   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16581
16582   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16583   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16584   DONE;
16585 })
16586
16587 (define_expand "log10xf2"
16588   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16589                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16590                                (match_dup 2)] UNSPEC_FYL2X))
16591               (clobber (match_scratch:XF 3 ""))])]
16592   "TARGET_USE_FANCY_MATH_387
16593    && flag_unsafe_math_optimizations"
16594 {
16595   operands[2] = gen_reg_rtx (XFmode);
16596   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16597 })
16598
16599 (define_expand "log10<mode>2"
16600   [(use (match_operand:MODEF 0 "register_operand" ""))
16601    (use (match_operand:MODEF 1 "register_operand" ""))]
16602   "TARGET_USE_FANCY_MATH_387
16603    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16604        || TARGET_MIX_SSE_I387)
16605    && flag_unsafe_math_optimizations"
16606 {
16607   rtx op0 = gen_reg_rtx (XFmode);
16608
16609   rtx op2 = gen_reg_rtx (XFmode);
16610   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16611
16612   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16613   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16614   DONE;
16615 })
16616
16617 (define_expand "log2xf2"
16618   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16619                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16620                                (match_dup 2)] UNSPEC_FYL2X))
16621               (clobber (match_scratch:XF 3 ""))])]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624 {
16625   operands[2] = gen_reg_rtx (XFmode);
16626   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16627 })
16628
16629 (define_expand "log2<mode>2"
16630   [(use (match_operand:MODEF 0 "register_operand" ""))
16631    (use (match_operand:MODEF 1 "register_operand" ""))]
16632   "TARGET_USE_FANCY_MATH_387
16633    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16634        || TARGET_MIX_SSE_I387)
16635    && flag_unsafe_math_optimizations"
16636 {
16637   rtx op0 = gen_reg_rtx (XFmode);
16638
16639   rtx op2 = gen_reg_rtx (XFmode);
16640   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16641
16642   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16643   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16644   DONE;
16645 })
16646
16647 (define_insn "fyl2xp1xf3_i387"
16648   [(set (match_operand:XF 0 "register_operand" "=f")
16649         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16650                     (match_operand:XF 2 "register_operand" "u")]
16651                    UNSPEC_FYL2XP1))
16652    (clobber (match_scratch:XF 3 "=2"))]
16653   "TARGET_USE_FANCY_MATH_387
16654    && flag_unsafe_math_optimizations"
16655   "fyl2xp1"
16656   [(set_attr "type" "fpspc")
16657    (set_attr "mode" "XF")])
16658
16659 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16660   [(set (match_operand:XF 0 "register_operand" "=f")
16661         (unspec:XF [(float_extend:XF
16662                       (match_operand:MODEF 1 "register_operand" "0"))
16663                     (match_operand:XF 2 "register_operand" "u")]
16664                    UNSPEC_FYL2XP1))
16665    (clobber (match_scratch:XF 3 "=2"))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16668        || TARGET_MIX_SSE_I387)
16669    && flag_unsafe_math_optimizations"
16670   "fyl2xp1"
16671   [(set_attr "type" "fpspc")
16672    (set_attr "mode" "XF")])
16673
16674 (define_expand "log1pxf2"
16675   [(use (match_operand:XF 0 "register_operand" ""))
16676    (use (match_operand:XF 1 "register_operand" ""))]
16677   "TARGET_USE_FANCY_MATH_387
16678    && flag_unsafe_math_optimizations"
16679 {
16680   if (optimize_insn_for_size_p ())
16681     FAIL;
16682
16683   ix86_emit_i387_log1p (operands[0], operands[1]);
16684   DONE;
16685 })
16686
16687 (define_expand "log1p<mode>2"
16688   [(use (match_operand:MODEF 0 "register_operand" ""))
16689    (use (match_operand:MODEF 1 "register_operand" ""))]
16690   "TARGET_USE_FANCY_MATH_387
16691    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16692        || TARGET_MIX_SSE_I387)
16693    && flag_unsafe_math_optimizations"
16694 {
16695   rtx op0;
16696
16697   if (optimize_insn_for_size_p ())
16698     FAIL;
16699
16700   op0 = gen_reg_rtx (XFmode);
16701
16702   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16703
16704   ix86_emit_i387_log1p (op0, operands[1]);
16705   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16706   DONE;
16707 })
16708
16709 (define_insn "fxtractxf3_i387"
16710   [(set (match_operand:XF 0 "register_operand" "=f")
16711         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16712                    UNSPEC_XTRACT_FRACT))
16713    (set (match_operand:XF 1 "register_operand" "=u")
16714         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && flag_unsafe_math_optimizations"
16717   "fxtract"
16718   [(set_attr "type" "fpspc")
16719    (set_attr "mode" "XF")])
16720
16721 (define_insn "fxtract_extend<mode>xf3_i387"
16722   [(set (match_operand:XF 0 "register_operand" "=f")
16723         (unspec:XF [(float_extend:XF
16724                       (match_operand:MODEF 2 "register_operand" "0"))]
16725                    UNSPEC_XTRACT_FRACT))
16726    (set (match_operand:XF 1 "register_operand" "=u")
16727         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16728   "TARGET_USE_FANCY_MATH_387
16729    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16730        || TARGET_MIX_SSE_I387)
16731    && flag_unsafe_math_optimizations"
16732   "fxtract"
16733   [(set_attr "type" "fpspc")
16734    (set_attr "mode" "XF")])
16735
16736 (define_expand "logbxf2"
16737   [(parallel [(set (match_dup 2)
16738                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16739                               UNSPEC_XTRACT_FRACT))
16740               (set (match_operand:XF 0 "register_operand" "")
16741                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16742   "TARGET_USE_FANCY_MATH_387
16743    && flag_unsafe_math_optimizations"
16744 {
16745   operands[2] = gen_reg_rtx (XFmode);
16746 })
16747
16748 (define_expand "logb<mode>2"
16749   [(use (match_operand:MODEF 0 "register_operand" ""))
16750    (use (match_operand:MODEF 1 "register_operand" ""))]
16751   "TARGET_USE_FANCY_MATH_387
16752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16753        || TARGET_MIX_SSE_I387)
16754    && flag_unsafe_math_optimizations"
16755 {
16756   rtx op0 = gen_reg_rtx (XFmode);
16757   rtx op1 = gen_reg_rtx (XFmode);
16758
16759   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16760   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16761   DONE;
16762 })
16763
16764 (define_expand "ilogbxf2"
16765   [(use (match_operand:SI 0 "register_operand" ""))
16766    (use (match_operand:XF 1 "register_operand" ""))]
16767   "TARGET_USE_FANCY_MATH_387
16768    && flag_unsafe_math_optimizations"
16769 {
16770   rtx op0, op1;
16771
16772   if (optimize_insn_for_size_p ())
16773     FAIL;
16774
16775   op0 = gen_reg_rtx (XFmode);
16776   op1 = gen_reg_rtx (XFmode);
16777
16778   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16779   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16780   DONE;
16781 })
16782
16783 (define_expand "ilogb<mode>2"
16784   [(use (match_operand:SI 0 "register_operand" ""))
16785    (use (match_operand:MODEF 1 "register_operand" ""))]
16786   "TARGET_USE_FANCY_MATH_387
16787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788        || TARGET_MIX_SSE_I387)
16789    && flag_unsafe_math_optimizations"
16790 {
16791   rtx op0, op1;
16792
16793   if (optimize_insn_for_size_p ())
16794     FAIL;
16795
16796   op0 = gen_reg_rtx (XFmode);
16797   op1 = gen_reg_rtx (XFmode);
16798
16799   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16800   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16801   DONE;
16802 })
16803
16804 (define_insn "*f2xm1xf2_i387"
16805   [(set (match_operand:XF 0 "register_operand" "=f")
16806         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16807                    UNSPEC_F2XM1))]
16808   "TARGET_USE_FANCY_MATH_387
16809    && flag_unsafe_math_optimizations"
16810   "f2xm1"
16811   [(set_attr "type" "fpspc")
16812    (set_attr "mode" "XF")])
16813
16814 (define_insn "*fscalexf4_i387"
16815   [(set (match_operand:XF 0 "register_operand" "=f")
16816         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16817                     (match_operand:XF 3 "register_operand" "1")]
16818                    UNSPEC_FSCALE_FRACT))
16819    (set (match_operand:XF 1 "register_operand" "=u")
16820         (unspec:XF [(match_dup 2) (match_dup 3)]
16821                    UNSPEC_FSCALE_EXP))]
16822   "TARGET_USE_FANCY_MATH_387
16823    && flag_unsafe_math_optimizations"
16824   "fscale"
16825   [(set_attr "type" "fpspc")
16826    (set_attr "mode" "XF")])
16827
16828 (define_expand "expNcorexf3"
16829   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16830                                (match_operand:XF 2 "register_operand" "")))
16831    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16832    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16833    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16834    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16835    (parallel [(set (match_operand:XF 0 "register_operand" "")
16836                    (unspec:XF [(match_dup 8) (match_dup 4)]
16837                               UNSPEC_FSCALE_FRACT))
16838               (set (match_dup 9)
16839                    (unspec:XF [(match_dup 8) (match_dup 4)]
16840                               UNSPEC_FSCALE_EXP))])]
16841   "TARGET_USE_FANCY_MATH_387
16842    && flag_unsafe_math_optimizations"
16843 {
16844   int i;
16845
16846   if (optimize_insn_for_size_p ())
16847     FAIL;
16848
16849   for (i = 3; i < 10; i++)
16850     operands[i] = gen_reg_rtx (XFmode);
16851
16852   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16853 })
16854
16855 (define_expand "expxf2"
16856   [(use (match_operand:XF 0 "register_operand" ""))
16857    (use (match_operand:XF 1 "register_operand" ""))]
16858   "TARGET_USE_FANCY_MATH_387
16859    && flag_unsafe_math_optimizations"
16860 {
16861   rtx op2;
16862
16863   if (optimize_insn_for_size_p ())
16864     FAIL;
16865
16866   op2 = gen_reg_rtx (XFmode);
16867   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16868
16869   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16870   DONE;
16871 })
16872
16873 (define_expand "exp<mode>2"
16874   [(use (match_operand:MODEF 0 "register_operand" ""))
16875    (use (match_operand:MODEF 1 "general_operand" ""))]
16876  "TARGET_USE_FANCY_MATH_387
16877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16878        || TARGET_MIX_SSE_I387)
16879    && flag_unsafe_math_optimizations"
16880 {
16881   rtx op0, op1;
16882
16883   if (optimize_insn_for_size_p ())
16884     FAIL;
16885
16886   op0 = gen_reg_rtx (XFmode);
16887   op1 = gen_reg_rtx (XFmode);
16888
16889   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16890   emit_insn (gen_expxf2 (op0, op1));
16891   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16892   DONE;
16893 })
16894
16895 (define_expand "exp10xf2"
16896   [(use (match_operand:XF 0 "register_operand" ""))
16897    (use (match_operand:XF 1 "register_operand" ""))]
16898   "TARGET_USE_FANCY_MATH_387
16899    && flag_unsafe_math_optimizations"
16900 {
16901   rtx op2;
16902
16903   if (optimize_insn_for_size_p ())
16904     FAIL;
16905
16906   op2 = gen_reg_rtx (XFmode);
16907   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16908
16909   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16910   DONE;
16911 })
16912
16913 (define_expand "exp10<mode>2"
16914   [(use (match_operand:MODEF 0 "register_operand" ""))
16915    (use (match_operand:MODEF 1 "general_operand" ""))]
16916  "TARGET_USE_FANCY_MATH_387
16917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16918        || TARGET_MIX_SSE_I387)
16919    && flag_unsafe_math_optimizations"
16920 {
16921   rtx op0, op1;
16922
16923   if (optimize_insn_for_size_p ())
16924     FAIL;
16925
16926   op0 = gen_reg_rtx (XFmode);
16927   op1 = gen_reg_rtx (XFmode);
16928
16929   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16930   emit_insn (gen_exp10xf2 (op0, op1));
16931   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16932   DONE;
16933 })
16934
16935 (define_expand "exp2xf2"
16936   [(use (match_operand:XF 0 "register_operand" ""))
16937    (use (match_operand:XF 1 "register_operand" ""))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations"
16940 {
16941   rtx op2;
16942
16943   if (optimize_insn_for_size_p ())
16944     FAIL;
16945
16946   op2 = gen_reg_rtx (XFmode);
16947   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16948
16949   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16950   DONE;
16951 })
16952
16953 (define_expand "exp2<mode>2"
16954   [(use (match_operand:MODEF 0 "register_operand" ""))
16955    (use (match_operand:MODEF 1 "general_operand" ""))]
16956  "TARGET_USE_FANCY_MATH_387
16957    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16958        || TARGET_MIX_SSE_I387)
16959    && flag_unsafe_math_optimizations"
16960 {
16961   rtx op0, op1;
16962
16963   if (optimize_insn_for_size_p ())
16964     FAIL;
16965
16966   op0 = gen_reg_rtx (XFmode);
16967   op1 = gen_reg_rtx (XFmode);
16968
16969   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16970   emit_insn (gen_exp2xf2 (op0, op1));
16971   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16972   DONE;
16973 })
16974
16975 (define_expand "expm1xf2"
16976   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16977                                (match_dup 2)))
16978    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16979    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16980    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16981    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16982    (parallel [(set (match_dup 7)
16983                    (unspec:XF [(match_dup 6) (match_dup 4)]
16984                               UNSPEC_FSCALE_FRACT))
16985               (set (match_dup 8)
16986                    (unspec:XF [(match_dup 6) (match_dup 4)]
16987                               UNSPEC_FSCALE_EXP))])
16988    (parallel [(set (match_dup 10)
16989                    (unspec:XF [(match_dup 9) (match_dup 8)]
16990                               UNSPEC_FSCALE_FRACT))
16991               (set (match_dup 11)
16992                    (unspec:XF [(match_dup 9) (match_dup 8)]
16993                               UNSPEC_FSCALE_EXP))])
16994    (set (match_dup 12) (minus:XF (match_dup 10)
16995                                  (float_extend:XF (match_dup 13))))
16996    (set (match_operand:XF 0 "register_operand" "")
16997         (plus:XF (match_dup 12) (match_dup 7)))]
16998   "TARGET_USE_FANCY_MATH_387
16999    && flag_unsafe_math_optimizations"
17000 {
17001   int i;
17002
17003   if (optimize_insn_for_size_p ())
17004     FAIL;
17005
17006   for (i = 2; i < 13; i++)
17007     operands[i] = gen_reg_rtx (XFmode);
17008
17009   operands[13]
17010     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17011
17012   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17013 })
17014
17015 (define_expand "expm1<mode>2"
17016   [(use (match_operand:MODEF 0 "register_operand" ""))
17017    (use (match_operand:MODEF 1 "general_operand" ""))]
17018  "TARGET_USE_FANCY_MATH_387
17019    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17020        || TARGET_MIX_SSE_I387)
17021    && flag_unsafe_math_optimizations"
17022 {
17023   rtx op0, op1;
17024
17025   if (optimize_insn_for_size_p ())
17026     FAIL;
17027
17028   op0 = gen_reg_rtx (XFmode);
17029   op1 = gen_reg_rtx (XFmode);
17030
17031   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17032   emit_insn (gen_expm1xf2 (op0, op1));
17033   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17034   DONE;
17035 })
17036
17037 (define_expand "ldexpxf3"
17038   [(set (match_dup 3)
17039         (float:XF (match_operand:SI 2 "register_operand" "")))
17040    (parallel [(set (match_operand:XF 0 " register_operand" "")
17041                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17042                                (match_dup 3)]
17043                               UNSPEC_FSCALE_FRACT))
17044               (set (match_dup 4)
17045                    (unspec:XF [(match_dup 1) (match_dup 3)]
17046                               UNSPEC_FSCALE_EXP))])]
17047   "TARGET_USE_FANCY_MATH_387
17048    && flag_unsafe_math_optimizations"
17049 {
17050   if (optimize_insn_for_size_p ())
17051     FAIL;
17052
17053   operands[3] = gen_reg_rtx (XFmode);
17054   operands[4] = gen_reg_rtx (XFmode);
17055 })
17056
17057 (define_expand "ldexp<mode>3"
17058   [(use (match_operand:MODEF 0 "register_operand" ""))
17059    (use (match_operand:MODEF 1 "general_operand" ""))
17060    (use (match_operand:SI 2 "register_operand" ""))]
17061  "TARGET_USE_FANCY_MATH_387
17062    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17063        || TARGET_MIX_SSE_I387)
17064    && flag_unsafe_math_optimizations"
17065 {
17066   rtx op0, op1;
17067
17068   if (optimize_insn_for_size_p ())
17069     FAIL;
17070
17071   op0 = gen_reg_rtx (XFmode);
17072   op1 = gen_reg_rtx (XFmode);
17073
17074   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17075   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17076   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17077   DONE;
17078 })
17079
17080 (define_expand "scalbxf3"
17081   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17082                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17083                                (match_operand:XF 2 "register_operand" "")]
17084                               UNSPEC_FSCALE_FRACT))
17085               (set (match_dup 3)
17086                    (unspec:XF [(match_dup 1) (match_dup 2)]
17087                               UNSPEC_FSCALE_EXP))])]
17088   "TARGET_USE_FANCY_MATH_387
17089    && flag_unsafe_math_optimizations"
17090 {
17091   if (optimize_insn_for_size_p ())
17092     FAIL;
17093
17094   operands[3] = gen_reg_rtx (XFmode);
17095 })
17096
17097 (define_expand "scalb<mode>3"
17098   [(use (match_operand:MODEF 0 "register_operand" ""))
17099    (use (match_operand:MODEF 1 "general_operand" ""))
17100    (use (match_operand:MODEF 2 "general_operand" ""))]
17101  "TARGET_USE_FANCY_MATH_387
17102    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17103        || TARGET_MIX_SSE_I387)
17104    && flag_unsafe_math_optimizations"
17105 {
17106   rtx op0, op1, op2;
17107
17108   if (optimize_insn_for_size_p ())
17109     FAIL;
17110
17111   op0 = gen_reg_rtx (XFmode);
17112   op1 = gen_reg_rtx (XFmode);
17113   op2 = gen_reg_rtx (XFmode);
17114
17115   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17116   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17117   emit_insn (gen_scalbxf3 (op0, op1, op2));
17118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17119   DONE;
17120 })
17121
17122 (define_expand "significandxf2"
17123   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17124                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17125                               UNSPEC_XTRACT_FRACT))
17126               (set (match_dup 2)
17127                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17128   "TARGET_USE_FANCY_MATH_387
17129    && flag_unsafe_math_optimizations"
17130 {
17131   operands[2] = gen_reg_rtx (XFmode);
17132 })
17133
17134 (define_expand "significand<mode>2"
17135   [(use (match_operand:MODEF 0 "register_operand" ""))
17136    (use (match_operand:MODEF 1 "register_operand" ""))]
17137   "TARGET_USE_FANCY_MATH_387
17138    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17139        || TARGET_MIX_SSE_I387)
17140    && flag_unsafe_math_optimizations"
17141 {
17142   rtx op0 = gen_reg_rtx (XFmode);
17143   rtx op1 = gen_reg_rtx (XFmode);
17144
17145   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17146   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17147   DONE;
17148 })
17149 \f
17150
17151 (define_insn "sse4_1_round<mode>2"
17152   [(set (match_operand:MODEF 0 "register_operand" "=x")
17153         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17154                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17155                       UNSPEC_ROUND))]
17156   "TARGET_ROUND"
17157   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17158   [(set_attr "type" "ssecvt")
17159    (set_attr "prefix_extra" "1")
17160    (set_attr "prefix" "maybe_vex")
17161    (set_attr "mode" "<MODE>")])
17162
17163 (define_insn "rintxf2"
17164   [(set (match_operand:XF 0 "register_operand" "=f")
17165         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17166                    UNSPEC_FRNDINT))]
17167   "TARGET_USE_FANCY_MATH_387
17168    && flag_unsafe_math_optimizations"
17169   "frndint"
17170   [(set_attr "type" "fpspc")
17171    (set_attr "mode" "XF")])
17172
17173 (define_expand "rint<mode>2"
17174   [(use (match_operand:MODEF 0 "register_operand" ""))
17175    (use (match_operand:MODEF 1 "register_operand" ""))]
17176   "(TARGET_USE_FANCY_MATH_387
17177     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17178         || TARGET_MIX_SSE_I387)
17179     && flag_unsafe_math_optimizations)
17180    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17181        && !flag_trapping_math)"
17182 {
17183   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17184       && !flag_trapping_math)
17185     {
17186       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17187         FAIL;
17188       if (TARGET_ROUND)
17189         emit_insn (gen_sse4_1_round<mode>2
17190                    (operands[0], operands[1], GEN_INT (0x04)));
17191       else
17192         ix86_expand_rint (operand0, operand1);
17193     }
17194   else
17195     {
17196       rtx op0 = gen_reg_rtx (XFmode);
17197       rtx op1 = gen_reg_rtx (XFmode);
17198
17199       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17200       emit_insn (gen_rintxf2 (op0, op1));
17201
17202       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17203     }
17204   DONE;
17205 })
17206
17207 (define_expand "round<mode>2"
17208   [(match_operand:MODEF 0 "register_operand" "")
17209    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17210   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17211    && !flag_trapping_math && !flag_rounding_math"
17212 {
17213   if (optimize_insn_for_size_p ())
17214     FAIL;
17215   if (TARGET_64BIT || (<MODE>mode != DFmode))
17216     ix86_expand_round (operand0, operand1);
17217   else
17218     ix86_expand_rounddf_32 (operand0, operand1);
17219   DONE;
17220 })
17221
17222 (define_insn_and_split "*fistdi2_1"
17223   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17224         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17225                    UNSPEC_FIST))]
17226   "TARGET_USE_FANCY_MATH_387
17227    && can_create_pseudo_p ()"
17228   "#"
17229   "&& 1"
17230   [(const_int 0)]
17231 {
17232   if (memory_operand (operands[0], VOIDmode))
17233     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17234   else
17235     {
17236       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17237       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17238                                          operands[2]));
17239     }
17240   DONE;
17241 }
17242   [(set_attr "type" "fpspc")
17243    (set_attr "mode" "DI")])
17244
17245 (define_insn "fistdi2"
17246   [(set (match_operand:DI 0 "memory_operand" "=m")
17247         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17248                    UNSPEC_FIST))
17249    (clobber (match_scratch:XF 2 "=&1f"))]
17250   "TARGET_USE_FANCY_MATH_387"
17251   "* return output_fix_trunc (insn, operands, 0);"
17252   [(set_attr "type" "fpspc")
17253    (set_attr "mode" "DI")])
17254
17255 (define_insn "fistdi2_with_temp"
17256   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17257         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17258                    UNSPEC_FIST))
17259    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17260    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17261   "TARGET_USE_FANCY_MATH_387"
17262   "#"
17263   [(set_attr "type" "fpspc")
17264    (set_attr "mode" "DI")])
17265
17266 (define_split
17267   [(set (match_operand:DI 0 "register_operand" "")
17268         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17269                    UNSPEC_FIST))
17270    (clobber (match_operand:DI 2 "memory_operand" ""))
17271    (clobber (match_scratch 3 ""))]
17272   "reload_completed"
17273   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17274               (clobber (match_dup 3))])
17275    (set (match_dup 0) (match_dup 2))]
17276   "")
17277
17278 (define_split
17279   [(set (match_operand:DI 0 "memory_operand" "")
17280         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17281                    UNSPEC_FIST))
17282    (clobber (match_operand:DI 2 "memory_operand" ""))
17283    (clobber (match_scratch 3 ""))]
17284   "reload_completed"
17285   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17286               (clobber (match_dup 3))])]
17287   "")
17288
17289 (define_insn_and_split "*fist<mode>2_1"
17290   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17291         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17292                            UNSPEC_FIST))]
17293   "TARGET_USE_FANCY_MATH_387
17294    && can_create_pseudo_p ()"
17295   "#"
17296   "&& 1"
17297   [(const_int 0)]
17298 {
17299   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17300   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17301                                         operands[2]));
17302   DONE;
17303 }
17304   [(set_attr "type" "fpspc")
17305    (set_attr "mode" "<MODE>")])
17306
17307 (define_insn "fist<mode>2"
17308   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17310                            UNSPEC_FIST))]
17311   "TARGET_USE_FANCY_MATH_387"
17312   "* return output_fix_trunc (insn, operands, 0);"
17313   [(set_attr "type" "fpspc")
17314    (set_attr "mode" "<MODE>")])
17315
17316 (define_insn "fist<mode>2_with_temp"
17317   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17318         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17319                            UNSPEC_FIST))
17320    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17321   "TARGET_USE_FANCY_MATH_387"
17322   "#"
17323   [(set_attr "type" "fpspc")
17324    (set_attr "mode" "<MODE>")])
17325
17326 (define_split
17327   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17328         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17329                            UNSPEC_FIST))
17330    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17331   "reload_completed"
17332   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17333    (set (match_dup 0) (match_dup 2))]
17334   "")
17335
17336 (define_split
17337   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17338         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17339                            UNSPEC_FIST))
17340    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17341   "reload_completed"
17342   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17343   "")
17344
17345 (define_expand "lrintxf<mode>2"
17346   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17347      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17348                       UNSPEC_FIST))]
17349   "TARGET_USE_FANCY_MATH_387"
17350   "")
17351
17352 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17353   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17354      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17355                         UNSPEC_FIX_NOTRUNC))]
17356   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17357    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17358   "")
17359
17360 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17361   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17362    (match_operand:MODEF 1 "register_operand" "")]
17363   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17364    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17365    && !flag_trapping_math && !flag_rounding_math"
17366 {
17367   if (optimize_insn_for_size_p ())
17368     FAIL;
17369   ix86_expand_lround (operand0, operand1);
17370   DONE;
17371 })
17372
17373 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17374 (define_insn_and_split "frndintxf2_floor"
17375   [(set (match_operand:XF 0 "register_operand" "")
17376         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17377          UNSPEC_FRNDINT_FLOOR))
17378    (clobber (reg:CC FLAGS_REG))]
17379   "TARGET_USE_FANCY_MATH_387
17380    && flag_unsafe_math_optimizations
17381    && can_create_pseudo_p ()"
17382   "#"
17383   "&& 1"
17384   [(const_int 0)]
17385 {
17386   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17387
17388   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17389   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17390
17391   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17392                                         operands[2], operands[3]));
17393   DONE;
17394 }
17395   [(set_attr "type" "frndint")
17396    (set_attr "i387_cw" "floor")
17397    (set_attr "mode" "XF")])
17398
17399 (define_insn "frndintxf2_floor_i387"
17400   [(set (match_operand:XF 0 "register_operand" "=f")
17401         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17402          UNSPEC_FRNDINT_FLOOR))
17403    (use (match_operand:HI 2 "memory_operand" "m"))
17404    (use (match_operand:HI 3 "memory_operand" "m"))]
17405   "TARGET_USE_FANCY_MATH_387
17406    && flag_unsafe_math_optimizations"
17407   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17408   [(set_attr "type" "frndint")
17409    (set_attr "i387_cw" "floor")
17410    (set_attr "mode" "XF")])
17411
17412 (define_expand "floorxf2"
17413   [(use (match_operand:XF 0 "register_operand" ""))
17414    (use (match_operand:XF 1 "register_operand" ""))]
17415   "TARGET_USE_FANCY_MATH_387
17416    && flag_unsafe_math_optimizations"
17417 {
17418   if (optimize_insn_for_size_p ())
17419     FAIL;
17420   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17421   DONE;
17422 })
17423
17424 (define_expand "floor<mode>2"
17425   [(use (match_operand:MODEF 0 "register_operand" ""))
17426    (use (match_operand:MODEF 1 "register_operand" ""))]
17427   "(TARGET_USE_FANCY_MATH_387
17428     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17429         || TARGET_MIX_SSE_I387)
17430     && flag_unsafe_math_optimizations)
17431    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17432        && !flag_trapping_math)"
17433 {
17434   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17435       && !flag_trapping_math
17436       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17437     {
17438       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17439         FAIL;
17440       if (TARGET_ROUND)
17441         emit_insn (gen_sse4_1_round<mode>2
17442                    (operands[0], operands[1], GEN_INT (0x01)));
17443       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17444         ix86_expand_floorceil (operand0, operand1, true);
17445       else
17446         ix86_expand_floorceildf_32 (operand0, operand1, true);
17447     }
17448   else
17449     {
17450       rtx op0, op1;
17451
17452       if (optimize_insn_for_size_p ())
17453         FAIL;
17454
17455       op0 = gen_reg_rtx (XFmode);
17456       op1 = gen_reg_rtx (XFmode);
17457       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17458       emit_insn (gen_frndintxf2_floor (op0, op1));
17459
17460       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17461     }
17462   DONE;
17463 })
17464
17465 (define_insn_and_split "*fist<mode>2_floor_1"
17466   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17467         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17468          UNSPEC_FIST_FLOOR))
17469    (clobber (reg:CC FLAGS_REG))]
17470   "TARGET_USE_FANCY_MATH_387
17471    && flag_unsafe_math_optimizations
17472    && can_create_pseudo_p ()"
17473   "#"
17474   "&& 1"
17475   [(const_int 0)]
17476 {
17477   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17478
17479   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17480   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17481   if (memory_operand (operands[0], VOIDmode))
17482     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17483                                       operands[2], operands[3]));
17484   else
17485     {
17486       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17487       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17488                                                   operands[2], operands[3],
17489                                                   operands[4]));
17490     }
17491   DONE;
17492 }
17493   [(set_attr "type" "fistp")
17494    (set_attr "i387_cw" "floor")
17495    (set_attr "mode" "<MODE>")])
17496
17497 (define_insn "fistdi2_floor"
17498   [(set (match_operand:DI 0 "memory_operand" "=m")
17499         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17500          UNSPEC_FIST_FLOOR))
17501    (use (match_operand:HI 2 "memory_operand" "m"))
17502    (use (match_operand:HI 3 "memory_operand" "m"))
17503    (clobber (match_scratch:XF 4 "=&1f"))]
17504   "TARGET_USE_FANCY_MATH_387
17505    && flag_unsafe_math_optimizations"
17506   "* return output_fix_trunc (insn, operands, 0);"
17507   [(set_attr "type" "fistp")
17508    (set_attr "i387_cw" "floor")
17509    (set_attr "mode" "DI")])
17510
17511 (define_insn "fistdi2_floor_with_temp"
17512   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17513         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17514          UNSPEC_FIST_FLOOR))
17515    (use (match_operand:HI 2 "memory_operand" "m,m"))
17516    (use (match_operand:HI 3 "memory_operand" "m,m"))
17517    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17518    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17519   "TARGET_USE_FANCY_MATH_387
17520    && flag_unsafe_math_optimizations"
17521   "#"
17522   [(set_attr "type" "fistp")
17523    (set_attr "i387_cw" "floor")
17524    (set_attr "mode" "DI")])
17525
17526 (define_split
17527   [(set (match_operand:DI 0 "register_operand" "")
17528         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17529          UNSPEC_FIST_FLOOR))
17530    (use (match_operand:HI 2 "memory_operand" ""))
17531    (use (match_operand:HI 3 "memory_operand" ""))
17532    (clobber (match_operand:DI 4 "memory_operand" ""))
17533    (clobber (match_scratch 5 ""))]
17534   "reload_completed"
17535   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17536               (use (match_dup 2))
17537               (use (match_dup 3))
17538               (clobber (match_dup 5))])
17539    (set (match_dup 0) (match_dup 4))]
17540   "")
17541
17542 (define_split
17543   [(set (match_operand:DI 0 "memory_operand" "")
17544         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17545          UNSPEC_FIST_FLOOR))
17546    (use (match_operand:HI 2 "memory_operand" ""))
17547    (use (match_operand:HI 3 "memory_operand" ""))
17548    (clobber (match_operand:DI 4 "memory_operand" ""))
17549    (clobber (match_scratch 5 ""))]
17550   "reload_completed"
17551   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17552               (use (match_dup 2))
17553               (use (match_dup 3))
17554               (clobber (match_dup 5))])]
17555   "")
17556
17557 (define_insn "fist<mode>2_floor"
17558   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17559         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17560          UNSPEC_FIST_FLOOR))
17561    (use (match_operand:HI 2 "memory_operand" "m"))
17562    (use (match_operand:HI 3 "memory_operand" "m"))]
17563   "TARGET_USE_FANCY_MATH_387
17564    && flag_unsafe_math_optimizations"
17565   "* return output_fix_trunc (insn, operands, 0);"
17566   [(set_attr "type" "fistp")
17567    (set_attr "i387_cw" "floor")
17568    (set_attr "mode" "<MODE>")])
17569
17570 (define_insn "fist<mode>2_floor_with_temp"
17571   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17572         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17573          UNSPEC_FIST_FLOOR))
17574    (use (match_operand:HI 2 "memory_operand" "m,m"))
17575    (use (match_operand:HI 3 "memory_operand" "m,m"))
17576    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17577   "TARGET_USE_FANCY_MATH_387
17578    && flag_unsafe_math_optimizations"
17579   "#"
17580   [(set_attr "type" "fistp")
17581    (set_attr "i387_cw" "floor")
17582    (set_attr "mode" "<MODE>")])
17583
17584 (define_split
17585   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17586         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17587          UNSPEC_FIST_FLOOR))
17588    (use (match_operand:HI 2 "memory_operand" ""))
17589    (use (match_operand:HI 3 "memory_operand" ""))
17590    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17591   "reload_completed"
17592   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17593                                   UNSPEC_FIST_FLOOR))
17594               (use (match_dup 2))
17595               (use (match_dup 3))])
17596    (set (match_dup 0) (match_dup 4))]
17597   "")
17598
17599 (define_split
17600   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17601         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17602          UNSPEC_FIST_FLOOR))
17603    (use (match_operand:HI 2 "memory_operand" ""))
17604    (use (match_operand:HI 3 "memory_operand" ""))
17605    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17606   "reload_completed"
17607   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17608                                   UNSPEC_FIST_FLOOR))
17609               (use (match_dup 2))
17610               (use (match_dup 3))])]
17611   "")
17612
17613 (define_expand "lfloorxf<mode>2"
17614   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17615                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17616                     UNSPEC_FIST_FLOOR))
17617               (clobber (reg:CC FLAGS_REG))])]
17618   "TARGET_USE_FANCY_MATH_387
17619    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17620    && flag_unsafe_math_optimizations"
17621   "")
17622
17623 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17624   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17625    (match_operand:MODEF 1 "register_operand" "")]
17626   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17627    && !flag_trapping_math"
17628 {
17629   if (TARGET_64BIT && optimize_insn_for_size_p ())
17630     FAIL;
17631   ix86_expand_lfloorceil (operand0, operand1, true);
17632   DONE;
17633 })
17634
17635 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17636 (define_insn_and_split "frndintxf2_ceil"
17637   [(set (match_operand:XF 0 "register_operand" "")
17638         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17639          UNSPEC_FRNDINT_CEIL))
17640    (clobber (reg:CC FLAGS_REG))]
17641   "TARGET_USE_FANCY_MATH_387
17642    && flag_unsafe_math_optimizations
17643    && can_create_pseudo_p ()"
17644   "#"
17645   "&& 1"
17646   [(const_int 0)]
17647 {
17648   ix86_optimize_mode_switching[I387_CEIL] = 1;
17649
17650   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17651   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17652
17653   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17654                                        operands[2], operands[3]));
17655   DONE;
17656 }
17657   [(set_attr "type" "frndint")
17658    (set_attr "i387_cw" "ceil")
17659    (set_attr "mode" "XF")])
17660
17661 (define_insn "frndintxf2_ceil_i387"
17662   [(set (match_operand:XF 0 "register_operand" "=f")
17663         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17664          UNSPEC_FRNDINT_CEIL))
17665    (use (match_operand:HI 2 "memory_operand" "m"))
17666    (use (match_operand:HI 3 "memory_operand" "m"))]
17667   "TARGET_USE_FANCY_MATH_387
17668    && flag_unsafe_math_optimizations"
17669   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17670   [(set_attr "type" "frndint")
17671    (set_attr "i387_cw" "ceil")
17672    (set_attr "mode" "XF")])
17673
17674 (define_expand "ceilxf2"
17675   [(use (match_operand:XF 0 "register_operand" ""))
17676    (use (match_operand:XF 1 "register_operand" ""))]
17677   "TARGET_USE_FANCY_MATH_387
17678    && flag_unsafe_math_optimizations"
17679 {
17680   if (optimize_insn_for_size_p ())
17681     FAIL;
17682   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17683   DONE;
17684 })
17685
17686 (define_expand "ceil<mode>2"
17687   [(use (match_operand:MODEF 0 "register_operand" ""))
17688    (use (match_operand:MODEF 1 "register_operand" ""))]
17689   "(TARGET_USE_FANCY_MATH_387
17690     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17691         || TARGET_MIX_SSE_I387)
17692     && flag_unsafe_math_optimizations)
17693    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17694        && !flag_trapping_math)"
17695 {
17696   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17697       && !flag_trapping_math
17698       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17699     {
17700       if (TARGET_ROUND)
17701         emit_insn (gen_sse4_1_round<mode>2
17702                    (operands[0], operands[1], GEN_INT (0x02)));
17703       else if (optimize_insn_for_size_p ())
17704         FAIL;
17705       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17706         ix86_expand_floorceil (operand0, operand1, false);
17707       else
17708         ix86_expand_floorceildf_32 (operand0, operand1, false);
17709     }
17710   else
17711     {
17712       rtx op0, op1;
17713
17714       if (optimize_insn_for_size_p ())
17715         FAIL;
17716
17717       op0 = gen_reg_rtx (XFmode);
17718       op1 = gen_reg_rtx (XFmode);
17719       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17720       emit_insn (gen_frndintxf2_ceil (op0, op1));
17721
17722       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17723     }
17724   DONE;
17725 })
17726
17727 (define_insn_and_split "*fist<mode>2_ceil_1"
17728   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17729         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17730          UNSPEC_FIST_CEIL))
17731    (clobber (reg:CC FLAGS_REG))]
17732   "TARGET_USE_FANCY_MATH_387
17733    && flag_unsafe_math_optimizations
17734    && can_create_pseudo_p ()"
17735   "#"
17736   "&& 1"
17737   [(const_int 0)]
17738 {
17739   ix86_optimize_mode_switching[I387_CEIL] = 1;
17740
17741   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17742   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17743   if (memory_operand (operands[0], VOIDmode))
17744     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17745                                      operands[2], operands[3]));
17746   else
17747     {
17748       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17749       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17750                                                  operands[2], operands[3],
17751                                                  operands[4]));
17752     }
17753   DONE;
17754 }
17755   [(set_attr "type" "fistp")
17756    (set_attr "i387_cw" "ceil")
17757    (set_attr "mode" "<MODE>")])
17758
17759 (define_insn "fistdi2_ceil"
17760   [(set (match_operand:DI 0 "memory_operand" "=m")
17761         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17762          UNSPEC_FIST_CEIL))
17763    (use (match_operand:HI 2 "memory_operand" "m"))
17764    (use (match_operand:HI 3 "memory_operand" "m"))
17765    (clobber (match_scratch:XF 4 "=&1f"))]
17766   "TARGET_USE_FANCY_MATH_387
17767    && flag_unsafe_math_optimizations"
17768   "* return output_fix_trunc (insn, operands, 0);"
17769   [(set_attr "type" "fistp")
17770    (set_attr "i387_cw" "ceil")
17771    (set_attr "mode" "DI")])
17772
17773 (define_insn "fistdi2_ceil_with_temp"
17774   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17775         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17776          UNSPEC_FIST_CEIL))
17777    (use (match_operand:HI 2 "memory_operand" "m,m"))
17778    (use (match_operand:HI 3 "memory_operand" "m,m"))
17779    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17780    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17781   "TARGET_USE_FANCY_MATH_387
17782    && flag_unsafe_math_optimizations"
17783   "#"
17784   [(set_attr "type" "fistp")
17785    (set_attr "i387_cw" "ceil")
17786    (set_attr "mode" "DI")])
17787
17788 (define_split
17789   [(set (match_operand:DI 0 "register_operand" "")
17790         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17791          UNSPEC_FIST_CEIL))
17792    (use (match_operand:HI 2 "memory_operand" ""))
17793    (use (match_operand:HI 3 "memory_operand" ""))
17794    (clobber (match_operand:DI 4 "memory_operand" ""))
17795    (clobber (match_scratch 5 ""))]
17796   "reload_completed"
17797   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17798               (use (match_dup 2))
17799               (use (match_dup 3))
17800               (clobber (match_dup 5))])
17801    (set (match_dup 0) (match_dup 4))]
17802   "")
17803
17804 (define_split
17805   [(set (match_operand:DI 0 "memory_operand" "")
17806         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17807          UNSPEC_FIST_CEIL))
17808    (use (match_operand:HI 2 "memory_operand" ""))
17809    (use (match_operand:HI 3 "memory_operand" ""))
17810    (clobber (match_operand:DI 4 "memory_operand" ""))
17811    (clobber (match_scratch 5 ""))]
17812   "reload_completed"
17813   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17814               (use (match_dup 2))
17815               (use (match_dup 3))
17816               (clobber (match_dup 5))])]
17817   "")
17818
17819 (define_insn "fist<mode>2_ceil"
17820   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17821         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17822          UNSPEC_FIST_CEIL))
17823    (use (match_operand:HI 2 "memory_operand" "m"))
17824    (use (match_operand:HI 3 "memory_operand" "m"))]
17825   "TARGET_USE_FANCY_MATH_387
17826    && flag_unsafe_math_optimizations"
17827   "* return output_fix_trunc (insn, operands, 0);"
17828   [(set_attr "type" "fistp")
17829    (set_attr "i387_cw" "ceil")
17830    (set_attr "mode" "<MODE>")])
17831
17832 (define_insn "fist<mode>2_ceil_with_temp"
17833   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17834         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17835          UNSPEC_FIST_CEIL))
17836    (use (match_operand:HI 2 "memory_operand" "m,m"))
17837    (use (match_operand:HI 3 "memory_operand" "m,m"))
17838    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17839   "TARGET_USE_FANCY_MATH_387
17840    && flag_unsafe_math_optimizations"
17841   "#"
17842   [(set_attr "type" "fistp")
17843    (set_attr "i387_cw" "ceil")
17844    (set_attr "mode" "<MODE>")])
17845
17846 (define_split
17847   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17848         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17849          UNSPEC_FIST_CEIL))
17850    (use (match_operand:HI 2 "memory_operand" ""))
17851    (use (match_operand:HI 3 "memory_operand" ""))
17852    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17853   "reload_completed"
17854   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17855                                   UNSPEC_FIST_CEIL))
17856               (use (match_dup 2))
17857               (use (match_dup 3))])
17858    (set (match_dup 0) (match_dup 4))]
17859   "")
17860
17861 (define_split
17862   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17863         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17864          UNSPEC_FIST_CEIL))
17865    (use (match_operand:HI 2 "memory_operand" ""))
17866    (use (match_operand:HI 3 "memory_operand" ""))
17867    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17868   "reload_completed"
17869   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17870                                   UNSPEC_FIST_CEIL))
17871               (use (match_dup 2))
17872               (use (match_dup 3))])]
17873   "")
17874
17875 (define_expand "lceilxf<mode>2"
17876   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17877                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17878                     UNSPEC_FIST_CEIL))
17879               (clobber (reg:CC FLAGS_REG))])]
17880   "TARGET_USE_FANCY_MATH_387
17881    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17882    && flag_unsafe_math_optimizations"
17883   "")
17884
17885 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17886   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17887    (match_operand:MODEF 1 "register_operand" "")]
17888   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17889    && !flag_trapping_math"
17890 {
17891   ix86_expand_lfloorceil (operand0, operand1, false);
17892   DONE;
17893 })
17894
17895 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17896 (define_insn_and_split "frndintxf2_trunc"
17897   [(set (match_operand:XF 0 "register_operand" "")
17898         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17899          UNSPEC_FRNDINT_TRUNC))
17900    (clobber (reg:CC FLAGS_REG))]
17901   "TARGET_USE_FANCY_MATH_387
17902    && flag_unsafe_math_optimizations
17903    && can_create_pseudo_p ()"
17904   "#"
17905   "&& 1"
17906   [(const_int 0)]
17907 {
17908   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17909
17910   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17911   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17912
17913   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17914                                         operands[2], operands[3]));
17915   DONE;
17916 }
17917   [(set_attr "type" "frndint")
17918    (set_attr "i387_cw" "trunc")
17919    (set_attr "mode" "XF")])
17920
17921 (define_insn "frndintxf2_trunc_i387"
17922   [(set (match_operand:XF 0 "register_operand" "=f")
17923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17924          UNSPEC_FRNDINT_TRUNC))
17925    (use (match_operand:HI 2 "memory_operand" "m"))
17926    (use (match_operand:HI 3 "memory_operand" "m"))]
17927   "TARGET_USE_FANCY_MATH_387
17928    && flag_unsafe_math_optimizations"
17929   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17930   [(set_attr "type" "frndint")
17931    (set_attr "i387_cw" "trunc")
17932    (set_attr "mode" "XF")])
17933
17934 (define_expand "btruncxf2"
17935   [(use (match_operand:XF 0 "register_operand" ""))
17936    (use (match_operand:XF 1 "register_operand" ""))]
17937   "TARGET_USE_FANCY_MATH_387
17938    && flag_unsafe_math_optimizations"
17939 {
17940   if (optimize_insn_for_size_p ())
17941     FAIL;
17942   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17943   DONE;
17944 })
17945
17946 (define_expand "btrunc<mode>2"
17947   [(use (match_operand:MODEF 0 "register_operand" ""))
17948    (use (match_operand:MODEF 1 "register_operand" ""))]
17949   "(TARGET_USE_FANCY_MATH_387
17950     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17951         || TARGET_MIX_SSE_I387)
17952     && flag_unsafe_math_optimizations)
17953    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17954        && !flag_trapping_math)"
17955 {
17956   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17957       && !flag_trapping_math
17958       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17959     {
17960       if (TARGET_ROUND)
17961         emit_insn (gen_sse4_1_round<mode>2
17962                    (operands[0], operands[1], GEN_INT (0x03)));
17963       else if (optimize_insn_for_size_p ())
17964         FAIL;
17965       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17966         ix86_expand_trunc (operand0, operand1);
17967       else
17968         ix86_expand_truncdf_32 (operand0, operand1);
17969     }
17970   else
17971     {
17972       rtx op0, op1;
17973
17974       if (optimize_insn_for_size_p ())
17975         FAIL;
17976
17977       op0 = gen_reg_rtx (XFmode);
17978       op1 = gen_reg_rtx (XFmode);
17979       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17980       emit_insn (gen_frndintxf2_trunc (op0, op1));
17981
17982       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17983     }
17984   DONE;
17985 })
17986
17987 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17988 (define_insn_and_split "frndintxf2_mask_pm"
17989   [(set (match_operand:XF 0 "register_operand" "")
17990         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17991          UNSPEC_FRNDINT_MASK_PM))
17992    (clobber (reg:CC FLAGS_REG))]
17993   "TARGET_USE_FANCY_MATH_387
17994    && flag_unsafe_math_optimizations
17995    && can_create_pseudo_p ()"
17996   "#"
17997   "&& 1"
17998   [(const_int 0)]
17999 {
18000   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18001
18002   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18003   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18004
18005   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18006                                           operands[2], operands[3]));
18007   DONE;
18008 }
18009   [(set_attr "type" "frndint")
18010    (set_attr "i387_cw" "mask_pm")
18011    (set_attr "mode" "XF")])
18012
18013 (define_insn "frndintxf2_mask_pm_i387"
18014   [(set (match_operand:XF 0 "register_operand" "=f")
18015         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18016          UNSPEC_FRNDINT_MASK_PM))
18017    (use (match_operand:HI 2 "memory_operand" "m"))
18018    (use (match_operand:HI 3 "memory_operand" "m"))]
18019   "TARGET_USE_FANCY_MATH_387
18020    && flag_unsafe_math_optimizations"
18021   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18022   [(set_attr "type" "frndint")
18023    (set_attr "i387_cw" "mask_pm")
18024    (set_attr "mode" "XF")])
18025
18026 (define_expand "nearbyintxf2"
18027   [(use (match_operand:XF 0 "register_operand" ""))
18028    (use (match_operand:XF 1 "register_operand" ""))]
18029   "TARGET_USE_FANCY_MATH_387
18030    && flag_unsafe_math_optimizations"
18031 {
18032   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18033
18034   DONE;
18035 })
18036
18037 (define_expand "nearbyint<mode>2"
18038   [(use (match_operand:MODEF 0 "register_operand" ""))
18039    (use (match_operand:MODEF 1 "register_operand" ""))]
18040   "TARGET_USE_FANCY_MATH_387
18041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18042        || TARGET_MIX_SSE_I387)
18043    && flag_unsafe_math_optimizations"
18044 {
18045   rtx op0 = gen_reg_rtx (XFmode);
18046   rtx op1 = gen_reg_rtx (XFmode);
18047
18048   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18049   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18050
18051   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18052   DONE;
18053 })
18054
18055 (define_insn "fxam<mode>2_i387"
18056   [(set (match_operand:HI 0 "register_operand" "=a")
18057         (unspec:HI
18058           [(match_operand:X87MODEF 1 "register_operand" "f")]
18059           UNSPEC_FXAM))]
18060   "TARGET_USE_FANCY_MATH_387"
18061   "fxam\n\tfnstsw\t%0"
18062   [(set_attr "type" "multi")
18063    (set_attr "length" "4")
18064    (set_attr "unit" "i387")
18065    (set_attr "mode" "<MODE>")])
18066
18067 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18068   [(set (match_operand:HI 0 "register_operand" "")
18069         (unspec:HI
18070           [(match_operand:MODEF 1 "memory_operand" "")]
18071           UNSPEC_FXAM_MEM))]
18072   "TARGET_USE_FANCY_MATH_387
18073    && can_create_pseudo_p ()"
18074   "#"
18075   "&& 1"
18076   [(set (match_dup 2)(match_dup 1))
18077    (set (match_dup 0)
18078         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18079 {
18080   operands[2] = gen_reg_rtx (<MODE>mode);
18081
18082   MEM_VOLATILE_P (operands[1]) = 1;
18083 }
18084   [(set_attr "type" "multi")
18085    (set_attr "unit" "i387")
18086    (set_attr "mode" "<MODE>")])
18087
18088 (define_expand "isinfxf2"
18089   [(use (match_operand:SI 0 "register_operand" ""))
18090    (use (match_operand:XF 1 "register_operand" ""))]
18091   "TARGET_USE_FANCY_MATH_387
18092    && TARGET_C99_FUNCTIONS"
18093 {
18094   rtx mask = GEN_INT (0x45);
18095   rtx val = GEN_INT (0x05);
18096
18097   rtx cond;
18098
18099   rtx scratch = gen_reg_rtx (HImode);
18100   rtx res = gen_reg_rtx (QImode);
18101
18102   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18103
18104   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18105   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18106   cond = gen_rtx_fmt_ee (EQ, QImode,
18107                          gen_rtx_REG (CCmode, FLAGS_REG),
18108                          const0_rtx);
18109   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18110   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18111   DONE;
18112 })
18113
18114 (define_expand "isinf<mode>2"
18115   [(use (match_operand:SI 0 "register_operand" ""))
18116    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18117   "TARGET_USE_FANCY_MATH_387
18118    && TARGET_C99_FUNCTIONS
18119    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18120 {
18121   rtx mask = GEN_INT (0x45);
18122   rtx val = GEN_INT (0x05);
18123
18124   rtx cond;
18125
18126   rtx scratch = gen_reg_rtx (HImode);
18127   rtx res = gen_reg_rtx (QImode);
18128
18129   /* Remove excess precision by forcing value through memory. */
18130   if (memory_operand (operands[1], VOIDmode))
18131     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18132   else
18133     {
18134       enum ix86_stack_slot slot = (virtuals_instantiated
18135                                    ? SLOT_TEMP
18136                                    : SLOT_VIRTUAL);
18137       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18138
18139       emit_move_insn (temp, operands[1]);
18140       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18141     }
18142
18143   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18144   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18145   cond = gen_rtx_fmt_ee (EQ, QImode,
18146                          gen_rtx_REG (CCmode, FLAGS_REG),
18147                          const0_rtx);
18148   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18149   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18150   DONE;
18151 })
18152
18153 (define_expand "signbit<mode>2"
18154   [(use (match_operand:SI 0 "register_operand" ""))
18155    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18156   "TARGET_USE_FANCY_MATH_387
18157    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18158 {
18159   rtx mask = GEN_INT (0x0200);
18160
18161   rtx scratch = gen_reg_rtx (HImode);
18162
18163   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18164   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18165   DONE;
18166 })
18167 \f
18168 ;; Block operation instructions
18169
18170 (define_insn "cld"
18171   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18172   ""
18173   "cld"
18174   [(set_attr "length" "1")
18175    (set_attr "length_immediate" "0")
18176    (set_attr "modrm" "0")])
18177
18178 (define_expand "movmemsi"
18179   [(use (match_operand:BLK 0 "memory_operand" ""))
18180    (use (match_operand:BLK 1 "memory_operand" ""))
18181    (use (match_operand:SI 2 "nonmemory_operand" ""))
18182    (use (match_operand:SI 3 "const_int_operand" ""))
18183    (use (match_operand:SI 4 "const_int_operand" ""))
18184    (use (match_operand:SI 5 "const_int_operand" ""))]
18185   ""
18186 {
18187  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18188                          operands[4], operands[5]))
18189    DONE;
18190  else
18191    FAIL;
18192 })
18193
18194 (define_expand "movmemdi"
18195   [(use (match_operand:BLK 0 "memory_operand" ""))
18196    (use (match_operand:BLK 1 "memory_operand" ""))
18197    (use (match_operand:DI 2 "nonmemory_operand" ""))
18198    (use (match_operand:DI 3 "const_int_operand" ""))
18199    (use (match_operand:SI 4 "const_int_operand" ""))
18200    (use (match_operand:SI 5 "const_int_operand" ""))]
18201   "TARGET_64BIT"
18202 {
18203  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18204                          operands[4], operands[5]))
18205    DONE;
18206  else
18207    FAIL;
18208 })
18209
18210 ;; Most CPUs don't like single string operations
18211 ;; Handle this case here to simplify previous expander.
18212
18213 (define_expand "strmov"
18214   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18215    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18216    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18217               (clobber (reg:CC FLAGS_REG))])
18218    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18219               (clobber (reg:CC FLAGS_REG))])]
18220   ""
18221 {
18222   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18223
18224   /* If .md ever supports :P for Pmode, these can be directly
18225      in the pattern above.  */
18226   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18227   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18228
18229   /* Can't use this if the user has appropriated esi or edi.  */
18230   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18231       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18232     {
18233       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18234                                       operands[2], operands[3],
18235                                       operands[5], operands[6]));
18236       DONE;
18237     }
18238
18239   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18240 })
18241
18242 (define_expand "strmov_singleop"
18243   [(parallel [(set (match_operand 1 "memory_operand" "")
18244                    (match_operand 3 "memory_operand" ""))
18245               (set (match_operand 0 "register_operand" "")
18246                    (match_operand 4 "" ""))
18247               (set (match_operand 2 "register_operand" "")
18248                    (match_operand 5 "" ""))])]
18249   ""
18250   "ix86_current_function_needs_cld = 1;")
18251
18252 (define_insn "*strmovdi_rex_1"
18253   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18254         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18255    (set (match_operand:DI 0 "register_operand" "=D")
18256         (plus:DI (match_dup 2)
18257                  (const_int 8)))
18258    (set (match_operand:DI 1 "register_operand" "=S")
18259         (plus:DI (match_dup 3)
18260                  (const_int 8)))]
18261   "TARGET_64BIT"
18262   "movsq"
18263   [(set_attr "type" "str")
18264    (set_attr "mode" "DI")
18265    (set_attr "memory" "both")])
18266
18267 (define_insn "*strmovsi_1"
18268   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18269         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18270    (set (match_operand:SI 0 "register_operand" "=D")
18271         (plus:SI (match_dup 2)
18272                  (const_int 4)))
18273    (set (match_operand:SI 1 "register_operand" "=S")
18274         (plus:SI (match_dup 3)
18275                  (const_int 4)))]
18276   "!TARGET_64BIT"
18277   "movs{l|d}"
18278   [(set_attr "type" "str")
18279    (set_attr "mode" "SI")
18280    (set_attr "memory" "both")])
18281
18282 (define_insn "*strmovsi_rex_1"
18283   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18284         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18285    (set (match_operand:DI 0 "register_operand" "=D")
18286         (plus:DI (match_dup 2)
18287                  (const_int 4)))
18288    (set (match_operand:DI 1 "register_operand" "=S")
18289         (plus:DI (match_dup 3)
18290                  (const_int 4)))]
18291   "TARGET_64BIT"
18292   "movs{l|d}"
18293   [(set_attr "type" "str")
18294    (set_attr "mode" "SI")
18295    (set_attr "memory" "both")])
18296
18297 (define_insn "*strmovhi_1"
18298   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18299         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18300    (set (match_operand:SI 0 "register_operand" "=D")
18301         (plus:SI (match_dup 2)
18302                  (const_int 2)))
18303    (set (match_operand:SI 1 "register_operand" "=S")
18304         (plus:SI (match_dup 3)
18305                  (const_int 2)))]
18306   "!TARGET_64BIT"
18307   "movsw"
18308   [(set_attr "type" "str")
18309    (set_attr "memory" "both")
18310    (set_attr "mode" "HI")])
18311
18312 (define_insn "*strmovhi_rex_1"
18313   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18314         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18315    (set (match_operand:DI 0 "register_operand" "=D")
18316         (plus:DI (match_dup 2)
18317                  (const_int 2)))
18318    (set (match_operand:DI 1 "register_operand" "=S")
18319         (plus:DI (match_dup 3)
18320                  (const_int 2)))]
18321   "TARGET_64BIT"
18322   "movsw"
18323   [(set_attr "type" "str")
18324    (set_attr "memory" "both")
18325    (set_attr "mode" "HI")])
18326
18327 (define_insn "*strmovqi_1"
18328   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18329         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18330    (set (match_operand:SI 0 "register_operand" "=D")
18331         (plus:SI (match_dup 2)
18332                  (const_int 1)))
18333    (set (match_operand:SI 1 "register_operand" "=S")
18334         (plus:SI (match_dup 3)
18335                  (const_int 1)))]
18336   "!TARGET_64BIT"
18337   "movsb"
18338   [(set_attr "type" "str")
18339    (set_attr "memory" "both")
18340    (set_attr "mode" "QI")])
18341
18342 (define_insn "*strmovqi_rex_1"
18343   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18344         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18345    (set (match_operand:DI 0 "register_operand" "=D")
18346         (plus:DI (match_dup 2)
18347                  (const_int 1)))
18348    (set (match_operand:DI 1 "register_operand" "=S")
18349         (plus:DI (match_dup 3)
18350                  (const_int 1)))]
18351   "TARGET_64BIT"
18352   "movsb"
18353   [(set_attr "type" "str")
18354    (set_attr "memory" "both")
18355    (set_attr "prefix_rex" "0")
18356    (set_attr "mode" "QI")])
18357
18358 (define_expand "rep_mov"
18359   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18360               (set (match_operand 0 "register_operand" "")
18361                    (match_operand 5 "" ""))
18362               (set (match_operand 2 "register_operand" "")
18363                    (match_operand 6 "" ""))
18364               (set (match_operand 1 "memory_operand" "")
18365                    (match_operand 3 "memory_operand" ""))
18366               (use (match_dup 4))])]
18367   ""
18368   "ix86_current_function_needs_cld = 1;")
18369
18370 (define_insn "*rep_movdi_rex64"
18371   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18372    (set (match_operand:DI 0 "register_operand" "=D")
18373         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18374                             (const_int 3))
18375                  (match_operand:DI 3 "register_operand" "0")))
18376    (set (match_operand:DI 1 "register_operand" "=S")
18377         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18378                  (match_operand:DI 4 "register_operand" "1")))
18379    (set (mem:BLK (match_dup 3))
18380         (mem:BLK (match_dup 4)))
18381    (use (match_dup 5))]
18382   "TARGET_64BIT"
18383   "rep movsq"
18384   [(set_attr "type" "str")
18385    (set_attr "prefix_rep" "1")
18386    (set_attr "memory" "both")
18387    (set_attr "mode" "DI")])
18388
18389 (define_insn "*rep_movsi"
18390   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18391    (set (match_operand:SI 0 "register_operand" "=D")
18392         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18393                             (const_int 2))
18394                  (match_operand:SI 3 "register_operand" "0")))
18395    (set (match_operand:SI 1 "register_operand" "=S")
18396         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18397                  (match_operand:SI 4 "register_operand" "1")))
18398    (set (mem:BLK (match_dup 3))
18399         (mem:BLK (match_dup 4)))
18400    (use (match_dup 5))]
18401   "!TARGET_64BIT"
18402   "rep movs{l|d}"
18403   [(set_attr "type" "str")
18404    (set_attr "prefix_rep" "1")
18405    (set_attr "memory" "both")
18406    (set_attr "mode" "SI")])
18407
18408 (define_insn "*rep_movsi_rex64"
18409   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18410    (set (match_operand:DI 0 "register_operand" "=D")
18411         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18412                             (const_int 2))
18413                  (match_operand:DI 3 "register_operand" "0")))
18414    (set (match_operand:DI 1 "register_operand" "=S")
18415         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18416                  (match_operand:DI 4 "register_operand" "1")))
18417    (set (mem:BLK (match_dup 3))
18418         (mem:BLK (match_dup 4)))
18419    (use (match_dup 5))]
18420   "TARGET_64BIT"
18421   "rep movs{l|d}"
18422   [(set_attr "type" "str")
18423    (set_attr "prefix_rep" "1")
18424    (set_attr "memory" "both")
18425    (set_attr "mode" "SI")])
18426
18427 (define_insn "*rep_movqi"
18428   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18429    (set (match_operand:SI 0 "register_operand" "=D")
18430         (plus:SI (match_operand:SI 3 "register_operand" "0")
18431                  (match_operand:SI 5 "register_operand" "2")))
18432    (set (match_operand:SI 1 "register_operand" "=S")
18433         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18434    (set (mem:BLK (match_dup 3))
18435         (mem:BLK (match_dup 4)))
18436    (use (match_dup 5))]
18437   "!TARGET_64BIT"
18438   "rep movsb"
18439   [(set_attr "type" "str")
18440    (set_attr "prefix_rep" "1")
18441    (set_attr "memory" "both")
18442    (set_attr "mode" "SI")])
18443
18444 (define_insn "*rep_movqi_rex64"
18445   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18446    (set (match_operand:DI 0 "register_operand" "=D")
18447         (plus:DI (match_operand:DI 3 "register_operand" "0")
18448                  (match_operand:DI 5 "register_operand" "2")))
18449    (set (match_operand:DI 1 "register_operand" "=S")
18450         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18451    (set (mem:BLK (match_dup 3))
18452         (mem:BLK (match_dup 4)))
18453    (use (match_dup 5))]
18454   "TARGET_64BIT"
18455   "rep movsb"
18456   [(set_attr "type" "str")
18457    (set_attr "prefix_rep" "1")
18458    (set_attr "memory" "both")
18459    (set_attr "mode" "SI")])
18460
18461 (define_expand "setmemsi"
18462    [(use (match_operand:BLK 0 "memory_operand" ""))
18463     (use (match_operand:SI 1 "nonmemory_operand" ""))
18464     (use (match_operand 2 "const_int_operand" ""))
18465     (use (match_operand 3 "const_int_operand" ""))
18466     (use (match_operand:SI 4 "const_int_operand" ""))
18467     (use (match_operand:SI 5 "const_int_operand" ""))]
18468   ""
18469 {
18470  if (ix86_expand_setmem (operands[0], operands[1],
18471                          operands[2], operands[3],
18472                          operands[4], operands[5]))
18473    DONE;
18474  else
18475    FAIL;
18476 })
18477
18478 (define_expand "setmemdi"
18479    [(use (match_operand:BLK 0 "memory_operand" ""))
18480     (use (match_operand:DI 1 "nonmemory_operand" ""))
18481     (use (match_operand 2 "const_int_operand" ""))
18482     (use (match_operand 3 "const_int_operand" ""))
18483     (use (match_operand 4 "const_int_operand" ""))
18484     (use (match_operand 5 "const_int_operand" ""))]
18485   "TARGET_64BIT"
18486 {
18487  if (ix86_expand_setmem (operands[0], operands[1],
18488                          operands[2], operands[3],
18489                          operands[4], operands[5]))
18490    DONE;
18491  else
18492    FAIL;
18493 })
18494
18495 ;; Most CPUs don't like single string operations
18496 ;; Handle this case here to simplify previous expander.
18497
18498 (define_expand "strset"
18499   [(set (match_operand 1 "memory_operand" "")
18500         (match_operand 2 "register_operand" ""))
18501    (parallel [(set (match_operand 0 "register_operand" "")
18502                    (match_dup 3))
18503               (clobber (reg:CC FLAGS_REG))])]
18504   ""
18505 {
18506   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18507     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18508
18509   /* If .md ever supports :P for Pmode, this can be directly
18510      in the pattern above.  */
18511   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18512                               GEN_INT (GET_MODE_SIZE (GET_MODE
18513                                                       (operands[2]))));
18514   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18515     {
18516       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18517                                       operands[3]));
18518       DONE;
18519     }
18520 })
18521
18522 (define_expand "strset_singleop"
18523   [(parallel [(set (match_operand 1 "memory_operand" "")
18524                    (match_operand 2 "register_operand" ""))
18525               (set (match_operand 0 "register_operand" "")
18526                    (match_operand 3 "" ""))])]
18527   ""
18528   "ix86_current_function_needs_cld = 1;")
18529
18530 (define_insn "*strsetdi_rex_1"
18531   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18532         (match_operand:DI 2 "register_operand" "a"))
18533    (set (match_operand:DI 0 "register_operand" "=D")
18534         (plus:DI (match_dup 1)
18535                  (const_int 8)))]
18536   "TARGET_64BIT"
18537   "stosq"
18538   [(set_attr "type" "str")
18539    (set_attr "memory" "store")
18540    (set_attr "mode" "DI")])
18541
18542 (define_insn "*strsetsi_1"
18543   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18544         (match_operand:SI 2 "register_operand" "a"))
18545    (set (match_operand:SI 0 "register_operand" "=D")
18546         (plus:SI (match_dup 1)
18547                  (const_int 4)))]
18548   "!TARGET_64BIT"
18549   "stos{l|d}"
18550   [(set_attr "type" "str")
18551    (set_attr "memory" "store")
18552    (set_attr "mode" "SI")])
18553
18554 (define_insn "*strsetsi_rex_1"
18555   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18556         (match_operand:SI 2 "register_operand" "a"))
18557    (set (match_operand:DI 0 "register_operand" "=D")
18558         (plus:DI (match_dup 1)
18559                  (const_int 4)))]
18560   "TARGET_64BIT"
18561   "stos{l|d}"
18562   [(set_attr "type" "str")
18563    (set_attr "memory" "store")
18564    (set_attr "mode" "SI")])
18565
18566 (define_insn "*strsethi_1"
18567   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18568         (match_operand:HI 2 "register_operand" "a"))
18569    (set (match_operand:SI 0 "register_operand" "=D")
18570         (plus:SI (match_dup 1)
18571                  (const_int 2)))]
18572   "!TARGET_64BIT"
18573   "stosw"
18574   [(set_attr "type" "str")
18575    (set_attr "memory" "store")
18576    (set_attr "mode" "HI")])
18577
18578 (define_insn "*strsethi_rex_1"
18579   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18580         (match_operand:HI 2 "register_operand" "a"))
18581    (set (match_operand:DI 0 "register_operand" "=D")
18582         (plus:DI (match_dup 1)
18583                  (const_int 2)))]
18584   "TARGET_64BIT"
18585   "stosw"
18586   [(set_attr "type" "str")
18587    (set_attr "memory" "store")
18588    (set_attr "mode" "HI")])
18589
18590 (define_insn "*strsetqi_1"
18591   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18592         (match_operand:QI 2 "register_operand" "a"))
18593    (set (match_operand:SI 0 "register_operand" "=D")
18594         (plus:SI (match_dup 1)
18595                  (const_int 1)))]
18596   "!TARGET_64BIT"
18597   "stosb"
18598   [(set_attr "type" "str")
18599    (set_attr "memory" "store")
18600    (set_attr "mode" "QI")])
18601
18602 (define_insn "*strsetqi_rex_1"
18603   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18604         (match_operand:QI 2 "register_operand" "a"))
18605    (set (match_operand:DI 0 "register_operand" "=D")
18606         (plus:DI (match_dup 1)
18607                  (const_int 1)))]
18608   "TARGET_64BIT"
18609   "stosb"
18610   [(set_attr "type" "str")
18611    (set_attr "memory" "store")
18612    (set_attr "prefix_rex" "0")
18613    (set_attr "mode" "QI")])
18614
18615 (define_expand "rep_stos"
18616   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18617               (set (match_operand 0 "register_operand" "")
18618                    (match_operand 4 "" ""))
18619               (set (match_operand 2 "memory_operand" "") (const_int 0))
18620               (use (match_operand 3 "register_operand" ""))
18621               (use (match_dup 1))])]
18622   ""
18623   "ix86_current_function_needs_cld = 1;")
18624
18625 (define_insn "*rep_stosdi_rex64"
18626   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18627    (set (match_operand:DI 0 "register_operand" "=D")
18628         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18629                             (const_int 3))
18630                  (match_operand:DI 3 "register_operand" "0")))
18631    (set (mem:BLK (match_dup 3))
18632         (const_int 0))
18633    (use (match_operand:DI 2 "register_operand" "a"))
18634    (use (match_dup 4))]
18635   "TARGET_64BIT"
18636   "rep stosq"
18637   [(set_attr "type" "str")
18638    (set_attr "prefix_rep" "1")
18639    (set_attr "memory" "store")
18640    (set_attr "mode" "DI")])
18641
18642 (define_insn "*rep_stossi"
18643   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18644    (set (match_operand:SI 0 "register_operand" "=D")
18645         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18646                             (const_int 2))
18647                  (match_operand:SI 3 "register_operand" "0")))
18648    (set (mem:BLK (match_dup 3))
18649         (const_int 0))
18650    (use (match_operand:SI 2 "register_operand" "a"))
18651    (use (match_dup 4))]
18652   "!TARGET_64BIT"
18653   "rep stos{l|d}"
18654   [(set_attr "type" "str")
18655    (set_attr "prefix_rep" "1")
18656    (set_attr "memory" "store")
18657    (set_attr "mode" "SI")])
18658
18659 (define_insn "*rep_stossi_rex64"
18660   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18661    (set (match_operand:DI 0 "register_operand" "=D")
18662         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18663                             (const_int 2))
18664                  (match_operand:DI 3 "register_operand" "0")))
18665    (set (mem:BLK (match_dup 3))
18666         (const_int 0))
18667    (use (match_operand:SI 2 "register_operand" "a"))
18668    (use (match_dup 4))]
18669   "TARGET_64BIT"
18670   "rep stos{l|d}"
18671   [(set_attr "type" "str")
18672    (set_attr "prefix_rep" "1")
18673    (set_attr "memory" "store")
18674    (set_attr "mode" "SI")])
18675
18676 (define_insn "*rep_stosqi"
18677   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18678    (set (match_operand:SI 0 "register_operand" "=D")
18679         (plus:SI (match_operand:SI 3 "register_operand" "0")
18680                  (match_operand:SI 4 "register_operand" "1")))
18681    (set (mem:BLK (match_dup 3))
18682         (const_int 0))
18683    (use (match_operand:QI 2 "register_operand" "a"))
18684    (use (match_dup 4))]
18685   "!TARGET_64BIT"
18686   "rep stosb"
18687   [(set_attr "type" "str")
18688    (set_attr "prefix_rep" "1")
18689    (set_attr "memory" "store")
18690    (set_attr "mode" "QI")])
18691
18692 (define_insn "*rep_stosqi_rex64"
18693   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18694    (set (match_operand:DI 0 "register_operand" "=D")
18695         (plus:DI (match_operand:DI 3 "register_operand" "0")
18696                  (match_operand:DI 4 "register_operand" "1")))
18697    (set (mem:BLK (match_dup 3))
18698         (const_int 0))
18699    (use (match_operand:QI 2 "register_operand" "a"))
18700    (use (match_dup 4))]
18701   "TARGET_64BIT"
18702   "rep stosb"
18703   [(set_attr "type" "str")
18704    (set_attr "prefix_rep" "1")
18705    (set_attr "memory" "store")
18706    (set_attr "prefix_rex" "0")
18707    (set_attr "mode" "QI")])
18708
18709 (define_expand "cmpstrnsi"
18710   [(set (match_operand:SI 0 "register_operand" "")
18711         (compare:SI (match_operand:BLK 1 "general_operand" "")
18712                     (match_operand:BLK 2 "general_operand" "")))
18713    (use (match_operand 3 "general_operand" ""))
18714    (use (match_operand 4 "immediate_operand" ""))]
18715   ""
18716 {
18717   rtx addr1, addr2, out, outlow, count, countreg, align;
18718
18719   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18720     FAIL;
18721
18722   /* Can't use this if the user has appropriated esi or edi.  */
18723   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18724     FAIL;
18725
18726   out = operands[0];
18727   if (!REG_P (out))
18728     out = gen_reg_rtx (SImode);
18729
18730   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18731   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18732   if (addr1 != XEXP (operands[1], 0))
18733     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18734   if (addr2 != XEXP (operands[2], 0))
18735     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18736
18737   count = operands[3];
18738   countreg = ix86_zero_extend_to_Pmode (count);
18739
18740   /* %%% Iff we are testing strict equality, we can use known alignment
18741      to good advantage.  This may be possible with combine, particularly
18742      once cc0 is dead.  */
18743   align = operands[4];
18744
18745   if (CONST_INT_P (count))
18746     {
18747       if (INTVAL (count) == 0)
18748         {
18749           emit_move_insn (operands[0], const0_rtx);
18750           DONE;
18751         }
18752       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18753                                      operands[1], operands[2]));
18754     }
18755   else
18756     {
18757       rtx (*cmp_insn)(rtx, rtx);
18758
18759       if (TARGET_64BIT)
18760         cmp_insn = gen_cmpdi_1;
18761       else
18762         cmp_insn = gen_cmpsi_1;
18763       emit_insn (cmp_insn (countreg, countreg));
18764       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18765                                   operands[1], operands[2]));
18766     }
18767
18768   outlow = gen_lowpart (QImode, out);
18769   emit_insn (gen_cmpintqi (outlow));
18770   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18771
18772   if (operands[0] != out)
18773     emit_move_insn (operands[0], out);
18774
18775   DONE;
18776 })
18777
18778 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18779
18780 (define_expand "cmpintqi"
18781   [(set (match_dup 1)
18782         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18783    (set (match_dup 2)
18784         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18785    (parallel [(set (match_operand:QI 0 "register_operand" "")
18786                    (minus:QI (match_dup 1)
18787                              (match_dup 2)))
18788               (clobber (reg:CC FLAGS_REG))])]
18789   ""
18790   "operands[1] = gen_reg_rtx (QImode);
18791    operands[2] = gen_reg_rtx (QImode);")
18792
18793 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18794 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18795
18796 (define_expand "cmpstrnqi_nz_1"
18797   [(parallel [(set (reg:CC FLAGS_REG)
18798                    (compare:CC (match_operand 4 "memory_operand" "")
18799                                (match_operand 5 "memory_operand" "")))
18800               (use (match_operand 2 "register_operand" ""))
18801               (use (match_operand:SI 3 "immediate_operand" ""))
18802               (clobber (match_operand 0 "register_operand" ""))
18803               (clobber (match_operand 1 "register_operand" ""))
18804               (clobber (match_dup 2))])]
18805   ""
18806   "ix86_current_function_needs_cld = 1;")
18807
18808 (define_insn "*cmpstrnqi_nz_1"
18809   [(set (reg:CC FLAGS_REG)
18810         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18811                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18812    (use (match_operand:SI 6 "register_operand" "2"))
18813    (use (match_operand:SI 3 "immediate_operand" "i"))
18814    (clobber (match_operand:SI 0 "register_operand" "=S"))
18815    (clobber (match_operand:SI 1 "register_operand" "=D"))
18816    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18817   "!TARGET_64BIT"
18818   "repz cmpsb"
18819   [(set_attr "type" "str")
18820    (set_attr "mode" "QI")
18821    (set_attr "prefix_rep" "1")])
18822
18823 (define_insn "*cmpstrnqi_nz_rex_1"
18824   [(set (reg:CC FLAGS_REG)
18825         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18826                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18827    (use (match_operand:DI 6 "register_operand" "2"))
18828    (use (match_operand:SI 3 "immediate_operand" "i"))
18829    (clobber (match_operand:DI 0 "register_operand" "=S"))
18830    (clobber (match_operand:DI 1 "register_operand" "=D"))
18831    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18832   "TARGET_64BIT"
18833   "repz cmpsb"
18834   [(set_attr "type" "str")
18835    (set_attr "mode" "QI")
18836    (set_attr "prefix_rex" "0")
18837    (set_attr "prefix_rep" "1")])
18838
18839 ;; The same, but the count is not known to not be zero.
18840
18841 (define_expand "cmpstrnqi_1"
18842   [(parallel [(set (reg:CC FLAGS_REG)
18843                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18844                                      (const_int 0))
18845                   (compare:CC (match_operand 4 "memory_operand" "")
18846                               (match_operand 5 "memory_operand" ""))
18847                   (const_int 0)))
18848               (use (match_operand:SI 3 "immediate_operand" ""))
18849               (use (reg:CC FLAGS_REG))
18850               (clobber (match_operand 0 "register_operand" ""))
18851               (clobber (match_operand 1 "register_operand" ""))
18852               (clobber (match_dup 2))])]
18853   ""
18854   "ix86_current_function_needs_cld = 1;")
18855
18856 (define_insn "*cmpstrnqi_1"
18857   [(set (reg:CC FLAGS_REG)
18858         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18859                              (const_int 0))
18860           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18861                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18862           (const_int 0)))
18863    (use (match_operand:SI 3 "immediate_operand" "i"))
18864    (use (reg:CC FLAGS_REG))
18865    (clobber (match_operand:SI 0 "register_operand" "=S"))
18866    (clobber (match_operand:SI 1 "register_operand" "=D"))
18867    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18868   "!TARGET_64BIT"
18869   "repz cmpsb"
18870   [(set_attr "type" "str")
18871    (set_attr "mode" "QI")
18872    (set_attr "prefix_rep" "1")])
18873
18874 (define_insn "*cmpstrnqi_rex_1"
18875   [(set (reg:CC FLAGS_REG)
18876         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18877                              (const_int 0))
18878           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18879                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18880           (const_int 0)))
18881    (use (match_operand:SI 3 "immediate_operand" "i"))
18882    (use (reg:CC FLAGS_REG))
18883    (clobber (match_operand:DI 0 "register_operand" "=S"))
18884    (clobber (match_operand:DI 1 "register_operand" "=D"))
18885    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18886   "TARGET_64BIT"
18887   "repz cmpsb"
18888   [(set_attr "type" "str")
18889    (set_attr "mode" "QI")
18890    (set_attr "prefix_rex" "0")
18891    (set_attr "prefix_rep" "1")])
18892
18893 (define_expand "strlensi"
18894   [(set (match_operand:SI 0 "register_operand" "")
18895         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18896                     (match_operand:QI 2 "immediate_operand" "")
18897                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18898   ""
18899 {
18900  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18901    DONE;
18902  else
18903    FAIL;
18904 })
18905
18906 (define_expand "strlendi"
18907   [(set (match_operand:DI 0 "register_operand" "")
18908         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18909                     (match_operand:QI 2 "immediate_operand" "")
18910                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18911   ""
18912 {
18913  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18914    DONE;
18915  else
18916    FAIL;
18917 })
18918
18919 (define_expand "strlenqi_1"
18920   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18921               (clobber (match_operand 1 "register_operand" ""))
18922               (clobber (reg:CC FLAGS_REG))])]
18923   ""
18924   "ix86_current_function_needs_cld = 1;")
18925
18926 (define_insn "*strlenqi_1"
18927   [(set (match_operand:SI 0 "register_operand" "=&c")
18928         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18929                     (match_operand:QI 2 "register_operand" "a")
18930                     (match_operand:SI 3 "immediate_operand" "i")
18931                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18932    (clobber (match_operand:SI 1 "register_operand" "=D"))
18933    (clobber (reg:CC FLAGS_REG))]
18934   "!TARGET_64BIT"
18935   "repnz scasb"
18936   [(set_attr "type" "str")
18937    (set_attr "mode" "QI")
18938    (set_attr "prefix_rep" "1")])
18939
18940 (define_insn "*strlenqi_rex_1"
18941   [(set (match_operand:DI 0 "register_operand" "=&c")
18942         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18943                     (match_operand:QI 2 "register_operand" "a")
18944                     (match_operand:DI 3 "immediate_operand" "i")
18945                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18946    (clobber (match_operand:DI 1 "register_operand" "=D"))
18947    (clobber (reg:CC FLAGS_REG))]
18948   "TARGET_64BIT"
18949   "repnz scasb"
18950   [(set_attr "type" "str")
18951    (set_attr "mode" "QI")
18952    (set_attr "prefix_rex" "0")
18953    (set_attr "prefix_rep" "1")])
18954
18955 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18956 ;; handled in combine, but it is not currently up to the task.
18957 ;; When used for their truth value, the cmpstrn* expanders generate
18958 ;; code like this:
18959 ;;
18960 ;;   repz cmpsb
18961 ;;   seta       %al
18962 ;;   setb       %dl
18963 ;;   cmpb       %al, %dl
18964 ;;   jcc        label
18965 ;;
18966 ;; The intermediate three instructions are unnecessary.
18967
18968 ;; This one handles cmpstrn*_nz_1...
18969 (define_peephole2
18970   [(parallel[
18971      (set (reg:CC FLAGS_REG)
18972           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18973                       (mem:BLK (match_operand 5 "register_operand" ""))))
18974      (use (match_operand 6 "register_operand" ""))
18975      (use (match_operand:SI 3 "immediate_operand" ""))
18976      (clobber (match_operand 0 "register_operand" ""))
18977      (clobber (match_operand 1 "register_operand" ""))
18978      (clobber (match_operand 2 "register_operand" ""))])
18979    (set (match_operand:QI 7 "register_operand" "")
18980         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18981    (set (match_operand:QI 8 "register_operand" "")
18982         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18983    (set (reg FLAGS_REG)
18984         (compare (match_dup 7) (match_dup 8)))
18985   ]
18986   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18987   [(parallel[
18988      (set (reg:CC FLAGS_REG)
18989           (compare:CC (mem:BLK (match_dup 4))
18990                       (mem:BLK (match_dup 5))))
18991      (use (match_dup 6))
18992      (use (match_dup 3))
18993      (clobber (match_dup 0))
18994      (clobber (match_dup 1))
18995      (clobber (match_dup 2))])]
18996   "")
18997
18998 ;; ...and this one handles cmpstrn*_1.
18999 (define_peephole2
19000   [(parallel[
19001      (set (reg:CC FLAGS_REG)
19002           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19003                                (const_int 0))
19004             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19005                         (mem:BLK (match_operand 5 "register_operand" "")))
19006             (const_int 0)))
19007      (use (match_operand:SI 3 "immediate_operand" ""))
19008      (use (reg:CC FLAGS_REG))
19009      (clobber (match_operand 0 "register_operand" ""))
19010      (clobber (match_operand 1 "register_operand" ""))
19011      (clobber (match_operand 2 "register_operand" ""))])
19012    (set (match_operand:QI 7 "register_operand" "")
19013         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19014    (set (match_operand:QI 8 "register_operand" "")
19015         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19016    (set (reg FLAGS_REG)
19017         (compare (match_dup 7) (match_dup 8)))
19018   ]
19019   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19020   [(parallel[
19021      (set (reg:CC FLAGS_REG)
19022           (if_then_else:CC (ne (match_dup 6)
19023                                (const_int 0))
19024             (compare:CC (mem:BLK (match_dup 4))
19025                         (mem:BLK (match_dup 5)))
19026             (const_int 0)))
19027      (use (match_dup 3))
19028      (use (reg:CC FLAGS_REG))
19029      (clobber (match_dup 0))
19030      (clobber (match_dup 1))
19031      (clobber (match_dup 2))])]
19032   "")
19033
19034
19035 \f
19036 ;; Conditional move instructions.
19037
19038 (define_expand "mov<mode>cc"
19039   [(set (match_operand:SWIM 0 "register_operand" "")
19040         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
19041                            (match_operand:SWIM 2 "general_operand" "")
19042                            (match_operand:SWIM 3 "general_operand" "")))]
19043   ""
19044   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19045
19046 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19047 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19048 ;; So just document what we're doing explicitly.
19049
19050 (define_expand "x86_mov<mode>cc_0_m1"
19051   [(parallel
19052     [(set (match_operand:SWI48 0 "register_operand" "")
19053           (if_then_else:SWI48
19054             (match_operator:SWI48 2 "ix86_carry_flag_operator"
19055              [(match_operand 1 "flags_reg_operand" "")
19056               (const_int 0)])
19057             (const_int -1)
19058             (const_int 0)))
19059      (clobber (reg:CC FLAGS_REG))])]
19060   ""
19061   "")
19062
19063 (define_insn "*x86_mov<mode>cc_0_m1"
19064   [(set (match_operand:SWI48 0 "register_operand" "=r")
19065         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19066                              [(reg FLAGS_REG) (const_int 0)])
19067           (const_int -1)
19068           (const_int 0)))
19069    (clobber (reg:CC FLAGS_REG))]
19070   ""
19071   "sbb{<imodesuffix>}\t%0, %0"
19072   ; Since we don't have the proper number of operands for an alu insn,
19073   ; fill in all the blanks.
19074   [(set_attr "type" "alu")
19075    (set_attr "use_carry" "1")
19076    (set_attr "pent_pair" "pu")
19077    (set_attr "memory" "none")
19078    (set_attr "imm_disp" "false")
19079    (set_attr "mode" "<MODE>")
19080    (set_attr "length_immediate" "0")])
19081
19082 (define_insn "*x86_mov<mode>cc_0_m1_se"
19083   [(set (match_operand:SWI48 0 "register_operand" "=r")
19084         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19085                              [(reg FLAGS_REG) (const_int 0)])
19086                             (const_int 1)
19087                             (const_int 0)))
19088    (clobber (reg:CC FLAGS_REG))]
19089   ""
19090   "sbb{<imodesuffix>}\t%0, %0"
19091   [(set_attr "type" "alu")
19092    (set_attr "use_carry" "1")
19093    (set_attr "pent_pair" "pu")
19094    (set_attr "memory" "none")
19095    (set_attr "imm_disp" "false")
19096    (set_attr "mode" "<MODE>")
19097    (set_attr "length_immediate" "0")])
19098
19099 (define_insn "*x86_mov<mode>cc_0_m1_neg"
19100   [(set (match_operand:SWI48 0 "register_operand" "=r")
19101         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19102                     [(reg FLAGS_REG) (const_int 0)])))]
19103   ""
19104   "sbb{<imodesuffix>}\t%0, %0"
19105   [(set_attr "type" "alu")
19106    (set_attr "use_carry" "1")
19107    (set_attr "pent_pair" "pu")
19108    (set_attr "memory" "none")
19109    (set_attr "imm_disp" "false")
19110    (set_attr "mode" "<MODE>")
19111    (set_attr "length_immediate" "0")])
19112
19113 (define_insn "*mov<mode>cc_noc"
19114   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
19115         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
19116                                [(reg FLAGS_REG) (const_int 0)])
19117           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
19118           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
19119   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19120   "@
19121    cmov%O2%C1\t{%2, %0|%0, %2}
19122    cmov%O2%c1\t{%3, %0|%0, %3}"
19123   [(set_attr "type" "icmov")
19124    (set_attr "mode" "<MODE>")])
19125
19126 (define_insn_and_split "*movqicc_noc"
19127   [(set (match_operand:QI 0 "register_operand" "=r,r")
19128         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19129                            [(match_operand 4 "flags_reg_operand" "")
19130                             (const_int 0)])
19131                       (match_operand:QI 2 "register_operand" "r,0")
19132                       (match_operand:QI 3 "register_operand" "0,r")))]
19133   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19134   "#"
19135   "&& reload_completed"
19136   [(set (match_dup 0)
19137         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19138                       (match_dup 2)
19139                       (match_dup 3)))]
19140   "operands[0] = gen_lowpart (SImode, operands[0]);
19141    operands[2] = gen_lowpart (SImode, operands[2]);
19142    operands[3] = gen_lowpart (SImode, operands[3]);"
19143   [(set_attr "type" "icmov")
19144    (set_attr "mode" "SI")])
19145
19146 (define_expand "mov<mode>cc"
19147   [(set (match_operand:X87MODEF 0 "register_operand" "")
19148         (if_then_else:X87MODEF
19149           (match_operand 1 "ix86_fp_comparison_operator" "")
19150           (match_operand:X87MODEF 2 "register_operand" "")
19151           (match_operand:X87MODEF 3 "register_operand" "")))]
19152   "(TARGET_80387 && TARGET_CMOVE)
19153    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19154   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19155
19156 (define_insn "*movsfcc_1_387"
19157   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19158         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19159                                 [(reg FLAGS_REG) (const_int 0)])
19160                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19161                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19162   "TARGET_80387 && TARGET_CMOVE
19163    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19164   "@
19165    fcmov%F1\t{%2, %0|%0, %2}
19166    fcmov%f1\t{%3, %0|%0, %3}
19167    cmov%O2%C1\t{%2, %0|%0, %2}
19168    cmov%O2%c1\t{%3, %0|%0, %3}"
19169   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19170    (set_attr "mode" "SF,SF,SI,SI")])
19171
19172 (define_insn "*movdfcc_1"
19173   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19174         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19175                                 [(reg FLAGS_REG) (const_int 0)])
19176                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19177                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19178   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19179    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19180   "@
19181    fcmov%F1\t{%2, %0|%0, %2}
19182    fcmov%f1\t{%3, %0|%0, %3}
19183    #
19184    #"
19185   [(set_attr "type" "fcmov,fcmov,multi,multi")
19186    (set_attr "mode" "DF")])
19187
19188 (define_insn "*movdfcc_1_rex64"
19189   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19190         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19191                                 [(reg FLAGS_REG) (const_int 0)])
19192                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19193                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19194   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19195    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19196   "@
19197    fcmov%F1\t{%2, %0|%0, %2}
19198    fcmov%f1\t{%3, %0|%0, %3}
19199    cmov%O2%C1\t{%2, %0|%0, %2}
19200    cmov%O2%c1\t{%3, %0|%0, %3}"
19201   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19202    (set_attr "mode" "DF")])
19203
19204 (define_split
19205   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19206         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19207                                 [(match_operand 4 "flags_reg_operand" "")
19208                                  (const_int 0)])
19209                       (match_operand:DF 2 "nonimmediate_operand" "")
19210                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19211   "!TARGET_64BIT && reload_completed"
19212   [(set (match_dup 2)
19213         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19214                       (match_dup 5)
19215                       (match_dup 6)))
19216    (set (match_dup 3)
19217         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19218                       (match_dup 7)
19219                       (match_dup 8)))]
19220   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19221    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19222
19223 (define_insn "*movxfcc_1"
19224   [(set (match_operand:XF 0 "register_operand" "=f,f")
19225         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19226                                 [(reg FLAGS_REG) (const_int 0)])
19227                       (match_operand:XF 2 "register_operand" "f,0")
19228                       (match_operand:XF 3 "register_operand" "0,f")))]
19229   "TARGET_80387 && TARGET_CMOVE"
19230   "@
19231    fcmov%F1\t{%2, %0|%0, %2}
19232    fcmov%f1\t{%3, %0|%0, %3}"
19233   [(set_attr "type" "fcmov")
19234    (set_attr "mode" "XF")])
19235
19236 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
19237 ;; the scalar versions to have only XMM registers as operands.
19238
19239 ;; XOP conditional move
19240 (define_insn "*xop_pcmov_<mode>"
19241   [(set (match_operand:MODEF 0 "register_operand" "=x")
19242         (if_then_else:MODEF
19243           (match_operand:MODEF 1 "register_operand" "x")
19244           (match_operand:MODEF 2 "register_operand" "x")
19245           (match_operand:MODEF 3 "register_operand" "x")))]
19246   "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)"
19247   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19248   [(set_attr "type" "sse4arg")])
19249
19250 ;; These versions of the min/max patterns are intentionally ignorant of
19251 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19252 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19253 ;; are undefined in this condition, we're certain this is correct.
19254
19255 (define_insn "*avx_<code><mode>3"
19256   [(set (match_operand:MODEF 0 "register_operand" "=x")
19257         (smaxmin:MODEF
19258           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19259           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19260   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19261   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19262   [(set_attr "type" "sseadd")
19263    (set_attr "prefix" "vex")
19264    (set_attr "mode" "<MODE>")])
19265
19266 (define_insn "<code><mode>3"
19267   [(set (match_operand:MODEF 0 "register_operand" "=x")
19268         (smaxmin:MODEF
19269           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19270           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19271   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19272   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19273   [(set_attr "type" "sseadd")
19274    (set_attr "mode" "<MODE>")])
19275
19276 ;; These versions of the min/max patterns implement exactly the operations
19277 ;;   min = (op1 < op2 ? op1 : op2)
19278 ;;   max = (!(op1 < op2) ? op1 : op2)
19279 ;; Their operands are not commutative, and thus they may be used in the
19280 ;; presence of -0.0 and NaN.
19281
19282 (define_insn "*avx_ieee_smin<mode>3"
19283   [(set (match_operand:MODEF 0 "register_operand" "=x")
19284         (unspec:MODEF
19285           [(match_operand:MODEF 1 "register_operand" "x")
19286            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19287          UNSPEC_IEEE_MIN))]
19288   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19289   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19290   [(set_attr "type" "sseadd")
19291    (set_attr "prefix" "vex")
19292    (set_attr "mode" "<MODE>")])
19293
19294 (define_insn "*ieee_smin<mode>3"
19295   [(set (match_operand:MODEF 0 "register_operand" "=x")
19296         (unspec:MODEF
19297           [(match_operand:MODEF 1 "register_operand" "0")
19298            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19299          UNSPEC_IEEE_MIN))]
19300   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19301   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19302   [(set_attr "type" "sseadd")
19303    (set_attr "mode" "<MODE>")])
19304
19305 (define_insn "*avx_ieee_smax<mode>3"
19306   [(set (match_operand:MODEF 0 "register_operand" "=x")
19307         (unspec:MODEF
19308           [(match_operand:MODEF 1 "register_operand" "0")
19309            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19310          UNSPEC_IEEE_MAX))]
19311   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19312   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19313   [(set_attr "type" "sseadd")
19314    (set_attr "prefix" "vex")
19315    (set_attr "mode" "<MODE>")])
19316
19317 (define_insn "*ieee_smax<mode>3"
19318   [(set (match_operand:MODEF 0 "register_operand" "=x")
19319         (unspec:MODEF
19320           [(match_operand:MODEF 1 "register_operand" "0")
19321            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19322          UNSPEC_IEEE_MAX))]
19323   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19324   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19325   [(set_attr "type" "sseadd")
19326    (set_attr "mode" "<MODE>")])
19327
19328 ;; Make two stack loads independent:
19329 ;;   fld aa              fld aa
19330 ;;   fld %st(0)     ->   fld bb
19331 ;;   fmul bb             fmul %st(1), %st
19332 ;;
19333 ;; Actually we only match the last two instructions for simplicity.
19334 (define_peephole2
19335   [(set (match_operand 0 "fp_register_operand" "")
19336         (match_operand 1 "fp_register_operand" ""))
19337    (set (match_dup 0)
19338         (match_operator 2 "binary_fp_operator"
19339            [(match_dup 0)
19340             (match_operand 3 "memory_operand" "")]))]
19341   "REGNO (operands[0]) != REGNO (operands[1])"
19342   [(set (match_dup 0) (match_dup 3))
19343    (set (match_dup 0) (match_dup 4))]
19344
19345   ;; The % modifier is not operational anymore in peephole2's, so we have to
19346   ;; swap the operands manually in the case of addition and multiplication.
19347   "if (COMMUTATIVE_ARITH_P (operands[2]))
19348      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19349                                  operands[0], operands[1]);
19350    else
19351      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19352                                  operands[1], operands[0]);")
19353
19354 ;; Conditional addition patterns
19355 (define_expand "add<mode>cc"
19356   [(match_operand:SWI 0 "register_operand" "")
19357    (match_operand 1 "comparison_operator" "")
19358    (match_operand:SWI 2 "register_operand" "")
19359    (match_operand:SWI 3 "const_int_operand" "")]
19360   ""
19361   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19362
19363 \f
19364 ;; Misc patterns (?)
19365
19366 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19367 ;; Otherwise there will be nothing to keep
19368 ;;
19369 ;; [(set (reg ebp) (reg esp))]
19370 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19371 ;;  (clobber (eflags)]
19372 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19373 ;;
19374 ;; in proper program order.
19375 (define_insn "pro_epilogue_adjust_stack_1"
19376   [(set (match_operand:SI 0 "register_operand" "=r,r")
19377         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19378                  (match_operand:SI 2 "immediate_operand" "i,i")))
19379    (clobber (reg:CC FLAGS_REG))
19380    (clobber (mem:BLK (scratch)))]
19381   "!TARGET_64BIT"
19382 {
19383   switch (get_attr_type (insn))
19384     {
19385     case TYPE_IMOV:
19386       return "mov{l}\t{%1, %0|%0, %1}";
19387
19388     case TYPE_ALU:
19389       if (CONST_INT_P (operands[2])
19390           && (INTVAL (operands[2]) == 128
19391               || (INTVAL (operands[2]) < 0
19392                   && INTVAL (operands[2]) != -128)))
19393         {
19394           operands[2] = GEN_INT (-INTVAL (operands[2]));
19395           return "sub{l}\t{%2, %0|%0, %2}";
19396         }
19397       return "add{l}\t{%2, %0|%0, %2}";
19398
19399     case TYPE_LEA:
19400       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19401       return "lea{l}\t{%a2, %0|%0, %a2}";
19402
19403     default:
19404       gcc_unreachable ();
19405     }
19406 }
19407   [(set (attr "type")
19408         (cond [(and (eq_attr "alternative" "0") 
19409                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19410                  (const_string "alu")
19411                (match_operand:SI 2 "const0_operand" "")
19412                  (const_string "imov")
19413               ]
19414               (const_string "lea")))
19415    (set (attr "length_immediate")
19416         (cond [(eq_attr "type" "imov")
19417                  (const_string "0")
19418                (and (eq_attr "type" "alu")
19419                     (match_operand 2 "const128_operand" ""))
19420                  (const_string "1")
19421               ]
19422               (const_string "*")))
19423    (set_attr "mode" "SI")])
19424
19425 (define_insn "pro_epilogue_adjust_stack_rex64"
19426   [(set (match_operand:DI 0 "register_operand" "=r,r")
19427         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19428                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19429    (clobber (reg:CC FLAGS_REG))
19430    (clobber (mem:BLK (scratch)))]
19431   "TARGET_64BIT"
19432 {
19433   switch (get_attr_type (insn))
19434     {
19435     case TYPE_IMOV:
19436       return "mov{q}\t{%1, %0|%0, %1}";
19437
19438     case TYPE_ALU:
19439       if (CONST_INT_P (operands[2])
19440           /* Avoid overflows.  */
19441           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19442           && (INTVAL (operands[2]) == 128
19443               || (INTVAL (operands[2]) < 0
19444                   && INTVAL (operands[2]) != -128)))
19445         {
19446           operands[2] = GEN_INT (-INTVAL (operands[2]));
19447           return "sub{q}\t{%2, %0|%0, %2}";
19448         }
19449       return "add{q}\t{%2, %0|%0, %2}";
19450
19451     case TYPE_LEA:
19452       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19453       return "lea{q}\t{%a2, %0|%0, %a2}";
19454
19455     default:
19456       gcc_unreachable ();
19457     }
19458 }
19459   [(set (attr "type")
19460         (cond [(and (eq_attr "alternative" "0")
19461                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19462                  (const_string "alu")
19463                (match_operand:DI 2 "const0_operand" "")
19464                  (const_string "imov")
19465               ]
19466               (const_string "lea")))
19467    (set (attr "length_immediate")
19468         (cond [(eq_attr "type" "imov")
19469                  (const_string "0")
19470                (and (eq_attr "type" "alu")
19471                     (match_operand 2 "const128_operand" ""))
19472                  (const_string "1")
19473               ]
19474               (const_string "*")))
19475    (set_attr "mode" "DI")])
19476
19477 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19478   [(set (match_operand:DI 0 "register_operand" "=r,r")
19479         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19480                  (match_operand:DI 3 "immediate_operand" "i,i")))
19481    (use (match_operand:DI 2 "register_operand" "r,r"))
19482    (clobber (reg:CC FLAGS_REG))
19483    (clobber (mem:BLK (scratch)))]
19484   "TARGET_64BIT"
19485 {
19486   switch (get_attr_type (insn))
19487     {
19488     case TYPE_ALU:
19489       return "add{q}\t{%2, %0|%0, %2}";
19490
19491     case TYPE_LEA:
19492       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19493       return "lea{q}\t{%a2, %0|%0, %a2}";
19494
19495     default:
19496       gcc_unreachable ();
19497     }
19498 }
19499   [(set_attr "type" "alu,lea")
19500    (set_attr "mode" "DI")])
19501
19502 (define_insn "allocate_stack_worker_32"
19503   [(set (match_operand:SI 0 "register_operand" "=a")
19504         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19505                             UNSPECV_STACK_PROBE))
19506    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19507    (clobber (reg:CC FLAGS_REG))]
19508   "!TARGET_64BIT && TARGET_STACK_PROBE"
19509   "call\t___chkstk"
19510   [(set_attr "type" "multi")
19511    (set_attr "length" "5")])
19512
19513 (define_insn "allocate_stack_worker_64"
19514   [(set (match_operand:DI 0 "register_operand" "=a")
19515         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19516                             UNSPECV_STACK_PROBE))
19517    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19518    (clobber (reg:DI R10_REG))
19519    (clobber (reg:DI R11_REG))
19520    (clobber (reg:CC FLAGS_REG))]
19521   "TARGET_64BIT && TARGET_STACK_PROBE"
19522   "call\t___chkstk"
19523   [(set_attr "type" "multi")
19524    (set_attr "length" "5")])
19525
19526 (define_expand "allocate_stack"
19527   [(match_operand 0 "register_operand" "")
19528    (match_operand 1 "general_operand" "")]
19529   "TARGET_STACK_PROBE"
19530 {
19531   rtx x;
19532
19533 #ifndef CHECK_STACK_LIMIT
19534 #define CHECK_STACK_LIMIT 0
19535 #endif
19536
19537   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19538       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19539     {
19540       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19541                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19542       if (x != stack_pointer_rtx)
19543         emit_move_insn (stack_pointer_rtx, x);
19544     }
19545   else
19546     {
19547       x = copy_to_mode_reg (Pmode, operands[1]);
19548       if (TARGET_64BIT)
19549         x = gen_allocate_stack_worker_64 (x, x);
19550       else
19551         x = gen_allocate_stack_worker_32 (x, x);
19552       emit_insn (x);
19553     }
19554
19555   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19556   DONE;
19557 })
19558
19559 ;; Use IOR for stack probes, this is shorter.
19560 (define_expand "probe_stack"
19561   [(match_operand 0 "memory_operand" "")]
19562   ""
19563 {
19564   if (GET_MODE (operands[0]) == DImode)
19565     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19566   else
19567     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19568   DONE;
19569 })
19570
19571 (define_expand "builtin_setjmp_receiver"
19572   [(label_ref (match_operand 0 "" ""))]
19573   "!TARGET_64BIT && flag_pic"
19574 {
19575 #if TARGET_MACHO
19576   if (TARGET_MACHO)
19577     {
19578       rtx xops[3];
19579       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19580       rtx label_rtx = gen_label_rtx ();
19581       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19582       xops[0] = xops[1] = picreg;
19583       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19584       ix86_expand_binary_operator (MINUS, SImode, xops);
19585     }
19586   else
19587 #endif
19588     emit_insn (gen_set_got (pic_offset_table_rtx));
19589   DONE;
19590 })
19591 \f
19592 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19593
19594 (define_split
19595   [(set (match_operand 0 "register_operand" "")
19596         (match_operator 3 "promotable_binary_operator"
19597            [(match_operand 1 "register_operand" "")
19598             (match_operand 2 "aligned_operand" "")]))
19599    (clobber (reg:CC FLAGS_REG))]
19600   "! TARGET_PARTIAL_REG_STALL && reload_completed
19601    && ((GET_MODE (operands[0]) == HImode
19602         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19603             /* ??? next two lines just !satisfies_constraint_K (...) */
19604             || !CONST_INT_P (operands[2])
19605             || satisfies_constraint_K (operands[2])))
19606        || (GET_MODE (operands[0]) == QImode
19607            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19608   [(parallel [(set (match_dup 0)
19609                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19610               (clobber (reg:CC FLAGS_REG))])]
19611   "operands[0] = gen_lowpart (SImode, operands[0]);
19612    operands[1] = gen_lowpart (SImode, operands[1]);
19613    if (GET_CODE (operands[3]) != ASHIFT)
19614      operands[2] = gen_lowpart (SImode, operands[2]);
19615    PUT_MODE (operands[3], SImode);")
19616
19617 ; Promote the QImode tests, as i386 has encoding of the AND
19618 ; instruction with 32-bit sign-extended immediate and thus the
19619 ; instruction size is unchanged, except in the %eax case for
19620 ; which it is increased by one byte, hence the ! optimize_size.
19621 (define_split
19622   [(set (match_operand 0 "flags_reg_operand" "")
19623         (match_operator 2 "compare_operator"
19624           [(and (match_operand 3 "aligned_operand" "")
19625                 (match_operand 4 "const_int_operand" ""))
19626            (const_int 0)]))
19627    (set (match_operand 1 "register_operand" "")
19628         (and (match_dup 3) (match_dup 4)))]
19629   "! TARGET_PARTIAL_REG_STALL && reload_completed
19630    && optimize_insn_for_speed_p ()
19631    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19632        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19633    /* Ensure that the operand will remain sign-extended immediate.  */
19634    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19635   [(parallel [(set (match_dup 0)
19636                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19637                                     (const_int 0)]))
19638               (set (match_dup 1)
19639                    (and:SI (match_dup 3) (match_dup 4)))])]
19640 {
19641   operands[4]
19642     = gen_int_mode (INTVAL (operands[4])
19643                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19644   operands[1] = gen_lowpart (SImode, operands[1]);
19645   operands[3] = gen_lowpart (SImode, operands[3]);
19646 })
19647
19648 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19649 ; the TEST instruction with 32-bit sign-extended immediate and thus
19650 ; the instruction size would at least double, which is not what we
19651 ; want even with ! optimize_size.
19652 (define_split
19653   [(set (match_operand 0 "flags_reg_operand" "")
19654         (match_operator 1 "compare_operator"
19655           [(and (match_operand:HI 2 "aligned_operand" "")
19656                 (match_operand:HI 3 "const_int_operand" ""))
19657            (const_int 0)]))]
19658   "! TARGET_PARTIAL_REG_STALL && reload_completed
19659    && ! TARGET_FAST_PREFIX
19660    && optimize_insn_for_speed_p ()
19661    /* Ensure that the operand will remain sign-extended immediate.  */
19662    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19663   [(set (match_dup 0)
19664         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19665                          (const_int 0)]))]
19666 {
19667   operands[3]
19668     = gen_int_mode (INTVAL (operands[3])
19669                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19670   operands[2] = gen_lowpart (SImode, operands[2]);
19671 })
19672
19673 (define_split
19674   [(set (match_operand 0 "register_operand" "")
19675         (neg (match_operand 1 "register_operand" "")))
19676    (clobber (reg:CC FLAGS_REG))]
19677   "! TARGET_PARTIAL_REG_STALL && reload_completed
19678    && (GET_MODE (operands[0]) == HImode
19679        || (GET_MODE (operands[0]) == QImode
19680            && (TARGET_PROMOTE_QImode
19681                || optimize_insn_for_size_p ())))"
19682   [(parallel [(set (match_dup 0)
19683                    (neg:SI (match_dup 1)))
19684               (clobber (reg:CC FLAGS_REG))])]
19685   "operands[0] = gen_lowpart (SImode, operands[0]);
19686    operands[1] = gen_lowpart (SImode, operands[1]);")
19687
19688 (define_split
19689   [(set (match_operand 0 "register_operand" "")
19690         (not (match_operand 1 "register_operand" "")))]
19691   "! TARGET_PARTIAL_REG_STALL && reload_completed
19692    && (GET_MODE (operands[0]) == HImode
19693        || (GET_MODE (operands[0]) == QImode
19694            && (TARGET_PROMOTE_QImode
19695                || optimize_insn_for_size_p ())))"
19696   [(set (match_dup 0)
19697         (not:SI (match_dup 1)))]
19698   "operands[0] = gen_lowpart (SImode, operands[0]);
19699    operands[1] = gen_lowpart (SImode, operands[1]);")
19700
19701 (define_split
19702   [(set (match_operand 0 "register_operand" "")
19703         (if_then_else (match_operator 1 "comparison_operator"
19704                                 [(reg FLAGS_REG) (const_int 0)])
19705                       (match_operand 2 "register_operand" "")
19706                       (match_operand 3 "register_operand" "")))]
19707   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19708    && (GET_MODE (operands[0]) == HImode
19709        || (GET_MODE (operands[0]) == QImode
19710            && (TARGET_PROMOTE_QImode
19711                || optimize_insn_for_size_p ())))"
19712   [(set (match_dup 0)
19713         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19714   "operands[0] = gen_lowpart (SImode, operands[0]);
19715    operands[2] = gen_lowpart (SImode, operands[2]);
19716    operands[3] = gen_lowpart (SImode, operands[3]);")
19717
19718 \f
19719 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19720 ;; transform a complex memory operation into two memory to register operations.
19721
19722 ;; Don't push memory operands
19723 (define_peephole2
19724   [(set (match_operand:SI 0 "push_operand" "")
19725         (match_operand:SI 1 "memory_operand" ""))
19726    (match_scratch:SI 2 "r")]
19727   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19728    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19729   [(set (match_dup 2) (match_dup 1))
19730    (set (match_dup 0) (match_dup 2))]
19731   "")
19732
19733 (define_peephole2
19734   [(set (match_operand:DI 0 "push_operand" "")
19735         (match_operand:DI 1 "memory_operand" ""))
19736    (match_scratch:DI 2 "r")]
19737   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19738    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19739   [(set (match_dup 2) (match_dup 1))
19740    (set (match_dup 0) (match_dup 2))]
19741   "")
19742
19743 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19744 ;; SImode pushes.
19745 (define_peephole2
19746   [(set (match_operand:SF 0 "push_operand" "")
19747         (match_operand:SF 1 "memory_operand" ""))
19748    (match_scratch:SF 2 "r")]
19749   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19750    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19751   [(set (match_dup 2) (match_dup 1))
19752    (set (match_dup 0) (match_dup 2))]
19753   "")
19754
19755 (define_peephole2
19756   [(set (match_operand:HI 0 "push_operand" "")
19757         (match_operand:HI 1 "memory_operand" ""))
19758    (match_scratch:HI 2 "r")]
19759   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19760    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19761   [(set (match_dup 2) (match_dup 1))
19762    (set (match_dup 0) (match_dup 2))]
19763   "")
19764
19765 (define_peephole2
19766   [(set (match_operand:QI 0 "push_operand" "")
19767         (match_operand:QI 1 "memory_operand" ""))
19768    (match_scratch:QI 2 "q")]
19769   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19770    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19771   [(set (match_dup 2) (match_dup 1))
19772    (set (match_dup 0) (match_dup 2))]
19773   "")
19774
19775 ;; Don't move an immediate directly to memory when the instruction
19776 ;; gets too big.
19777 (define_peephole2
19778   [(match_scratch:SI 1 "r")
19779    (set (match_operand:SI 0 "memory_operand" "")
19780         (const_int 0))]
19781   "optimize_insn_for_speed_p ()
19782    && ! TARGET_USE_MOV0
19783    && TARGET_SPLIT_LONG_MOVES
19784    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19785    && peep2_regno_dead_p (0, FLAGS_REG)"
19786   [(parallel [(set (match_dup 1) (const_int 0))
19787               (clobber (reg:CC FLAGS_REG))])
19788    (set (match_dup 0) (match_dup 1))]
19789   "")
19790
19791 (define_peephole2
19792   [(match_scratch:HI 1 "r")
19793    (set (match_operand:HI 0 "memory_operand" "")
19794         (const_int 0))]
19795   "optimize_insn_for_speed_p ()
19796    && ! TARGET_USE_MOV0
19797    && TARGET_SPLIT_LONG_MOVES
19798    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19799    && peep2_regno_dead_p (0, FLAGS_REG)"
19800   [(parallel [(set (match_dup 2) (const_int 0))
19801               (clobber (reg:CC FLAGS_REG))])
19802    (set (match_dup 0) (match_dup 1))]
19803   "operands[2] = gen_lowpart (SImode, operands[1]);")
19804
19805 (define_peephole2
19806   [(match_scratch:QI 1 "q")
19807    (set (match_operand:QI 0 "memory_operand" "")
19808         (const_int 0))]
19809   "optimize_insn_for_speed_p ()
19810    && ! TARGET_USE_MOV0
19811    && TARGET_SPLIT_LONG_MOVES
19812    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19813    && peep2_regno_dead_p (0, FLAGS_REG)"
19814   [(parallel [(set (match_dup 2) (const_int 0))
19815               (clobber (reg:CC FLAGS_REG))])
19816    (set (match_dup 0) (match_dup 1))]
19817   "operands[2] = gen_lowpart (SImode, operands[1]);")
19818
19819 (define_peephole2
19820   [(match_scratch:SI 2 "r")
19821    (set (match_operand:SI 0 "memory_operand" "")
19822         (match_operand:SI 1 "immediate_operand" ""))]
19823   "optimize_insn_for_speed_p ()
19824    && TARGET_SPLIT_LONG_MOVES
19825    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19826   [(set (match_dup 2) (match_dup 1))
19827    (set (match_dup 0) (match_dup 2))]
19828   "")
19829
19830 (define_peephole2
19831   [(match_scratch:HI 2 "r")
19832    (set (match_operand:HI 0 "memory_operand" "")
19833         (match_operand:HI 1 "immediate_operand" ""))]
19834   "optimize_insn_for_speed_p ()
19835    && TARGET_SPLIT_LONG_MOVES
19836    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19837   [(set (match_dup 2) (match_dup 1))
19838    (set (match_dup 0) (match_dup 2))]
19839   "")
19840
19841 (define_peephole2
19842   [(match_scratch:QI 2 "q")
19843    (set (match_operand:QI 0 "memory_operand" "")
19844         (match_operand:QI 1 "immediate_operand" ""))]
19845   "optimize_insn_for_speed_p ()
19846    && TARGET_SPLIT_LONG_MOVES
19847    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19848   [(set (match_dup 2) (match_dup 1))
19849    (set (match_dup 0) (match_dup 2))]
19850   "")
19851
19852 ;; Don't compare memory with zero, load and use a test instead.
19853 (define_peephole2
19854   [(set (match_operand 0 "flags_reg_operand" "")
19855         (match_operator 1 "compare_operator"
19856           [(match_operand:SI 2 "memory_operand" "")
19857            (const_int 0)]))
19858    (match_scratch:SI 3 "r")]
19859   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19860   [(set (match_dup 3) (match_dup 2))
19861    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19862   "")
19863
19864 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19865 ;; Don't split NOTs with a displacement operand, because resulting XOR
19866 ;; will not be pairable anyway.
19867 ;;
19868 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19869 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19870 ;; so this split helps here as well.
19871 ;;
19872 ;; Note: Can't do this as a regular split because we can't get proper
19873 ;; lifetime information then.
19874
19875 (define_peephole2
19876   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19877         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19878   "optimize_insn_for_speed_p ()
19879    && ((TARGET_NOT_UNPAIRABLE
19880         && (!MEM_P (operands[0])
19881             || !memory_displacement_operand (operands[0], SImode)))
19882        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19883    && peep2_regno_dead_p (0, FLAGS_REG)"
19884   [(parallel [(set (match_dup 0)
19885                    (xor:SI (match_dup 1) (const_int -1)))
19886               (clobber (reg:CC FLAGS_REG))])]
19887   "")
19888
19889 (define_peephole2
19890   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19891         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19892   "optimize_insn_for_speed_p ()
19893    && ((TARGET_NOT_UNPAIRABLE
19894         && (!MEM_P (operands[0])
19895             || !memory_displacement_operand (operands[0], HImode)))
19896        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19897    && peep2_regno_dead_p (0, FLAGS_REG)"
19898   [(parallel [(set (match_dup 0)
19899                    (xor:HI (match_dup 1) (const_int -1)))
19900               (clobber (reg:CC FLAGS_REG))])]
19901   "")
19902
19903 (define_peephole2
19904   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19905         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19906   "optimize_insn_for_speed_p ()
19907    && ((TARGET_NOT_UNPAIRABLE
19908         && (!MEM_P (operands[0])
19909             || !memory_displacement_operand (operands[0], QImode)))
19910        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19911    && peep2_regno_dead_p (0, FLAGS_REG)"
19912   [(parallel [(set (match_dup 0)
19913                    (xor:QI (match_dup 1) (const_int -1)))
19914               (clobber (reg:CC FLAGS_REG))])]
19915   "")
19916
19917 ;; Non pairable "test imm, reg" instructions can be translated to
19918 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19919 ;; byte opcode instead of two, have a short form for byte operands),
19920 ;; so do it for other CPUs as well.  Given that the value was dead,
19921 ;; this should not create any new dependencies.  Pass on the sub-word
19922 ;; versions if we're concerned about partial register stalls.
19923
19924 (define_peephole2
19925   [(set (match_operand 0 "flags_reg_operand" "")
19926         (match_operator 1 "compare_operator"
19927           [(and:SI (match_operand:SI 2 "register_operand" "")
19928                    (match_operand:SI 3 "immediate_operand" ""))
19929            (const_int 0)]))]
19930   "ix86_match_ccmode (insn, CCNOmode)
19931    && (true_regnum (operands[2]) != AX_REG
19932        || satisfies_constraint_K (operands[3]))
19933    && peep2_reg_dead_p (1, operands[2])"
19934   [(parallel
19935      [(set (match_dup 0)
19936            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19937                             (const_int 0)]))
19938       (set (match_dup 2)
19939            (and:SI (match_dup 2) (match_dup 3)))])]
19940   "")
19941
19942 ;; We don't need to handle HImode case, because it will be promoted to SImode
19943 ;; on ! TARGET_PARTIAL_REG_STALL
19944
19945 (define_peephole2
19946   [(set (match_operand 0 "flags_reg_operand" "")
19947         (match_operator 1 "compare_operator"
19948           [(and:QI (match_operand:QI 2 "register_operand" "")
19949                    (match_operand:QI 3 "immediate_operand" ""))
19950            (const_int 0)]))]
19951   "! TARGET_PARTIAL_REG_STALL
19952    && ix86_match_ccmode (insn, CCNOmode)
19953    && true_regnum (operands[2]) != AX_REG
19954    && peep2_reg_dead_p (1, operands[2])"
19955   [(parallel
19956      [(set (match_dup 0)
19957            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19958                             (const_int 0)]))
19959       (set (match_dup 2)
19960            (and:QI (match_dup 2) (match_dup 3)))])]
19961   "")
19962
19963 (define_peephole2
19964   [(set (match_operand 0 "flags_reg_operand" "")
19965         (match_operator 1 "compare_operator"
19966           [(and:SI
19967              (zero_extract:SI
19968                (match_operand 2 "ext_register_operand" "")
19969                (const_int 8)
19970                (const_int 8))
19971              (match_operand 3 "const_int_operand" ""))
19972            (const_int 0)]))]
19973   "! TARGET_PARTIAL_REG_STALL
19974    && ix86_match_ccmode (insn, CCNOmode)
19975    && true_regnum (operands[2]) != AX_REG
19976    && peep2_reg_dead_p (1, operands[2])"
19977   [(parallel [(set (match_dup 0)
19978                    (match_op_dup 1
19979                      [(and:SI
19980                         (zero_extract:SI
19981                           (match_dup 2)
19982                           (const_int 8)
19983                           (const_int 8))
19984                         (match_dup 3))
19985                       (const_int 0)]))
19986               (set (zero_extract:SI (match_dup 2)
19987                                     (const_int 8)
19988                                     (const_int 8))
19989                    (and:SI
19990                      (zero_extract:SI
19991                        (match_dup 2)
19992                        (const_int 8)
19993                        (const_int 8))
19994                      (match_dup 3)))])]
19995   "")
19996
19997 ;; Don't do logical operations with memory inputs.
19998 (define_peephole2
19999   [(match_scratch:SI 2 "r")
20000    (parallel [(set (match_operand:SI 0 "register_operand" "")
20001                    (match_operator:SI 3 "arith_or_logical_operator"
20002                      [(match_dup 0)
20003                       (match_operand:SI 1 "memory_operand" "")]))
20004               (clobber (reg:CC FLAGS_REG))])]
20005   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20006   [(set (match_dup 2) (match_dup 1))
20007    (parallel [(set (match_dup 0)
20008                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20009               (clobber (reg:CC FLAGS_REG))])]
20010   "")
20011
20012 (define_peephole2
20013   [(match_scratch:SI 2 "r")
20014    (parallel [(set (match_operand:SI 0 "register_operand" "")
20015                    (match_operator:SI 3 "arith_or_logical_operator"
20016                      [(match_operand:SI 1 "memory_operand" "")
20017                       (match_dup 0)]))
20018               (clobber (reg:CC FLAGS_REG))])]
20019   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20020   [(set (match_dup 2) (match_dup 1))
20021    (parallel [(set (match_dup 0)
20022                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20023               (clobber (reg:CC FLAGS_REG))])]
20024   "")
20025
20026 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20027 ;; refers to the destination of the load!
20028
20029 (define_peephole2
20030   [(set (match_operand:SI 0 "register_operand" "")
20031         (match_operand:SI 1 "register_operand" ""))
20032    (parallel [(set (match_dup 0)
20033                    (match_operator:SI 3 "commutative_operator"
20034                      [(match_dup 0)
20035                       (match_operand:SI 2 "memory_operand" "")]))
20036               (clobber (reg:CC FLAGS_REG))])]
20037   "REGNO (operands[0]) != REGNO (operands[1])
20038    && GENERAL_REGNO_P (REGNO (operands[0]))
20039    && GENERAL_REGNO_P (REGNO (operands[1]))"
20040   [(set (match_dup 0) (match_dup 4))
20041    (parallel [(set (match_dup 0)
20042                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20043               (clobber (reg:CC FLAGS_REG))])]
20044   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20045
20046 (define_peephole2
20047   [(set (match_operand 0 "register_operand" "")
20048         (match_operand 1 "register_operand" ""))
20049    (set (match_dup 0)
20050                    (match_operator 3 "commutative_operator"
20051                      [(match_dup 0)
20052                       (match_operand 2 "memory_operand" "")]))]
20053   "REGNO (operands[0]) != REGNO (operands[1])
20054    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20055        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20056   [(set (match_dup 0) (match_dup 2))
20057    (set (match_dup 0)
20058         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20059   "")
20060
20061 ; Don't do logical operations with memory outputs
20062 ;
20063 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20064 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20065 ; the same decoder scheduling characteristics as the original.
20066
20067 (define_peephole2
20068   [(match_scratch:SI 2 "r")
20069    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20070                    (match_operator:SI 3 "arith_or_logical_operator"
20071                      [(match_dup 0)
20072                       (match_operand:SI 1 "nonmemory_operand" "")]))
20073               (clobber (reg:CC FLAGS_REG))])]
20074   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20075    /* Do not split stack checking probes.  */
20076    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20077   [(set (match_dup 2) (match_dup 0))
20078    (parallel [(set (match_dup 2)
20079                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20080               (clobber (reg:CC FLAGS_REG))])
20081    (set (match_dup 0) (match_dup 2))]
20082   "")
20083
20084 (define_peephole2
20085   [(match_scratch:SI 2 "r")
20086    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20087                    (match_operator:SI 3 "arith_or_logical_operator"
20088                      [(match_operand:SI 1 "nonmemory_operand" "")
20089                       (match_dup 0)]))
20090               (clobber (reg:CC FLAGS_REG))])]
20091   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20092    /* Do not split stack checking probes.  */
20093    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20094   [(set (match_dup 2) (match_dup 0))
20095    (parallel [(set (match_dup 2)
20096                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20097               (clobber (reg:CC FLAGS_REG))])
20098    (set (match_dup 0) (match_dup 2))]
20099   "")
20100
20101 ;; Attempt to always use XOR for zeroing registers.
20102 (define_peephole2
20103   [(set (match_operand 0 "register_operand" "")
20104         (match_operand 1 "const0_operand" ""))]
20105   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20106    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20107    && GENERAL_REG_P (operands[0])
20108    && peep2_regno_dead_p (0, FLAGS_REG)"
20109   [(parallel [(set (match_dup 0) (const_int 0))
20110               (clobber (reg:CC FLAGS_REG))])]
20111 {
20112   operands[0] = gen_lowpart (word_mode, operands[0]);
20113 })
20114
20115 (define_peephole2
20116   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20117         (const_int 0))]
20118   "(GET_MODE (operands[0]) == QImode
20119     || GET_MODE (operands[0]) == HImode)
20120    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20121    && peep2_regno_dead_p (0, FLAGS_REG)"
20122   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20123               (clobber (reg:CC FLAGS_REG))])])
20124
20125 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20126 (define_peephole2
20127   [(set (match_operand 0 "register_operand" "")
20128         (const_int -1))]
20129   "(GET_MODE (operands[0]) == HImode
20130     || GET_MODE (operands[0]) == SImode
20131     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20132    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20133    && peep2_regno_dead_p (0, FLAGS_REG)"
20134   [(parallel [(set (match_dup 0) (const_int -1))
20135               (clobber (reg:CC FLAGS_REG))])]
20136   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20137                               operands[0]);")
20138
20139 ;; Attempt to convert simple leas to adds. These can be created by
20140 ;; move expanders.
20141 (define_peephole2
20142   [(set (match_operand:SI 0 "register_operand" "")
20143         (plus:SI (match_dup 0)
20144                  (match_operand:SI 1 "nonmemory_operand" "")))]
20145   "peep2_regno_dead_p (0, FLAGS_REG)"
20146   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20147               (clobber (reg:CC FLAGS_REG))])]
20148   "")
20149
20150 (define_peephole2
20151   [(set (match_operand:SI 0 "register_operand" "")
20152         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20153                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20154   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20155   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20156               (clobber (reg:CC FLAGS_REG))])]
20157   "operands[2] = gen_lowpart (SImode, operands[2]);")
20158
20159 (define_peephole2
20160   [(set (match_operand:DI 0 "register_operand" "")
20161         (plus:DI (match_dup 0)
20162                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20163   "peep2_regno_dead_p (0, FLAGS_REG)"
20164   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20165               (clobber (reg:CC FLAGS_REG))])]
20166   "")
20167
20168 (define_peephole2
20169   [(set (match_operand:SI 0 "register_operand" "")
20170         (mult:SI (match_dup 0)
20171                  (match_operand:SI 1 "const_int_operand" "")))]
20172   "exact_log2 (INTVAL (operands[1])) >= 0
20173    && peep2_regno_dead_p (0, FLAGS_REG)"
20174   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20175               (clobber (reg:CC FLAGS_REG))])]
20176   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20177
20178 (define_peephole2
20179   [(set (match_operand:DI 0 "register_operand" "")
20180         (mult:DI (match_dup 0)
20181                  (match_operand:DI 1 "const_int_operand" "")))]
20182   "exact_log2 (INTVAL (operands[1])) >= 0
20183    && peep2_regno_dead_p (0, FLAGS_REG)"
20184   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20185               (clobber (reg:CC FLAGS_REG))])]
20186   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20187
20188 (define_peephole2
20189   [(set (match_operand:SI 0 "register_operand" "")
20190         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20191                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20192   "exact_log2 (INTVAL (operands[2])) >= 0
20193    && REGNO (operands[0]) == REGNO (operands[1])
20194    && peep2_regno_dead_p (0, FLAGS_REG)"
20195   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20196               (clobber (reg:CC FLAGS_REG))])]
20197   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20198
20199 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20200 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20201 ;; many CPUs it is also faster, since special hardware to avoid esp
20202 ;; dependencies is present.
20203
20204 ;; While some of these conversions may be done using splitters, we use peepholes
20205 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20206
20207 ;; Convert prologue esp subtractions to push.
20208 ;; We need register to push.  In order to keep verify_flow_info happy we have
20209 ;; two choices
20210 ;; - use scratch and clobber it in order to avoid dependencies
20211 ;; - use already live register
20212 ;; We can't use the second way right now, since there is no reliable way how to
20213 ;; verify that given register is live.  First choice will also most likely in
20214 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20215 ;; call clobbered registers are dead.  We may want to use base pointer as an
20216 ;; alternative when no register is available later.
20217
20218 (define_peephole2
20219   [(match_scratch:SI 0 "r")
20220    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20221               (clobber (reg:CC FLAGS_REG))
20222               (clobber (mem:BLK (scratch)))])]
20223   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20224   [(clobber (match_dup 0))
20225    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20226               (clobber (mem:BLK (scratch)))])])
20227
20228 (define_peephole2
20229   [(match_scratch:SI 0 "r")
20230    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20231               (clobber (reg:CC FLAGS_REG))
20232               (clobber (mem:BLK (scratch)))])]
20233   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20234   [(clobber (match_dup 0))
20235    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20236    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20237               (clobber (mem:BLK (scratch)))])])
20238
20239 ;; Convert esp subtractions to push.
20240 (define_peephole2
20241   [(match_scratch:SI 0 "r")
20242    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20243               (clobber (reg:CC FLAGS_REG))])]
20244   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20245   [(clobber (match_dup 0))
20246    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20247
20248 (define_peephole2
20249   [(match_scratch:SI 0 "r")
20250    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20251               (clobber (reg:CC FLAGS_REG))])]
20252   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20253   [(clobber (match_dup 0))
20254    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20255    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20256
20257 ;; Convert epilogue deallocator to pop.
20258 (define_peephole2
20259   [(match_scratch:SI 0 "r")
20260    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20261               (clobber (reg:CC FLAGS_REG))
20262               (clobber (mem:BLK (scratch)))])]
20263   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20264   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20265               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20266               (clobber (mem:BLK (scratch)))])]
20267   "")
20268
20269 ;; Two pops case is tricky, since pop causes dependency on destination register.
20270 ;; We use two registers if available.
20271 (define_peephole2
20272   [(match_scratch:SI 0 "r")
20273    (match_scratch:SI 1 "r")
20274    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20275               (clobber (reg:CC FLAGS_REG))
20276               (clobber (mem:BLK (scratch)))])]
20277   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20278   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20279               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20280               (clobber (mem:BLK (scratch)))])
20281    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20282               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20283   "")
20284
20285 (define_peephole2
20286   [(match_scratch:SI 0 "r")
20287    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20288               (clobber (reg:CC FLAGS_REG))
20289               (clobber (mem:BLK (scratch)))])]
20290   "optimize_insn_for_size_p ()"
20291   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20292               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20293               (clobber (mem:BLK (scratch)))])
20294    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20295               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20296   "")
20297
20298 ;; Convert esp additions to pop.
20299 (define_peephole2
20300   [(match_scratch:SI 0 "r")
20301    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20302               (clobber (reg:CC FLAGS_REG))])]
20303   ""
20304   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20305               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20306   "")
20307
20308 ;; Two pops case is tricky, since pop causes dependency on destination register.
20309 ;; We use two registers if available.
20310 (define_peephole2
20311   [(match_scratch:SI 0 "r")
20312    (match_scratch:SI 1 "r")
20313    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20314               (clobber (reg:CC FLAGS_REG))])]
20315   ""
20316   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20317               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20318    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20319               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20320   "")
20321
20322 (define_peephole2
20323   [(match_scratch:SI 0 "r")
20324    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20325               (clobber (reg:CC FLAGS_REG))])]
20326   "optimize_insn_for_size_p ()"
20327   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20328               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20329    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20330               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20331   "")
20332 \f
20333 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20334 ;; required and register dies.  Similarly for 128 to -128.
20335 (define_peephole2
20336   [(set (match_operand 0 "flags_reg_operand" "")
20337         (match_operator 1 "compare_operator"
20338           [(match_operand 2 "register_operand" "")
20339            (match_operand 3 "const_int_operand" "")]))]
20340   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20341      && incdec_operand (operands[3], GET_MODE (operands[3])))
20342     || (!TARGET_FUSE_CMP_AND_BRANCH
20343         && INTVAL (operands[3]) == 128))
20344    && ix86_match_ccmode (insn, CCGCmode)
20345    && peep2_reg_dead_p (1, operands[2])"
20346   [(parallel [(set (match_dup 0)
20347                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20348               (clobber (match_dup 2))])]
20349   "")
20350 \f
20351 (define_peephole2
20352   [(match_scratch:DI 0 "r")
20353    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20354               (clobber (reg:CC FLAGS_REG))
20355               (clobber (mem:BLK (scratch)))])]
20356   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20357   [(clobber (match_dup 0))
20358    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20359               (clobber (mem:BLK (scratch)))])])
20360
20361 (define_peephole2
20362   [(match_scratch:DI 0 "r")
20363    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20364               (clobber (reg:CC FLAGS_REG))
20365               (clobber (mem:BLK (scratch)))])]
20366   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20367   [(clobber (match_dup 0))
20368    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20369    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20370               (clobber (mem:BLK (scratch)))])])
20371
20372 ;; Convert esp subtractions to push.
20373 (define_peephole2
20374   [(match_scratch:DI 0 "r")
20375    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20376               (clobber (reg:CC FLAGS_REG))])]
20377   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20378   [(clobber (match_dup 0))
20379    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20380
20381 (define_peephole2
20382   [(match_scratch:DI 0 "r")
20383    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20384               (clobber (reg:CC FLAGS_REG))])]
20385   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20386   [(clobber (match_dup 0))
20387    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20388    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20389
20390 ;; Convert epilogue deallocator to pop.
20391 (define_peephole2
20392   [(match_scratch:DI 0 "r")
20393    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20394               (clobber (reg:CC FLAGS_REG))
20395               (clobber (mem:BLK (scratch)))])]
20396   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20397   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20398               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20399               (clobber (mem:BLK (scratch)))])]
20400   "")
20401
20402 ;; Two pops case is tricky, since pop causes dependency on destination register.
20403 ;; We use two registers if available.
20404 (define_peephole2
20405   [(match_scratch:DI 0 "r")
20406    (match_scratch:DI 1 "r")
20407    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20408               (clobber (reg:CC FLAGS_REG))
20409               (clobber (mem:BLK (scratch)))])]
20410   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20411   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20412               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20413               (clobber (mem:BLK (scratch)))])
20414    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20415               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20416   "")
20417
20418 (define_peephole2
20419   [(match_scratch:DI 0 "r")
20420    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20421               (clobber (reg:CC FLAGS_REG))
20422               (clobber (mem:BLK (scratch)))])]
20423   "optimize_insn_for_size_p ()"
20424   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20425               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20426               (clobber (mem:BLK (scratch)))])
20427    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20428               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20429   "")
20430
20431 ;; Convert esp additions to pop.
20432 (define_peephole2
20433   [(match_scratch:DI 0 "r")
20434    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20435               (clobber (reg:CC FLAGS_REG))])]
20436   ""
20437   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20438               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20439   "")
20440
20441 ;; Two pops case is tricky, since pop causes dependency on destination register.
20442 ;; We use two registers if available.
20443 (define_peephole2
20444   [(match_scratch:DI 0 "r")
20445    (match_scratch:DI 1 "r")
20446    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20447               (clobber (reg:CC FLAGS_REG))])]
20448   ""
20449   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20450               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20451    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20452               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20453   "")
20454
20455 (define_peephole2
20456   [(match_scratch:DI 0 "r")
20457    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20458               (clobber (reg:CC FLAGS_REG))])]
20459   "optimize_insn_for_size_p ()"
20460   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20461               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20462    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20463               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20464   "")
20465 \f
20466 ;; Convert imul by three, five and nine into lea
20467 (define_peephole2
20468   [(parallel
20469     [(set (match_operand:SI 0 "register_operand" "")
20470           (mult:SI (match_operand:SI 1 "register_operand" "")
20471                    (match_operand:SI 2 "const_int_operand" "")))
20472      (clobber (reg:CC FLAGS_REG))])]
20473   "INTVAL (operands[2]) == 3
20474    || INTVAL (operands[2]) == 5
20475    || INTVAL (operands[2]) == 9"
20476   [(set (match_dup 0)
20477         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20478                  (match_dup 1)))]
20479   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20480
20481 (define_peephole2
20482   [(parallel
20483     [(set (match_operand:SI 0 "register_operand" "")
20484           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20485                    (match_operand:SI 2 "const_int_operand" "")))
20486      (clobber (reg:CC FLAGS_REG))])]
20487   "optimize_insn_for_speed_p ()
20488    && (INTVAL (operands[2]) == 3
20489        || INTVAL (operands[2]) == 5
20490        || INTVAL (operands[2]) == 9)"
20491   [(set (match_dup 0) (match_dup 1))
20492    (set (match_dup 0)
20493         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20494                  (match_dup 0)))]
20495   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20496
20497 (define_peephole2
20498   [(parallel
20499     [(set (match_operand:DI 0 "register_operand" "")
20500           (mult:DI (match_operand:DI 1 "register_operand" "")
20501                    (match_operand:DI 2 "const_int_operand" "")))
20502      (clobber (reg:CC FLAGS_REG))])]
20503   "TARGET_64BIT
20504    && (INTVAL (operands[2]) == 3
20505        || INTVAL (operands[2]) == 5
20506        || INTVAL (operands[2]) == 9)"
20507   [(set (match_dup 0)
20508         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20509                  (match_dup 1)))]
20510   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20511
20512 (define_peephole2
20513   [(parallel
20514     [(set (match_operand:DI 0 "register_operand" "")
20515           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20516                    (match_operand:DI 2 "const_int_operand" "")))
20517      (clobber (reg:CC FLAGS_REG))])]
20518   "TARGET_64BIT
20519    && optimize_insn_for_speed_p ()
20520    && (INTVAL (operands[2]) == 3
20521        || INTVAL (operands[2]) == 5
20522        || INTVAL (operands[2]) == 9)"
20523   [(set (match_dup 0) (match_dup 1))
20524    (set (match_dup 0)
20525         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20526                  (match_dup 0)))]
20527   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20528
20529 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20530 ;; imul $32bit_imm, reg, reg is direct decoded.
20531 (define_peephole2
20532   [(match_scratch:DI 3 "r")
20533    (parallel [(set (match_operand:DI 0 "register_operand" "")
20534                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20535                             (match_operand:DI 2 "immediate_operand" "")))
20536               (clobber (reg:CC FLAGS_REG))])]
20537   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20538    && !satisfies_constraint_K (operands[2])"
20539   [(set (match_dup 3) (match_dup 1))
20540    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20541               (clobber (reg:CC FLAGS_REG))])]
20542 "")
20543
20544 (define_peephole2
20545   [(match_scratch:SI 3 "r")
20546    (parallel [(set (match_operand:SI 0 "register_operand" "")
20547                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20548                             (match_operand:SI 2 "immediate_operand" "")))
20549               (clobber (reg:CC FLAGS_REG))])]
20550   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20551    && !satisfies_constraint_K (operands[2])"
20552   [(set (match_dup 3) (match_dup 1))
20553    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20554               (clobber (reg:CC FLAGS_REG))])]
20555 "")
20556
20557 (define_peephole2
20558   [(match_scratch:SI 3 "r")
20559    (parallel [(set (match_operand:DI 0 "register_operand" "")
20560                    (zero_extend:DI
20561                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20562                               (match_operand:SI 2 "immediate_operand" ""))))
20563               (clobber (reg:CC FLAGS_REG))])]
20564   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20565    && !satisfies_constraint_K (operands[2])"
20566   [(set (match_dup 3) (match_dup 1))
20567    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20568               (clobber (reg:CC FLAGS_REG))])]
20569 "")
20570
20571 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20572 ;; Convert it into imul reg, reg
20573 ;; It would be better to force assembler to encode instruction using long
20574 ;; immediate, but there is apparently no way to do so.
20575 (define_peephole2
20576   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20577                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20578                             (match_operand:DI 2 "const_int_operand" "")))
20579               (clobber (reg:CC FLAGS_REG))])
20580    (match_scratch:DI 3 "r")]
20581   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20582    && satisfies_constraint_K (operands[2])"
20583   [(set (match_dup 3) (match_dup 2))
20584    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20585               (clobber (reg:CC FLAGS_REG))])]
20586 {
20587   if (!rtx_equal_p (operands[0], operands[1]))
20588     emit_move_insn (operands[0], operands[1]);
20589 })
20590
20591 (define_peephole2
20592   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20593                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20594                             (match_operand:SI 2 "const_int_operand" "")))
20595               (clobber (reg:CC FLAGS_REG))])
20596    (match_scratch:SI 3 "r")]
20597   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20598    && satisfies_constraint_K (operands[2])"
20599   [(set (match_dup 3) (match_dup 2))
20600    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20601               (clobber (reg:CC FLAGS_REG))])]
20602 {
20603   if (!rtx_equal_p (operands[0], operands[1]))
20604     emit_move_insn (operands[0], operands[1]);
20605 })
20606
20607 (define_peephole2
20608   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20609                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20610                             (match_operand:HI 2 "immediate_operand" "")))
20611               (clobber (reg:CC FLAGS_REG))])
20612    (match_scratch:HI 3 "r")]
20613   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20614   [(set (match_dup 3) (match_dup 2))
20615    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20616               (clobber (reg:CC FLAGS_REG))])]
20617 {
20618   if (!rtx_equal_p (operands[0], operands[1]))
20619     emit_move_insn (operands[0], operands[1]);
20620 })
20621
20622 ;; After splitting up read-modify operations, array accesses with memory
20623 ;; operands might end up in form:
20624 ;;  sall    $2, %eax
20625 ;;  movl    4(%esp), %edx
20626 ;;  addl    %edx, %eax
20627 ;; instead of pre-splitting:
20628 ;;  sall    $2, %eax
20629 ;;  addl    4(%esp), %eax
20630 ;; Turn it into:
20631 ;;  movl    4(%esp), %edx
20632 ;;  leal    (%edx,%eax,4), %eax
20633
20634 (define_peephole2
20635   [(parallel [(set (match_operand 0 "register_operand" "")
20636                    (ashift (match_operand 1 "register_operand" "")
20637                            (match_operand 2 "const_int_operand" "")))
20638                (clobber (reg:CC FLAGS_REG))])
20639    (set (match_operand 3 "register_operand")
20640         (match_operand 4 "x86_64_general_operand" ""))
20641    (parallel [(set (match_operand 5 "register_operand" "")
20642                    (plus (match_operand 6 "register_operand" "")
20643                          (match_operand 7 "register_operand" "")))
20644                    (clobber (reg:CC FLAGS_REG))])]
20645   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20646    /* Validate MODE for lea.  */
20647    && ((!TARGET_PARTIAL_REG_STALL
20648         && (GET_MODE (operands[0]) == QImode
20649             || GET_MODE (operands[0]) == HImode))
20650        || GET_MODE (operands[0]) == SImode
20651        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20652    /* We reorder load and the shift.  */
20653    && !rtx_equal_p (operands[1], operands[3])
20654    && !reg_overlap_mentioned_p (operands[0], operands[4])
20655    /* Last PLUS must consist of operand 0 and 3.  */
20656    && !rtx_equal_p (operands[0], operands[3])
20657    && (rtx_equal_p (operands[3], operands[6])
20658        || rtx_equal_p (operands[3], operands[7]))
20659    && (rtx_equal_p (operands[0], operands[6])
20660        || rtx_equal_p (operands[0], operands[7]))
20661    /* The intermediate operand 0 must die or be same as output.  */
20662    && (rtx_equal_p (operands[0], operands[5])
20663        || peep2_reg_dead_p (3, operands[0]))"
20664   [(set (match_dup 3) (match_dup 4))
20665    (set (match_dup 0) (match_dup 1))]
20666 {
20667   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20668   int scale = 1 << INTVAL (operands[2]);
20669   rtx index = gen_lowpart (Pmode, operands[1]);
20670   rtx base = gen_lowpart (Pmode, operands[3]);
20671   rtx dest = gen_lowpart (mode, operands[5]);
20672
20673   operands[1] = gen_rtx_PLUS (Pmode, base,
20674                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20675   if (mode != Pmode)
20676     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20677   operands[0] = dest;
20678 })
20679 \f
20680 ;; Call-value patterns last so that the wildcard operand does not
20681 ;; disrupt insn-recog's switch tables.
20682
20683 (define_insn "*call_value_pop_0"
20684   [(set (match_operand 0 "" "")
20685         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20686               (match_operand:SI 2 "" "")))
20687    (set (reg:SI SP_REG)
20688         (plus:SI (reg:SI SP_REG)
20689                  (match_operand:SI 3 "immediate_operand" "")))]
20690   "!TARGET_64BIT"
20691 {
20692   if (SIBLING_CALL_P (insn))
20693     return "jmp\t%P1";
20694   else
20695     return "call\t%P1";
20696 }
20697   [(set_attr "type" "callv")])
20698
20699 (define_insn "*call_value_pop_1"
20700   [(set (match_operand 0 "" "")
20701         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20702               (match_operand:SI 2 "" "")))
20703    (set (reg:SI SP_REG)
20704         (plus:SI (reg:SI SP_REG)
20705                  (match_operand:SI 3 "immediate_operand" "i")))]
20706   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20707 {
20708   if (constant_call_address_operand (operands[1], Pmode))
20709     return "call\t%P1";
20710   return "call\t%A1";
20711 }
20712   [(set_attr "type" "callv")])
20713
20714 (define_insn "*sibcall_value_pop_1"
20715   [(set (match_operand 0 "" "")
20716         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20717               (match_operand:SI 2 "" "")))
20718    (set (reg:SI SP_REG)
20719         (plus:SI (reg:SI SP_REG)
20720                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20721   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20722   "@
20723    jmp\t%P1
20724    jmp\t%A1"
20725   [(set_attr "type" "callv")])
20726
20727 (define_insn "*call_value_0"
20728   [(set (match_operand 0 "" "")
20729         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20730               (match_operand:SI 2 "" "")))]
20731   "!TARGET_64BIT"
20732 {
20733   if (SIBLING_CALL_P (insn))
20734     return "jmp\t%P1";
20735   else
20736     return "call\t%P1";
20737 }
20738   [(set_attr "type" "callv")])
20739
20740 (define_insn "*call_value_0_rex64"
20741   [(set (match_operand 0 "" "")
20742         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20743               (match_operand:DI 2 "const_int_operand" "")))]
20744   "TARGET_64BIT"
20745 {
20746   if (SIBLING_CALL_P (insn))
20747     return "jmp\t%P1";
20748   else
20749     return "call\t%P1";
20750 }
20751   [(set_attr "type" "callv")])
20752
20753 (define_insn "*call_value_0_rex64_ms_sysv"
20754   [(set (match_operand 0 "" "")
20755         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20756               (match_operand:DI 2 "const_int_operand" "")))
20757    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20758    (clobber (reg:TI XMM6_REG))
20759    (clobber (reg:TI XMM7_REG))
20760    (clobber (reg:TI XMM8_REG))
20761    (clobber (reg:TI XMM9_REG))
20762    (clobber (reg:TI XMM10_REG))
20763    (clobber (reg:TI XMM11_REG))
20764    (clobber (reg:TI XMM12_REG))
20765    (clobber (reg:TI XMM13_REG))
20766    (clobber (reg:TI XMM14_REG))
20767    (clobber (reg:TI XMM15_REG))
20768    (clobber (reg:DI SI_REG))
20769    (clobber (reg:DI DI_REG))]
20770   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20771 {
20772   if (SIBLING_CALL_P (insn))
20773     return "jmp\t%P1";
20774   else
20775     return "call\t%P1";
20776 }
20777   [(set_attr "type" "callv")])
20778
20779 (define_insn "*call_value_1"
20780   [(set (match_operand 0 "" "")
20781         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20782               (match_operand:SI 2 "" "")))]
20783   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20784 {
20785   if (constant_call_address_operand (operands[1], Pmode))
20786     return "call\t%P1";
20787   return "call\t%A1";
20788 }
20789   [(set_attr "type" "callv")])
20790
20791 (define_insn "*sibcall_value_1"
20792   [(set (match_operand 0 "" "")
20793         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20794               (match_operand:SI 2 "" "")))]
20795   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20796   "@
20797    jmp\t%P1
20798    jmp\t%A1"
20799   [(set_attr "type" "callv")])
20800
20801 (define_insn "*call_value_1_rex64"
20802   [(set (match_operand 0 "" "")
20803         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20804               (match_operand:DI 2 "" "")))]
20805   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20806    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20807 {
20808   if (constant_call_address_operand (operands[1], Pmode))
20809     return "call\t%P1";
20810   return "call\t%A1";
20811 }
20812   [(set_attr "type" "callv")])
20813
20814 (define_insn "*call_value_1_rex64_ms_sysv"
20815   [(set (match_operand 0 "" "")
20816         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20817               (match_operand:DI 2 "" "")))
20818    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20819    (clobber (reg:TI XMM6_REG))
20820    (clobber (reg:TI XMM7_REG))
20821    (clobber (reg:TI XMM8_REG))
20822    (clobber (reg:TI XMM9_REG))
20823    (clobber (reg:TI XMM10_REG))
20824    (clobber (reg:TI XMM11_REG))
20825    (clobber (reg:TI XMM12_REG))
20826    (clobber (reg:TI XMM13_REG))
20827    (clobber (reg:TI XMM14_REG))
20828    (clobber (reg:TI XMM15_REG))
20829    (clobber (reg:DI SI_REG))
20830    (clobber (reg:DI DI_REG))]
20831   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20832 {
20833   if (constant_call_address_operand (operands[1], Pmode))
20834     return "call\t%P1";
20835   return "call\t%A1";
20836 }
20837   [(set_attr "type" "callv")])
20838
20839 (define_insn "*call_value_1_rex64_large"
20840   [(set (match_operand 0 "" "")
20841         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20842               (match_operand:DI 2 "" "")))]
20843   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20844   "call\t%A1"
20845   [(set_attr "type" "callv")])
20846
20847 (define_insn "*sibcall_value_1_rex64"
20848   [(set (match_operand 0 "" "")
20849         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20850               (match_operand:DI 2 "" "")))]
20851   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20852   "@
20853    jmp\t%P1
20854    jmp\t%A1"
20855   [(set_attr "type" "callv")])
20856 \f
20857 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20858 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20859 ;; caught for use by garbage collectors and the like.  Using an insn that
20860 ;; maps to SIGILL makes it more likely the program will rightfully die.
20861 ;; Keeping with tradition, "6" is in honor of #UD.
20862 (define_insn "trap"
20863   [(trap_if (const_int 1) (const_int 6))]
20864   ""
20865   { return ASM_SHORT "0x0b0f"; }
20866   [(set_attr "length" "2")])
20867
20868 (define_expand "sse_prologue_save"
20869   [(parallel [(set (match_operand:BLK 0 "" "")
20870                    (unspec:BLK [(reg:DI XMM0_REG)
20871                                 (reg:DI XMM1_REG)
20872                                 (reg:DI XMM2_REG)
20873                                 (reg:DI XMM3_REG)
20874                                 (reg:DI XMM4_REG)
20875                                 (reg:DI XMM5_REG)
20876                                 (reg:DI XMM6_REG)
20877                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20878               (use (match_operand:DI 1 "register_operand" ""))
20879               (use (match_operand:DI 2 "immediate_operand" ""))
20880               (use (label_ref:DI (match_operand 3 "" "")))])]
20881   "TARGET_64BIT"
20882   "")
20883
20884 (define_insn "*sse_prologue_save_insn"
20885   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20886                           (match_operand:DI 4 "const_int_operand" "n")))
20887         (unspec:BLK [(reg:DI XMM0_REG)
20888                      (reg:DI XMM1_REG)
20889                      (reg:DI XMM2_REG)
20890                      (reg:DI XMM3_REG)
20891                      (reg:DI XMM4_REG)
20892                      (reg:DI XMM5_REG)
20893                      (reg:DI XMM6_REG)
20894                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20895    (use (match_operand:DI 1 "register_operand" "r"))
20896    (use (match_operand:DI 2 "const_int_operand" "i"))
20897    (use (label_ref:DI (match_operand 3 "" "X")))]
20898   "TARGET_64BIT
20899    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20900    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20901 {
20902   int i;
20903   operands[0] = gen_rtx_MEM (Pmode,
20904                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20905   /* VEX instruction with a REX prefix will #UD.  */
20906   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20907     gcc_unreachable ();
20908
20909   output_asm_insn ("jmp\t%A1", operands);
20910   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20911     {
20912       operands[4] = adjust_address (operands[0], DImode, i*16);
20913       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20914       PUT_MODE (operands[4], TImode);
20915       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20916         output_asm_insn ("rex", operands);
20917       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20918     }
20919   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20920                                      CODE_LABEL_NUMBER (operands[3]));
20921   return "";
20922 }
20923   [(set_attr "type" "other")
20924    (set_attr "length_immediate" "0")
20925    (set_attr "length_address" "0")
20926    (set (attr "length")
20927      (if_then_else
20928        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20929        (const_string "34")
20930        (const_string "42")))
20931    (set_attr "memory" "store")
20932    (set_attr "modrm" "0")
20933    (set_attr "prefix" "maybe_vex")
20934    (set_attr "mode" "DI")])
20935
20936 (define_expand "prefetch"
20937   [(prefetch (match_operand 0 "address_operand" "")
20938              (match_operand:SI 1 "const_int_operand" "")
20939              (match_operand:SI 2 "const_int_operand" ""))]
20940   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20941 {
20942   int rw = INTVAL (operands[1]);
20943   int locality = INTVAL (operands[2]);
20944
20945   gcc_assert (rw == 0 || rw == 1);
20946   gcc_assert (locality >= 0 && locality <= 3);
20947   gcc_assert (GET_MODE (operands[0]) == Pmode
20948               || GET_MODE (operands[0]) == VOIDmode);
20949
20950   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20951      supported by SSE counterpart or the SSE prefetch is not available
20952      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20953      of locality.  */
20954   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20955     operands[2] = GEN_INT (3);
20956   else
20957     operands[1] = const0_rtx;
20958 })
20959
20960 (define_insn "*prefetch_sse"
20961   [(prefetch (match_operand:SI 0 "address_operand" "p")
20962              (const_int 0)
20963              (match_operand:SI 1 "const_int_operand" ""))]
20964   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20965 {
20966   static const char * const patterns[4] = {
20967    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20968   };
20969
20970   int locality = INTVAL (operands[1]);
20971   gcc_assert (locality >= 0 && locality <= 3);
20972
20973   return patterns[locality];
20974 }
20975   [(set_attr "type" "sse")
20976    (set_attr "atom_sse_attr" "prefetch")
20977    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20978    (set_attr "memory" "none")])
20979
20980 (define_insn "*prefetch_sse_rex"
20981   [(prefetch (match_operand:DI 0 "address_operand" "p")
20982              (const_int 0)
20983              (match_operand:SI 1 "const_int_operand" ""))]
20984   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20985 {
20986   static const char * const patterns[4] = {
20987    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20988   };
20989
20990   int locality = INTVAL (operands[1]);
20991   gcc_assert (locality >= 0 && locality <= 3);
20992
20993   return patterns[locality];
20994 }
20995   [(set_attr "type" "sse")
20996    (set_attr "atom_sse_attr" "prefetch")
20997    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20998    (set_attr "memory" "none")])
20999
21000 (define_insn "*prefetch_3dnow"
21001   [(prefetch (match_operand:SI 0 "address_operand" "p")
21002              (match_operand:SI 1 "const_int_operand" "n")
21003              (const_int 3))]
21004   "TARGET_3DNOW && !TARGET_64BIT"
21005 {
21006   if (INTVAL (operands[1]) == 0)
21007     return "prefetch\t%a0";
21008   else
21009     return "prefetchw\t%a0";
21010 }
21011   [(set_attr "type" "mmx")
21012    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21013    (set_attr "memory" "none")])
21014
21015 (define_insn "*prefetch_3dnow_rex"
21016   [(prefetch (match_operand:DI 0 "address_operand" "p")
21017              (match_operand:SI 1 "const_int_operand" "n")
21018              (const_int 3))]
21019   "TARGET_3DNOW && TARGET_64BIT"
21020 {
21021   if (INTVAL (operands[1]) == 0)
21022     return "prefetch\t%a0";
21023   else
21024     return "prefetchw\t%a0";
21025 }
21026   [(set_attr "type" "mmx")
21027    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21028    (set_attr "memory" "none")])
21029
21030 (define_expand "stack_protect_set"
21031   [(match_operand 0 "memory_operand" "")
21032    (match_operand 1 "memory_operand" "")]
21033   ""
21034 {
21035 #ifdef TARGET_THREAD_SSP_OFFSET
21036   if (TARGET_64BIT)
21037     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21038                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21039   else
21040     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21041                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21042 #else
21043   if (TARGET_64BIT)
21044     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21045   else
21046     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21047 #endif
21048   DONE;
21049 })
21050
21051 (define_insn "stack_protect_set_si"
21052   [(set (match_operand:SI 0 "memory_operand" "=m")
21053         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21054    (set (match_scratch:SI 2 "=&r") (const_int 0))
21055    (clobber (reg:CC FLAGS_REG))]
21056   ""
21057   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21058   [(set_attr "type" "multi")])
21059
21060 (define_insn "stack_protect_set_di"
21061   [(set (match_operand:DI 0 "memory_operand" "=m")
21062         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21063    (set (match_scratch:DI 2 "=&r") (const_int 0))
21064    (clobber (reg:CC FLAGS_REG))]
21065   "TARGET_64BIT"
21066   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21067   [(set_attr "type" "multi")])
21068
21069 (define_insn "stack_tls_protect_set_si"
21070   [(set (match_operand:SI 0 "memory_operand" "=m")
21071         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21072    (set (match_scratch:SI 2 "=&r") (const_int 0))
21073    (clobber (reg:CC FLAGS_REG))]
21074   ""
21075   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21076   [(set_attr "type" "multi")])
21077
21078 (define_insn "stack_tls_protect_set_di"
21079   [(set (match_operand:DI 0 "memory_operand" "=m")
21080         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21081    (set (match_scratch:DI 2 "=&r") (const_int 0))
21082    (clobber (reg:CC FLAGS_REG))]
21083   "TARGET_64BIT"
21084   {
21085      /* The kernel uses a different segment register for performance reasons; a
21086         system call would not have to trash the userspace segment register,
21087         which would be expensive */
21088      if (ix86_cmodel != CM_KERNEL)
21089         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21090      else
21091         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21092   }
21093   [(set_attr "type" "multi")])
21094
21095 (define_expand "stack_protect_test"
21096   [(match_operand 0 "memory_operand" "")
21097    (match_operand 1 "memory_operand" "")
21098    (match_operand 2 "" "")]
21099   ""
21100 {
21101   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21102
21103 #ifdef TARGET_THREAD_SSP_OFFSET
21104   if (TARGET_64BIT)
21105     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21106                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21107   else
21108     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21109                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21110 #else
21111   if (TARGET_64BIT)
21112     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21113   else
21114     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21115 #endif
21116
21117   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21118                                   flags, const0_rtx, operands[2]));
21119   DONE;
21120 })
21121
21122 (define_insn "stack_protect_test_si"
21123   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21124         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21125                      (match_operand:SI 2 "memory_operand" "m")]
21126                     UNSPEC_SP_TEST))
21127    (clobber (match_scratch:SI 3 "=&r"))]
21128   ""
21129   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21130   [(set_attr "type" "multi")])
21131
21132 (define_insn "stack_protect_test_di"
21133   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21134         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21135                      (match_operand:DI 2 "memory_operand" "m")]
21136                     UNSPEC_SP_TEST))
21137    (clobber (match_scratch:DI 3 "=&r"))]
21138   "TARGET_64BIT"
21139   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21140   [(set_attr "type" "multi")])
21141
21142 (define_insn "stack_tls_protect_test_si"
21143   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21144         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21145                      (match_operand:SI 2 "const_int_operand" "i")]
21146                     UNSPEC_SP_TLS_TEST))
21147    (clobber (match_scratch:SI 3 "=r"))]
21148   ""
21149   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21150   [(set_attr "type" "multi")])
21151
21152 (define_insn "stack_tls_protect_test_di"
21153   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21154         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21155                      (match_operand:DI 2 "const_int_operand" "i")]
21156                     UNSPEC_SP_TLS_TEST))
21157    (clobber (match_scratch:DI 3 "=r"))]
21158   "TARGET_64BIT"
21159   {
21160      /* The kernel uses a different segment register for performance reasons; a
21161         system call would not have to trash the userspace segment register,
21162         which would be expensive */
21163      if (ix86_cmodel != CM_KERNEL)
21164         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21165      else
21166         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21167   }
21168   [(set_attr "type" "multi")])
21169
21170 (define_mode_iterator CRC32MODE [QI HI SI])
21171 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21172 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21173
21174 (define_insn "sse4_2_crc32<mode>"
21175   [(set (match_operand:SI 0 "register_operand" "=r")
21176         (unspec:SI
21177           [(match_operand:SI 1 "register_operand" "0")
21178            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21179           UNSPEC_CRC32))]
21180   "TARGET_SSE4_2 || TARGET_CRC32"
21181   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21182   [(set_attr "type" "sselog1")
21183    (set_attr "prefix_rep" "1")
21184    (set_attr "prefix_extra" "1")
21185    (set (attr "prefix_data16")
21186      (if_then_else (match_operand:HI 2 "" "")
21187        (const_string "1")
21188        (const_string "*")))
21189    (set (attr "prefix_rex")
21190      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21191        (const_string "1")
21192        (const_string "*")))
21193    (set_attr "mode" "SI")])
21194
21195 (define_insn "sse4_2_crc32di"
21196   [(set (match_operand:DI 0 "register_operand" "=r")
21197         (unspec:DI
21198           [(match_operand:DI 1 "register_operand" "0")
21199            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21200           UNSPEC_CRC32))]
21201   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21202   "crc32q\t{%2, %0|%0, %2}"
21203   [(set_attr "type" "sselog1")
21204    (set_attr "prefix_rep" "1")
21205    (set_attr "prefix_extra" "1")
21206    (set_attr "mode" "DI")])
21207
21208 (define_expand "rdpmc"
21209   [(match_operand:DI 0 "register_operand" "")
21210    (match_operand:SI 1 "register_operand" "")]
21211   ""
21212 {
21213   rtx reg = gen_reg_rtx (DImode);
21214   rtx si;
21215
21216   /* Force operand 1 into ECX.  */
21217   rtx ecx = gen_rtx_REG (SImode, CX_REG);
21218   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21219   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21220                                 UNSPECV_RDPMC);
21221
21222   if (TARGET_64BIT)
21223     {
21224       rtvec vec = rtvec_alloc (2);
21225       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21226       rtx upper = gen_reg_rtx (DImode);
21227       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21228                                         gen_rtvec (1, const0_rtx),
21229                                         UNSPECV_RDPMC);
21230       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21231       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21232       emit_insn (load);
21233       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21234                                    NULL, 1, OPTAB_DIRECT);
21235       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21236                                  OPTAB_DIRECT);
21237     }
21238   else
21239     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21240   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21241   DONE;
21242 })
21243
21244 (define_insn "*rdpmc"
21245   [(set (match_operand:DI 0 "register_operand" "=A")
21246         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21247                             UNSPECV_RDPMC))]
21248   "!TARGET_64BIT"
21249   "rdpmc"
21250   [(set_attr "type" "other")
21251    (set_attr "length" "2")])
21252
21253 (define_insn "*rdpmc_rex64"
21254   [(set (match_operand:DI 0 "register_operand" "=a")
21255         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21256                             UNSPECV_RDPMC))
21257   (set (match_operand:DI 1 "register_operand" "=d")
21258        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21259   "TARGET_64BIT"
21260   "rdpmc"
21261   [(set_attr "type" "other")
21262    (set_attr "length" "2")])
21263
21264 (define_expand "rdtsc"
21265   [(set (match_operand:DI 0 "register_operand" "")
21266         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21267   ""
21268 {
21269   if (TARGET_64BIT)
21270     {
21271       rtvec vec = rtvec_alloc (2);
21272       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21273       rtx upper = gen_reg_rtx (DImode);
21274       rtx lower = gen_reg_rtx (DImode);
21275       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21276                                          gen_rtvec (1, const0_rtx),
21277                                          UNSPECV_RDTSC);
21278       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21279       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21280       emit_insn (load);
21281       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21282                                    NULL, 1, OPTAB_DIRECT);
21283       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21284                                    OPTAB_DIRECT);
21285       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21286       DONE;
21287     }
21288 })
21289
21290 (define_insn "*rdtsc"
21291   [(set (match_operand:DI 0 "register_operand" "=A")
21292         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21293   "!TARGET_64BIT"
21294   "rdtsc"
21295   [(set_attr "type" "other")
21296    (set_attr "length" "2")])
21297
21298 (define_insn "*rdtsc_rex64"
21299   [(set (match_operand:DI 0 "register_operand" "=a")
21300         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21301    (set (match_operand:DI 1 "register_operand" "=d")
21302         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21303   "TARGET_64BIT"
21304   "rdtsc"
21305   [(set_attr "type" "other")
21306    (set_attr "length" "2")])
21307
21308 (define_expand "rdtscp"
21309   [(match_operand:DI 0 "register_operand" "")
21310    (match_operand:SI 1 "memory_operand" "")]
21311   ""
21312 {
21313   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21314                                     gen_rtvec (1, const0_rtx),
21315                                     UNSPECV_RDTSCP);
21316   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21317                                     gen_rtvec (1, const0_rtx),
21318                                     UNSPECV_RDTSCP);
21319   rtx reg = gen_reg_rtx (DImode);
21320   rtx tmp = gen_reg_rtx (SImode);
21321
21322   if (TARGET_64BIT)
21323     {
21324       rtvec vec = rtvec_alloc (3);
21325       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21326       rtx upper = gen_reg_rtx (DImode);
21327       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21328       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21329       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21330       emit_insn (load);
21331       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21332                                    NULL, 1, OPTAB_DIRECT);
21333       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21334                                  OPTAB_DIRECT);
21335     }
21336   else
21337     {
21338       rtvec vec = rtvec_alloc (2);
21339       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21340       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21341       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21342       emit_insn (load);
21343     }
21344   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21345   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21346   DONE;
21347 })
21348
21349 (define_insn "*rdtscp"
21350   [(set (match_operand:DI 0 "register_operand" "=A")
21351         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21352    (set (match_operand:SI 1 "register_operand" "=c")
21353         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21354   "!TARGET_64BIT"
21355   "rdtscp"
21356   [(set_attr "type" "other")
21357    (set_attr "length" "3")])
21358
21359 (define_insn "*rdtscp_rex64"
21360   [(set (match_operand:DI 0 "register_operand" "=a")
21361         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21362    (set (match_operand:DI 1 "register_operand" "=d")
21363         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21364    (set (match_operand:SI 2 "register_operand" "=c")
21365         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21366   "TARGET_64BIT"
21367   "rdtscp"
21368   [(set_attr "type" "other")
21369    (set_attr "length" "3")])
21370
21371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21372 ;;
21373 ;; LWP instructions
21374 ;;
21375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21376
21377 (define_insn "lwp_llwpcbhi1"
21378   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21379            UNSPEC_LLWP_INTRINSIC)]
21380   "TARGET_LWP"
21381   "llwpcb\t%0"
21382   [(set_attr "type" "lwp")
21383    (set_attr "mode" "HI")])
21384
21385 (define_insn "lwp_llwpcbsi1"
21386   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21387            UNSPEC_LLWP_INTRINSIC)]
21388   "TARGET_LWP"
21389   "llwpcb\t%0"
21390   [(set_attr "type" "lwp")
21391    (set_attr "mode" "SI")])
21392
21393 (define_insn "lwp_llwpcbdi1"
21394   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21395            UNSPEC_LLWP_INTRINSIC)]
21396   "TARGET_LWP"
21397   "llwpcb\t%0"
21398   [(set_attr "type" "lwp")
21399    (set_attr "mode" "DI")])
21400
21401 (define_insn "lwp_slwpcbhi1"
21402   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21403            UNSPEC_SLWP_INTRINSIC)]
21404   "TARGET_LWP"
21405   "slwpcb\t%0"
21406   [(set_attr "type" "lwp")
21407    (set_attr "mode" "HI")])
21408
21409 (define_insn "lwp_slwpcbsi1"
21410   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21411            UNSPEC_SLWP_INTRINSIC)]
21412   "TARGET_LWP"
21413   "slwpcb\t%0"
21414   [(set_attr "type" "lwp")
21415    (set_attr "mode" "SI")])
21416
21417 (define_insn "lwp_slwpcbdi1"
21418   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21419            UNSPEC_SLWP_INTRINSIC)]
21420   "TARGET_LWP"
21421   "slwpcb\t%0"
21422   [(set_attr "type" "lwp")
21423    (set_attr "mode" "DI")])
21424
21425 (define_insn "lwp_lwpvalhi3"
21426   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21427                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21428                      (match_operand:HI 2 "const_int_operand" "")]
21429                     UNSPECV_LWPVAL_INTRINSIC)]
21430   "TARGET_LWP"
21431   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21432   [(set_attr "type" "lwp")
21433    (set_attr "mode" "HI")])
21434
21435 (define_insn "lwp_lwpvalsi3"
21436   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21437                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21438                      (match_operand:SI 2 "const_int_operand" "")]
21439                     UNSPECV_LWPVAL_INTRINSIC)]
21440   "TARGET_LWP"
21441   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21442   [(set_attr "type" "lwp")
21443    (set_attr "mode" "SI")])
21444
21445 (define_insn "lwp_lwpvaldi3"
21446   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21447                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21448                      (match_operand:SI 2 "const_int_operand" "")]
21449                     UNSPECV_LWPVAL_INTRINSIC)]
21450   "TARGET_LWP"
21451   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21452   [(set_attr "type" "lwp")
21453    (set_attr "mode" "DI")])
21454
21455 (define_insn "lwp_lwpinshi3"
21456   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21457                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21458                      (match_operand:HI 2 "const_int_operand" "")]
21459                     UNSPECV_LWPINS_INTRINSIC)]
21460   "TARGET_LWP"
21461   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21462   [(set_attr "type" "lwp")
21463    (set_attr "mode" "HI")])
21464
21465 (define_insn "lwp_lwpinssi3"
21466   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21467                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21468                      (match_operand:SI 2 "const_int_operand" "")]
21469                     UNSPECV_LWPINS_INTRINSIC)]
21470   "TARGET_LWP"
21471   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21472   [(set_attr "type" "lwp")
21473    (set_attr "mode" "SI")])
21474
21475 (define_insn "lwp_lwpinsdi3"
21476   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21477                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21478                      (match_operand:SI 2 "const_int_operand" "")]
21479                     UNSPECV_LWPINS_INTRINSIC)]
21480   "TARGET_LWP"
21481   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21482   [(set_attr "type" "lwp")
21483    (set_attr "mode" "DI")])
21484
21485 (include "mmx.md")
21486 (include "sse.md")
21487 (include "sync.md")