OSDN Git Service

2009-06-28 Paolo Bonzini <bonzini@gnu.org>
[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 SSE5 com* 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 SSE5
200    (UNSPEC_SSE5_INTRINSIC       150)
201    (UNSPEC_SSE5_UNSIGNED_CMP    151)
202    (UNSPEC_SSE5_TRUEFALSE       152)
203    (UNSPEC_SSE5_PERMUTE         153)
204    (UNSPEC_FRCZ                 154)
205    (UNSPEC_CVTPH2PS             155)
206    (UNSPEC_CVTPS2PH             156)
207
208    ; For AES support
209    (UNSPEC_AESENC               159)
210    (UNSPEC_AESENCLAST           160)
211    (UNSPEC_AESDEC               161)
212    (UNSPEC_AESDECLAST           162)
213    (UNSPEC_AESIMC               163)
214    (UNSPEC_AESKEYGENASSIST      164)
215
216    ; For PCLMUL support
217    (UNSPEC_PCLMUL               165)
218
219    ; For AVX support
220    (UNSPEC_PCMP                 166)
221    (UNSPEC_VPERMIL              167)
222    (UNSPEC_VPERMIL2F128         168)
223    (UNSPEC_MASKLOAD             169)
224    (UNSPEC_MASKSTORE            170)
225    (UNSPEC_CAST                 171)
226    (UNSPEC_VTESTP               172)
227   ])
228
229 (define_constants
230   [(UNSPECV_BLOCKAGE            0)
231    (UNSPECV_STACK_PROBE         1)
232    (UNSPECV_EMMS                2)
233    (UNSPECV_LDMXCSR             3)
234    (UNSPECV_STMXCSR             4)
235    (UNSPECV_FEMMS               5)
236    (UNSPECV_CLFLUSH             6)
237    (UNSPECV_ALIGN               7)
238    (UNSPECV_MONITOR             8)
239    (UNSPECV_MWAIT               9)
240    (UNSPECV_CMPXCHG             10)
241    (UNSPECV_XCHG                12)
242    (UNSPECV_LOCK                13)
243    (UNSPECV_PROLOGUE_USE        14)
244    (UNSPECV_CLD                 15)
245    (UNSPECV_VZEROALL            16)
246    (UNSPECV_VZEROUPPER          17)
247    (UNSPECV_RDTSC               18)
248    (UNSPECV_RDTSCP              19)
249    (UNSPECV_RDPMC               20)
250   ])
251
252 ;; Constants to represent pcomtrue/pcomfalse variants
253 (define_constants
254   [(PCOM_FALSE                  0)
255    (PCOM_TRUE                   1)
256    (COM_FALSE_S                 2)
257    (COM_FALSE_P                 3)
258    (COM_TRUE_S                  4)
259    (COM_TRUE_P                  5)
260   ])
261
262 ;; Constants used in the SSE5 pperm instruction
263 (define_constants
264   [(PPERM_SRC                   0x00)   /* copy source */
265    (PPERM_INVERT                0x20)   /* invert source */
266    (PPERM_REVERSE               0x40)   /* bit reverse source */
267    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
268    (PPERM_ZERO                  0x80)   /* all 0's */
269    (PPERM_ONES                  0xa0)   /* all 1's */
270    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
271    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
272    (PPERM_SRC1                  0x00)   /* use first source byte */
273    (PPERM_SRC2                  0x10)   /* use second source byte */
274    ])
275
276 ;; Registers by name.
277 (define_constants
278   [(AX_REG                       0)
279    (DX_REG                       1)
280    (CX_REG                       2)
281    (BX_REG                       3)
282    (SI_REG                       4)
283    (DI_REG                       5)
284    (BP_REG                       6)
285    (SP_REG                       7)
286    (ST0_REG                      8)
287    (ST1_REG                      9)
288    (ST2_REG                     10)
289    (ST3_REG                     11)
290    (ST4_REG                     12)
291    (ST5_REG                     13)
292    (ST6_REG                     14)
293    (ST7_REG                     15)
294    (FLAGS_REG                   17)
295    (FPSR_REG                    18)
296    (FPCR_REG                    19)
297    (XMM0_REG                    21)
298    (XMM1_REG                    22)
299    (XMM2_REG                    23)
300    (XMM3_REG                    24)
301    (XMM4_REG                    25)
302    (XMM5_REG                    26)
303    (XMM6_REG                    27)
304    (XMM7_REG                    28)
305    (MM0_REG                     29)
306    (MM1_REG                     30)
307    (MM2_REG                     31)
308    (MM3_REG                     32)
309    (MM4_REG                     33)
310    (MM5_REG                     34)
311    (MM6_REG                     35)
312    (MM7_REG                     36)
313    (R8_REG                      37)
314    (R9_REG                      38)
315    (R10_REG                     39)
316    (R11_REG                     40)
317    (R12_REG                     41)
318    (R13_REG                     42)
319    (XMM8_REG                    45)
320    (XMM9_REG                    46)
321    (XMM10_REG                   47)
322    (XMM11_REG                   48)
323    (XMM12_REG                   49)
324    (XMM13_REG                   50)
325    (XMM14_REG                   51)
326    (XMM15_REG                   52)
327   ])
328
329 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
330 ;; from i386.c.
331
332 ;; In C guard expressions, put expressions which may be compile-time
333 ;; constants first.  This allows for better optimization.  For
334 ;; example, write "TARGET_64BIT && reload_completed", not
335 ;; "reload_completed && TARGET_64BIT".
336
337 \f
338 ;; Processor type.
339 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
340                     generic64,amdfam10"
341   (const (symbol_ref "ix86_schedule")))
342
343 ;; A basic instruction type.  Refinements due to arguments to be
344 ;; provided in other attributes.
345 (define_attr "type"
346   "other,multi,
347    alu,alu1,negnot,imov,imovx,lea,
348    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
349    icmp,test,ibr,setcc,icmov,
350    push,pop,call,callv,leave,
351    str,bitmanip,
352    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
353    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
354    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
355    ssemuladd,sse4arg,
356    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
357   (const_string "other"))
358
359 ;; Main data type used by the insn
360 (define_attr "mode"
361   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
362   (const_string "unknown"))
363
364 ;; The CPU unit operations uses.
365 (define_attr "unit" "integer,i387,sse,mmx,unknown"
366   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
367            (const_string "i387")
368          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
369                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
370                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
371            (const_string "sse")
372          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
373            (const_string "mmx")
374          (eq_attr "type" "other")
375            (const_string "unknown")]
376          (const_string "integer")))
377
378 ;; The (bounding maximum) length of an instruction immediate.
379 (define_attr "length_immediate" ""
380   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
381                           bitmanip")
382            (const_int 0)
383          (eq_attr "unit" "i387,sse,mmx")
384            (const_int 0)
385          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
386                           imul,icmp,push,pop")
387            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
388          (eq_attr "type" "imov,test")
389            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
390          (eq_attr "type" "call")
391            (if_then_else (match_operand 0 "constant_call_address_operand" "")
392              (const_int 4)
393              (const_int 0))
394          (eq_attr "type" "callv")
395            (if_then_else (match_operand 1 "constant_call_address_operand" "")
396              (const_int 4)
397              (const_int 0))
398          ;; We don't know the size before shorten_branches.  Expect
399          ;; the instruction to fit for better scheduling.
400          (eq_attr "type" "ibr")
401            (const_int 1)
402          ]
403          (symbol_ref "/* Update immediate_length and other attributes! */
404                       gcc_unreachable (),1")))
405
406 ;; The (bounding maximum) length of an instruction address.
407 (define_attr "length_address" ""
408   (cond [(eq_attr "type" "str,other,multi,fxch")
409            (const_int 0)
410          (and (eq_attr "type" "call")
411               (match_operand 0 "constant_call_address_operand" ""))
412              (const_int 0)
413          (and (eq_attr "type" "callv")
414               (match_operand 1 "constant_call_address_operand" ""))
415              (const_int 0)
416          ]
417          (symbol_ref "ix86_attr_length_address_default (insn)")))
418
419 ;; Set when length prefix is used.
420 (define_attr "prefix_data16" ""
421   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
422            (const_int 0)
423          (eq_attr "mode" "HI")
424            (const_int 1)
425          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
426            (const_int 1)
427         ]
428         (const_int 0)))
429
430 ;; Set when string REP prefix is used.
431 (define_attr "prefix_rep" ""
432   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
433            (const_int 0)
434          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
435            (const_int 1)
436         ]
437         (const_int 0)))
438
439 ;; Set when 0f opcode prefix is used.
440 (define_attr "prefix_0f" ""
441   (if_then_else
442     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
443          (eq_attr "unit" "sse,mmx"))
444     (const_int 1)
445     (const_int 0)))
446
447 ;; Set when REX opcode prefix is used.
448 (define_attr "prefix_rex" ""
449   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
450            (const_int 0)
451          (and (eq_attr "mode" "DI")
452               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
453                    (eq_attr "unit" "!mmx")))
454            (const_int 1)
455          (and (eq_attr "mode" "QI")
456               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
457                   (const_int 0)))
458            (const_int 1)
459          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
460              (const_int 0))
461            (const_int 1)
462          (and (eq_attr "type" "imovx")
463               (match_operand:QI 1 "ext_QIreg_operand" ""))
464            (const_int 1)
465         ]
466         (const_int 0)))
467
468 ;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
469 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
470 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
471 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
472 (define_attr "prefix_extra" ""
473   (cond [(eq_attr "type" "ssemuladd,sse4arg")
474            (const_int 2)
475          (eq_attr "type" "sseiadd1,ssecvt1")
476            (const_int 1)
477         ]
478         (const_int 0)))
479
480 ;; Prefix used: original, VEX or maybe VEX.
481 (define_attr "prefix" "orig,vex,maybe_vex"
482   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
483     (const_string "vex")
484     (const_string "orig")))
485
486 ;; VEX W bit is used.
487 (define_attr "prefix_vex_w" "" (const_int 0))
488
489 ;; The length of VEX prefix
490 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
491 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
492 ;; still prefix_0f 1, with prefix_extra 1.
493 (define_attr "length_vex" ""
494   (if_then_else (and (eq_attr "prefix_0f" "1")
495                      (eq_attr "prefix_extra" "0"))
496     (if_then_else (eq_attr "prefix_vex_w" "1")
497       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
498       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
499     (if_then_else (eq_attr "prefix_vex_w" "1")
500       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
501       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
502
503 ;; Set when modrm byte is used.
504 (define_attr "modrm" ""
505   (cond [(eq_attr "type" "str,leave")
506            (const_int 0)
507          (eq_attr "unit" "i387")
508            (const_int 0)
509          (and (eq_attr "type" "incdec")
510               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
511                    (ior (match_operand:SI 1 "register_operand" "")
512                         (match_operand:HI 1 "register_operand" ""))))
513            (const_int 0)
514          (and (eq_attr "type" "push")
515               (not (match_operand 1 "memory_operand" "")))
516            (const_int 0)
517          (and (eq_attr "type" "pop")
518               (not (match_operand 0 "memory_operand" "")))
519            (const_int 0)
520          (and (eq_attr "type" "imov")
521               (and (not (eq_attr "mode" "DI"))
522                    (ior (and (match_operand 0 "register_operand" "")
523                              (match_operand 1 "immediate_operand" ""))
524                         (ior (and (match_operand 0 "ax_reg_operand" "")
525                                   (match_operand 1 "memory_displacement_only_operand" ""))
526                              (and (match_operand 0 "memory_displacement_only_operand" "")
527                                   (match_operand 1 "ax_reg_operand" ""))))))
528            (const_int 0)
529          (and (eq_attr "type" "call")
530               (match_operand 0 "constant_call_address_operand" ""))
531              (const_int 0)
532          (and (eq_attr "type" "callv")
533               (match_operand 1 "constant_call_address_operand" ""))
534              (const_int 0)
535          (and (eq_attr "type" "alu,alu1,icmp,test")
536               (match_operand 0 "ax_reg_operand" ""))
537              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
538          ]
539          (const_int 1)))
540
541 ;; The (bounding maximum) length of an instruction in bytes.
542 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
543 ;; Later we may want to split them and compute proper length as for
544 ;; other insns.
545 (define_attr "length" ""
546   (cond [(eq_attr "type" "other,multi,fistp,frndint")
547            (const_int 16)
548          (eq_attr "type" "fcmp")
549            (const_int 4)
550          (eq_attr "unit" "i387")
551            (plus (const_int 2)
552                  (plus (attr "prefix_data16")
553                        (attr "length_address")))
554          (ior (eq_attr "prefix" "vex")
555               (and (eq_attr "prefix" "maybe_vex")
556                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
557            (plus (attr "length_vex")
558                  (plus (attr "length_immediate")
559                        (plus (attr "modrm")
560                              (attr "length_address"))))]
561          (plus (plus (attr "modrm")
562                      (plus (attr "prefix_0f")
563                            (plus (attr "prefix_rex")
564                                  (plus (attr "prefix_extra")
565                                        (const_int 1)))))
566                (plus (attr "prefix_rep")
567                      (plus (attr "prefix_data16")
568                            (plus (attr "length_immediate")
569                                  (attr "length_address")))))))
570
571 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
572 ;; `store' if there is a simple memory reference therein, or `unknown'
573 ;; if the instruction is complex.
574
575 (define_attr "memory" "none,load,store,both,unknown"
576   (cond [(eq_attr "type" "other,multi,str")
577            (const_string "unknown")
578          (eq_attr "type" "lea,fcmov,fpspc")
579            (const_string "none")
580          (eq_attr "type" "fistp,leave")
581            (const_string "both")
582          (eq_attr "type" "frndint")
583            (const_string "load")
584          (eq_attr "type" "push")
585            (if_then_else (match_operand 1 "memory_operand" "")
586              (const_string "both")
587              (const_string "store"))
588          (eq_attr "type" "pop")
589            (if_then_else (match_operand 0 "memory_operand" "")
590              (const_string "both")
591              (const_string "load"))
592          (eq_attr "type" "setcc")
593            (if_then_else (match_operand 0 "memory_operand" "")
594              (const_string "store")
595              (const_string "none"))
596          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
597            (if_then_else (ior (match_operand 0 "memory_operand" "")
598                               (match_operand 1 "memory_operand" ""))
599              (const_string "load")
600              (const_string "none"))
601          (eq_attr "type" "ibr")
602            (if_then_else (match_operand 0 "memory_operand" "")
603              (const_string "load")
604              (const_string "none"))
605          (eq_attr "type" "call")
606            (if_then_else (match_operand 0 "constant_call_address_operand" "")
607              (const_string "none")
608              (const_string "load"))
609          (eq_attr "type" "callv")
610            (if_then_else (match_operand 1 "constant_call_address_operand" "")
611              (const_string "none")
612              (const_string "load"))
613          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
614               (match_operand 1 "memory_operand" ""))
615            (const_string "both")
616          (and (match_operand 0 "memory_operand" "")
617               (match_operand 1 "memory_operand" ""))
618            (const_string "both")
619          (match_operand 0 "memory_operand" "")
620            (const_string "store")
621          (match_operand 1 "memory_operand" "")
622            (const_string "load")
623          (and (eq_attr "type"
624                  "!alu1,negnot,ishift1,
625                    imov,imovx,icmp,test,bitmanip,
626                    fmov,fcmp,fsgn,
627                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
628                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
629               (match_operand 2 "memory_operand" ""))
630            (const_string "load")
631          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
632               (match_operand 3 "memory_operand" ""))
633            (const_string "load")
634         ]
635         (const_string "none")))
636
637 ;; Indicates if an instruction has both an immediate and a displacement.
638
639 (define_attr "imm_disp" "false,true,unknown"
640   (cond [(eq_attr "type" "other,multi")
641            (const_string "unknown")
642          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
643               (and (match_operand 0 "memory_displacement_operand" "")
644                    (match_operand 1 "immediate_operand" "")))
645            (const_string "true")
646          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
647               (and (match_operand 0 "memory_displacement_operand" "")
648                    (match_operand 2 "immediate_operand" "")))
649            (const_string "true")
650         ]
651         (const_string "false")))
652
653 ;; Indicates if an FP operation has an integer source.
654
655 (define_attr "fp_int_src" "false,true"
656   (const_string "false"))
657
658 ;; Defines rounding mode of an FP operation.
659
660 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
661   (const_string "any"))
662
663 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
664 (define_attr "use_carry" "0,1" (const_string "0"))
665
666 ;; Define attribute to indicate unaligned ssemov insns
667 (define_attr "movu" "0,1" (const_string "0"))
668
669 ;; Describe a user's asm statement.
670 (define_asm_attributes
671   [(set_attr "length" "128")
672    (set_attr "type" "multi")])
673
674 ;; All integer comparison codes.
675 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
676
677 ;; All floating-point comparison codes.
678 (define_code_iterator fp_cond [unordered ordered
679                                uneq unge ungt unle unlt ltgt ])
680
681 (define_code_iterator plusminus [plus minus])
682
683 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
684
685 ;; Base name for define_insn
686 (define_code_attr plusminus_insn
687   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
688    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
689
690 ;; Base name for insn mnemonic.
691 (define_code_attr plusminus_mnemonic
692   [(plus "add") (ss_plus "adds") (us_plus "addus")
693    (minus "sub") (ss_minus "subs") (us_minus "subus")])
694
695 ;; Mark commutative operators as such in constraints.
696 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
697                         (minus "") (ss_minus "") (us_minus "")])
698
699 ;; Mapping of signed max and min
700 (define_code_iterator smaxmin [smax smin])
701
702 ;; Mapping of unsigned max and min
703 (define_code_iterator umaxmin [umax umin])
704
705 ;; Mapping of signed/unsigned max and min
706 (define_code_iterator maxmin [smax smin umax umin])
707
708 ;; Base name for integer and FP insn mnemonic
709 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
710                                  (umax "maxu") (umin "minu")])
711 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
712
713 ;; Mapping of parallel logic operators
714 (define_code_iterator plogic [and ior xor])
715
716 ;; Base name for insn mnemonic.
717 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
718
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
721
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
724
725 ;; All single word integer modes.
726 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
727
728 ;; Single word integer modes without QImode.
729 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
730
731 ;; Instruction suffix for integer modes.
732 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
733
734 ;; Register class for integer modes.
735 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
736
737 ;; Immediate operand constraint for integer modes.
738 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
739
740 ;; General operand predicate for integer modes.
741 (define_mode_attr general_operand
742         [(QI "general_operand")
743          (HI "general_operand")
744          (SI "general_operand")
745          (DI "x86_64_general_operand")])
746
747 ;; SSE and x87 SFmode and DFmode floating point modes
748 (define_mode_iterator MODEF [SF DF])
749
750 ;; All x87 floating point modes
751 (define_mode_iterator X87MODEF [SF DF XF])
752
753 ;; All integer modes handled by x87 fisttp operator.
754 (define_mode_iterator X87MODEI [HI SI DI])
755
756 ;; All integer modes handled by integer x87 operators.
757 (define_mode_iterator X87MODEI12 [HI SI])
758
759 ;; All integer modes handled by SSE cvtts?2si* operators.
760 (define_mode_iterator SSEMODEI24 [SI DI])
761
762 ;; SSE asm suffix for floating point modes
763 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
764
765 ;; SSE vector mode corresponding to a scalar mode
766 (define_mode_attr ssevecmode
767   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
768
769 ;; Instruction suffix for REX 64bit operators.
770 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
771
772 ;; This mode iterator allows :P to be used for patterns that operate on
773 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
774 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
775
776 \f
777 ;; Scheduling descriptions
778
779 (include "pentium.md")
780 (include "ppro.md")
781 (include "k6.md")
782 (include "athlon.md")
783 (include "geode.md")
784 (include "atom.md")
785
786 \f
787 ;; Operand and operator predicates and constraints
788
789 (include "predicates.md")
790 (include "constraints.md")
791
792 \f
793 ;; Compare and branch/compare and store instructions.
794
795 (define_expand "cbranchti4"
796   [(set (reg:CC FLAGS_REG)
797         (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
798                     (match_operand:TI 2 "x86_64_general_operand" "")))
799    (set (pc) (if_then_else
800               (match_operator 0 "comparison_operator"
801                [(reg:CC FLAGS_REG)
802                 (const_int 0)])
803               (label_ref (match_operand 3 "" ""))
804               (pc)))]
805   "TARGET_64BIT"
806 {
807   if (MEM_P (operands[1]) && MEM_P (operands[2]))
808     operands[1] = force_reg (TImode, operands[1]);
809   ix86_compare_op0 = operands[1];
810   ix86_compare_op1 = operands[2];
811   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
812   DONE;
813 })
814
815 (define_expand "cbranchdi4"
816   [(set (reg:CC FLAGS_REG)
817         (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
818                     (match_operand:DI 2 "x86_64_general_operand" "")))
819    (set (pc) (if_then_else
820               (match_operator 0 "comparison_operator"
821                [(reg:CC FLAGS_REG)
822                 (const_int 0)])
823               (label_ref (match_operand 3 "" ""))
824               (pc)))]
825   ""
826 {
827   if (MEM_P (operands[1]) && MEM_P (operands[2]))
828     operands[1] = force_reg (DImode, operands[1]);
829   ix86_compare_op0 = operands[1];
830   ix86_compare_op1 = operands[2];
831   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
832   DONE;
833 })
834
835 (define_expand "cstoredi4"
836   [(set (reg:CC FLAGS_REG)
837         (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
838                     (match_operand:DI 3 "x86_64_general_operand" "")))
839    (set (match_operand:QI 0 "register_operand" "")
840               (match_operator 1 "comparison_operator"
841                [(reg:CC FLAGS_REG)
842                 (const_int 0)]))]
843   "TARGET_64BIT"
844 {
845   if (MEM_P (operands[2]) && MEM_P (operands[3]))
846     operands[2] = force_reg (DImode, operands[2]);
847   ix86_compare_op0 = operands[2];
848   ix86_compare_op1 = operands[3];
849   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
850   DONE;
851 })
852
853 (define_expand "cbranchsi4"
854   [(set (reg:CC FLAGS_REG)
855         (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
856                     (match_operand:SI 2 "general_operand" "")))
857    (set (pc) (if_then_else
858               (match_operator 0 "comparison_operator"
859                [(reg:CC FLAGS_REG)
860                 (const_int 0)])
861               (label_ref (match_operand 3 "" ""))
862               (pc)))]
863   ""
864 {
865   if (MEM_P (operands[1]) && MEM_P (operands[2]))
866     operands[1] = force_reg (SImode, operands[1]);
867   ix86_compare_op0 = operands[1];
868   ix86_compare_op1 = operands[2];
869   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
870   DONE;
871 })
872
873 (define_expand "cstoresi4"
874   [(set (reg:CC FLAGS_REG)
875         (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
876                     (match_operand:SI 3 "general_operand" "")))
877    (set (match_operand:QI 0 "register_operand" "")
878               (match_operator 1 "comparison_operator"
879                [(reg:CC FLAGS_REG)
880                 (const_int 0)]))]
881   ""
882 {
883   if (MEM_P (operands[2]) && MEM_P (operands[3]))
884     operands[2] = force_reg (SImode, operands[2]);
885   ix86_compare_op0 = operands[2];
886   ix86_compare_op1 = operands[3];
887   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
888   DONE;
889 })
890
891 (define_expand "cbranchhi4"
892   [(set (reg:CC FLAGS_REG)
893         (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
894                     (match_operand:HI 2 "general_operand" "")))
895    (set (pc) (if_then_else
896               (match_operator 0 "comparison_operator"
897                [(reg:CC FLAGS_REG)
898                 (const_int 0)])
899               (label_ref (match_operand 3 "" ""))
900               (pc)))]
901   ""
902 {
903   if (MEM_P (operands[1]) && MEM_P (operands[2]))
904     operands[1] = force_reg (HImode, operands[1]);
905   ix86_compare_op0 = operands[1];
906   ix86_compare_op1 = operands[2];
907   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
908   DONE;
909 })
910
911 (define_expand "cstorehi4"
912   [(set (reg:CC FLAGS_REG)
913         (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
914                     (match_operand:HI 3 "general_operand" "")))
915    (set (match_operand:QI 0 "register_operand" "")
916               (match_operator 1 "comparison_operator"
917                [(reg:CC FLAGS_REG)
918                 (const_int 0)]))]
919   ""
920 {
921   if (MEM_P (operands[2]) && MEM_P (operands[3]))
922     operands[2] = force_reg (HImode, operands[2]);
923   ix86_compare_op0 = operands[2];
924   ix86_compare_op1 = operands[3];
925   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
926   DONE;
927 })
928
929
930 (define_expand "cbranchqi4"
931   [(set (reg:CC FLAGS_REG)
932         (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
933                     (match_operand:QI 2 "general_operand" "")))
934    (set (pc) (if_then_else
935               (match_operator 0 "comparison_operator"
936                [(reg:CC FLAGS_REG)
937                 (const_int 0)])
938               (label_ref (match_operand 3 "" ""))
939               (pc)))]
940   ""
941 {
942   if (MEM_P (operands[1]) && MEM_P (operands[2]))
943     operands[1] = force_reg (QImode, operands[1]);
944   ix86_compare_op0 = operands[1];
945   ix86_compare_op1 = operands[2];
946   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
947   DONE;
948 })
949
950
951 (define_expand "cstoreqi4"
952   [(set (reg:CC FLAGS_REG)
953         (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
954                     (match_operand:QI 3 "general_operand" "")))
955    (set (match_operand:QI 0 "register_operand" "")
956               (match_operator 1 "comparison_operator"
957                [(reg:CC FLAGS_REG)
958                 (const_int 0)]))]
959   ""
960 {
961   if (MEM_P (operands[2]) && MEM_P (operands[3]))
962     operands[2] = force_reg (QImode, operands[2]);
963   ix86_compare_op0 = operands[2];
964   ix86_compare_op1 = operands[3];
965   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
966   DONE;
967 })
968
969
970 (define_insn "cmpdi_ccno_1_rex64"
971   [(set (reg FLAGS_REG)
972         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
973                  (match_operand:DI 1 "const0_operand" "")))]
974   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
975   "@
976    test{q}\t%0, %0
977    cmp{q}\t{%1, %0|%0, %1}"
978   [(set_attr "type" "test,icmp")
979    (set_attr "length_immediate" "0,1")
980    (set_attr "mode" "DI")])
981
982 (define_insn "*cmpdi_minus_1_rex64"
983   [(set (reg FLAGS_REG)
984         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
985                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
986                  (const_int 0)))]
987   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
988   "cmp{q}\t{%1, %0|%0, %1}"
989   [(set_attr "type" "icmp")
990    (set_attr "mode" "DI")])
991
992 (define_expand "cmpdi_1_rex64"
993   [(set (reg:CC FLAGS_REG)
994         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
995                     (match_operand:DI 1 "general_operand" "")))]
996   "TARGET_64BIT"
997   "")
998
999 (define_insn "cmpdi_1_insn_rex64"
1000   [(set (reg FLAGS_REG)
1001         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1002                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1003   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004   "cmp{q}\t{%1, %0|%0, %1}"
1005   [(set_attr "type" "icmp")
1006    (set_attr "mode" "DI")])
1007
1008
1009 (define_insn "*cmpsi_ccno_1"
1010   [(set (reg FLAGS_REG)
1011         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1012                  (match_operand:SI 1 "const0_operand" "")))]
1013   "ix86_match_ccmode (insn, CCNOmode)"
1014   "@
1015    test{l}\t%0, %0
1016    cmp{l}\t{%1, %0|%0, %1}"
1017   [(set_attr "type" "test,icmp")
1018    (set_attr "length_immediate" "0,1")
1019    (set_attr "mode" "SI")])
1020
1021 (define_insn "*cmpsi_minus_1"
1022   [(set (reg FLAGS_REG)
1023         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1024                            (match_operand:SI 1 "general_operand" "ri,mr"))
1025                  (const_int 0)))]
1026   "ix86_match_ccmode (insn, CCGOCmode)"
1027   "cmp{l}\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "icmp")
1029    (set_attr "mode" "SI")])
1030
1031 (define_expand "cmpsi_1"
1032   [(set (reg:CC FLAGS_REG)
1033         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1034                     (match_operand:SI 1 "general_operand" "")))]
1035   ""
1036   "")
1037
1038 (define_insn "*cmpsi_1_insn"
1039   [(set (reg FLAGS_REG)
1040         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1041                  (match_operand:SI 1 "general_operand" "ri,mr")))]
1042   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1043     && ix86_match_ccmode (insn, CCmode)"
1044   "cmp{l}\t{%1, %0|%0, %1}"
1045   [(set_attr "type" "icmp")
1046    (set_attr "mode" "SI")])
1047
1048 (define_insn "*cmphi_ccno_1"
1049   [(set (reg FLAGS_REG)
1050         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1051                  (match_operand:HI 1 "const0_operand" "")))]
1052   "ix86_match_ccmode (insn, CCNOmode)"
1053   "@
1054    test{w}\t%0, %0
1055    cmp{w}\t{%1, %0|%0, %1}"
1056   [(set_attr "type" "test,icmp")
1057    (set_attr "length_immediate" "0,1")
1058    (set_attr "mode" "HI")])
1059
1060 (define_insn "*cmphi_minus_1"
1061   [(set (reg FLAGS_REG)
1062         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1063                            (match_operand:HI 1 "general_operand" "rn,mr"))
1064                  (const_int 0)))]
1065   "ix86_match_ccmode (insn, CCGOCmode)"
1066   "cmp{w}\t{%1, %0|%0, %1}"
1067   [(set_attr "type" "icmp")
1068    (set_attr "mode" "HI")])
1069
1070 (define_insn "*cmphi_1"
1071   [(set (reg FLAGS_REG)
1072         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1073                  (match_operand:HI 1 "general_operand" "rn,mr")))]
1074   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1075    && ix86_match_ccmode (insn, CCmode)"
1076   "cmp{w}\t{%1, %0|%0, %1}"
1077   [(set_attr "type" "icmp")
1078    (set_attr "mode" "HI")])
1079
1080 (define_insn "*cmpqi_ccno_1"
1081   [(set (reg FLAGS_REG)
1082         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1083                  (match_operand:QI 1 "const0_operand" "")))]
1084   "ix86_match_ccmode (insn, CCNOmode)"
1085   "@
1086    test{b}\t%0, %0
1087    cmp{b}\t{$0, %0|%0, 0}"
1088   [(set_attr "type" "test,icmp")
1089    (set_attr "length_immediate" "0,1")
1090    (set_attr "mode" "QI")])
1091
1092 (define_insn "*cmpqi_1"
1093   [(set (reg FLAGS_REG)
1094         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1095                  (match_operand:QI 1 "general_operand" "qn,mq")))]
1096   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1097     && ix86_match_ccmode (insn, CCmode)"
1098   "cmp{b}\t{%1, %0|%0, %1}"
1099   [(set_attr "type" "icmp")
1100    (set_attr "mode" "QI")])
1101
1102 (define_insn "*cmpqi_minus_1"
1103   [(set (reg FLAGS_REG)
1104         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1105                            (match_operand:QI 1 "general_operand" "qn,mq"))
1106                  (const_int 0)))]
1107   "ix86_match_ccmode (insn, CCGOCmode)"
1108   "cmp{b}\t{%1, %0|%0, %1}"
1109   [(set_attr "type" "icmp")
1110    (set_attr "mode" "QI")])
1111
1112 (define_insn "*cmpqi_ext_1"
1113   [(set (reg FLAGS_REG)
1114         (compare
1115           (match_operand:QI 0 "general_operand" "Qm")
1116           (subreg:QI
1117             (zero_extract:SI
1118               (match_operand 1 "ext_register_operand" "Q")
1119               (const_int 8)
1120               (const_int 8)) 0)))]
1121   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1122   "cmp{b}\t{%h1, %0|%0, %h1}"
1123   [(set_attr "type" "icmp")
1124    (set_attr "mode" "QI")])
1125
1126 (define_insn "*cmpqi_ext_1_rex64"
1127   [(set (reg FLAGS_REG)
1128         (compare
1129           (match_operand:QI 0 "register_operand" "Q")
1130           (subreg:QI
1131             (zero_extract:SI
1132               (match_operand 1 "ext_register_operand" "Q")
1133               (const_int 8)
1134               (const_int 8)) 0)))]
1135   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1136   "cmp{b}\t{%h1, %0|%0, %h1}"
1137   [(set_attr "type" "icmp")
1138    (set_attr "mode" "QI")])
1139
1140 (define_insn "*cmpqi_ext_2"
1141   [(set (reg FLAGS_REG)
1142         (compare
1143           (subreg:QI
1144             (zero_extract:SI
1145               (match_operand 0 "ext_register_operand" "Q")
1146               (const_int 8)
1147               (const_int 8)) 0)
1148           (match_operand:QI 1 "const0_operand" "")))]
1149   "ix86_match_ccmode (insn, CCNOmode)"
1150   "test{b}\t%h0, %h0"
1151   [(set_attr "type" "test")
1152    (set_attr "length_immediate" "0")
1153    (set_attr "mode" "QI")])
1154
1155 (define_expand "cmpqi_ext_3"
1156   [(set (reg:CC FLAGS_REG)
1157         (compare:CC
1158           (subreg:QI
1159             (zero_extract:SI
1160               (match_operand 0 "ext_register_operand" "")
1161               (const_int 8)
1162               (const_int 8)) 0)
1163           (match_operand:QI 1 "general_operand" "")))]
1164   ""
1165   "")
1166
1167 (define_insn "cmpqi_ext_3_insn"
1168   [(set (reg FLAGS_REG)
1169         (compare
1170           (subreg:QI
1171             (zero_extract:SI
1172               (match_operand 0 "ext_register_operand" "Q")
1173               (const_int 8)
1174               (const_int 8)) 0)
1175           (match_operand:QI 1 "general_operand" "Qmn")))]
1176   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1177   "cmp{b}\t{%1, %h0|%h0, %1}"
1178   [(set_attr "type" "icmp")
1179    (set_attr "modrm" "1")
1180    (set_attr "mode" "QI")])
1181
1182 (define_insn "cmpqi_ext_3_insn_rex64"
1183   [(set (reg FLAGS_REG)
1184         (compare
1185           (subreg:QI
1186             (zero_extract:SI
1187               (match_operand 0 "ext_register_operand" "Q")
1188               (const_int 8)
1189               (const_int 8)) 0)
1190           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1191   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1192   "cmp{b}\t{%1, %h0|%h0, %1}"
1193   [(set_attr "type" "icmp")
1194    (set_attr "modrm" "1")
1195    (set_attr "mode" "QI")])
1196
1197 (define_insn "*cmpqi_ext_4"
1198   [(set (reg FLAGS_REG)
1199         (compare
1200           (subreg:QI
1201             (zero_extract:SI
1202               (match_operand 0 "ext_register_operand" "Q")
1203               (const_int 8)
1204               (const_int 8)) 0)
1205           (subreg:QI
1206             (zero_extract:SI
1207               (match_operand 1 "ext_register_operand" "Q")
1208               (const_int 8)
1209               (const_int 8)) 0)))]
1210   "ix86_match_ccmode (insn, CCmode)"
1211   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1212   [(set_attr "type" "icmp")
1213    (set_attr "mode" "QI")])
1214
1215 ;; These implement float point compares.
1216 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1217 ;; which would allow mix and match FP modes on the compares.  Which is what
1218 ;; the old patterns did, but with many more of them.
1219
1220 (define_expand "cbranchxf4"
1221   [(set (reg:CC FLAGS_REG)
1222         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1223                     (match_operand:XF 2 "nonmemory_operand" "")))
1224    (set (pc) (if_then_else
1225               (match_operator 0 "ix86_fp_comparison_operator"
1226                [(reg:CC FLAGS_REG)
1227                 (const_int 0)])
1228               (label_ref (match_operand 3 "" ""))
1229               (pc)))]
1230   "TARGET_80387"
1231 {
1232   ix86_compare_op0 = operands[1];
1233   ix86_compare_op1 = operands[2];
1234   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1235   DONE;
1236 })
1237
1238 (define_expand "cstorexf4"
1239   [(set (reg:CC FLAGS_REG)
1240         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1241                     (match_operand:XF 3 "nonmemory_operand" "")))
1242    (set (match_operand:QI 0 "register_operand" "")
1243               (match_operator 1 "ix86_fp_comparison_operator"
1244                [(reg:CC FLAGS_REG)
1245                 (const_int 0)]))]
1246   "TARGET_80387"
1247 {
1248   ix86_compare_op0 = operands[2];
1249   ix86_compare_op1 = operands[3];
1250   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1251   DONE;
1252 })
1253
1254 (define_expand "cbranch<mode>4"
1255   [(set (reg:CC FLAGS_REG)
1256         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1257                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1258    (set (pc) (if_then_else
1259               (match_operator 0 "ix86_fp_comparison_operator"
1260                [(reg:CC FLAGS_REG)
1261                 (const_int 0)])
1262               (label_ref (match_operand 3 "" ""))
1263               (pc)))]
1264   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1265 {
1266   ix86_compare_op0 = operands[1];
1267   ix86_compare_op1 = operands[2];
1268   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1269   DONE;
1270 })
1271
1272 (define_expand "cstore<mode>4"
1273   [(set (reg:CC FLAGS_REG)
1274         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1275                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1276    (set (match_operand:QI 0 "register_operand" "")
1277               (match_operator 1 "ix86_fp_comparison_operator"
1278                [(reg:CC FLAGS_REG)
1279                 (const_int 0)]))]
1280   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1281 {
1282   ix86_compare_op0 = operands[2];
1283   ix86_compare_op1 = operands[3];
1284   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1285   DONE;
1286 })
1287
1288 (define_expand "cbranchcc4"
1289   [(set (pc) (if_then_else
1290               (match_operator 0 "comparison_operator"
1291                [(match_operand 1 "flags_reg_operand" "")
1292                 (match_operand 2 "const0_operand" "")])
1293               (label_ref (match_operand 3 "" ""))
1294               (pc)))]
1295   ""
1296 {
1297   ix86_compare_op0 = operands[1];
1298   ix86_compare_op1 = operands[2];
1299   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1300   DONE;
1301 })
1302
1303 (define_expand "cstorecc4"
1304   [(set (match_operand:QI 0 "register_operand" "")
1305               (match_operator 1 "comparison_operator"
1306                [(match_operand 2 "flags_reg_operand" "")
1307                 (match_operand 3 "const0_operand" "")]))]
1308   ""
1309 {
1310   ix86_compare_op0 = operands[2];
1311   ix86_compare_op1 = operands[3];
1312   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1313   DONE;
1314 })
1315
1316
1317 ;; FP compares, step 1:
1318 ;; Set the FP condition codes.
1319 ;;
1320 ;; CCFPmode     compare with exceptions
1321 ;; CCFPUmode    compare with no exceptions
1322
1323 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1324 ;; used to manage the reg stack popping would not be preserved.
1325
1326 (define_insn "*cmpfp_0"
1327   [(set (match_operand:HI 0 "register_operand" "=a")
1328         (unspec:HI
1329           [(compare:CCFP
1330              (match_operand 1 "register_operand" "f")
1331              (match_operand 2 "const0_operand" ""))]
1332         UNSPEC_FNSTSW))]
1333   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1334    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1335   "* return output_fp_compare (insn, operands, 0, 0);"
1336   [(set_attr "type" "multi")
1337    (set_attr "unit" "i387")
1338    (set (attr "mode")
1339      (cond [(match_operand:SF 1 "" "")
1340               (const_string "SF")
1341             (match_operand:DF 1 "" "")
1342               (const_string "DF")
1343            ]
1344            (const_string "XF")))])
1345
1346 (define_insn_and_split "*cmpfp_0_cc"
1347   [(set (reg:CCFP FLAGS_REG)
1348         (compare:CCFP
1349           (match_operand 1 "register_operand" "f")
1350           (match_operand 2 "const0_operand" "")))
1351    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1352   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1353    && TARGET_SAHF && !TARGET_CMOVE
1354    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1355   "#"
1356   "&& reload_completed"
1357   [(set (match_dup 0)
1358         (unspec:HI
1359           [(compare:CCFP (match_dup 1)(match_dup 2))]
1360         UNSPEC_FNSTSW))
1361    (set (reg:CC FLAGS_REG)
1362         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363   ""
1364   [(set_attr "type" "multi")
1365    (set_attr "unit" "i387")
1366    (set (attr "mode")
1367      (cond [(match_operand:SF 1 "" "")
1368               (const_string "SF")
1369             (match_operand:DF 1 "" "")
1370               (const_string "DF")
1371            ]
1372            (const_string "XF")))])
1373
1374 (define_insn "*cmpfp_xf"
1375   [(set (match_operand:HI 0 "register_operand" "=a")
1376         (unspec:HI
1377           [(compare:CCFP
1378              (match_operand:XF 1 "register_operand" "f")
1379              (match_operand:XF 2 "register_operand" "f"))]
1380           UNSPEC_FNSTSW))]
1381   "TARGET_80387"
1382   "* return output_fp_compare (insn, operands, 0, 0);"
1383   [(set_attr "type" "multi")
1384    (set_attr "unit" "i387")
1385    (set_attr "mode" "XF")])
1386
1387 (define_insn_and_split "*cmpfp_xf_cc"
1388   [(set (reg:CCFP FLAGS_REG)
1389         (compare:CCFP
1390           (match_operand:XF 1 "register_operand" "f")
1391           (match_operand:XF 2 "register_operand" "f")))
1392    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1393   "TARGET_80387
1394    && TARGET_SAHF && !TARGET_CMOVE"
1395   "#"
1396   "&& reload_completed"
1397   [(set (match_dup 0)
1398         (unspec:HI
1399           [(compare:CCFP (match_dup 1)(match_dup 2))]
1400         UNSPEC_FNSTSW))
1401    (set (reg:CC FLAGS_REG)
1402         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1403   ""
1404   [(set_attr "type" "multi")
1405    (set_attr "unit" "i387")
1406    (set_attr "mode" "XF")])
1407
1408 (define_insn "*cmpfp_<mode>"
1409   [(set (match_operand:HI 0 "register_operand" "=a")
1410         (unspec:HI
1411           [(compare:CCFP
1412              (match_operand:MODEF 1 "register_operand" "f")
1413              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1414           UNSPEC_FNSTSW))]
1415   "TARGET_80387"
1416   "* return output_fp_compare (insn, operands, 0, 0);"
1417   [(set_attr "type" "multi")
1418    (set_attr "unit" "i387")
1419    (set_attr "mode" "<MODE>")])
1420
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422   [(set (reg:CCFP FLAGS_REG)
1423         (compare:CCFP
1424           (match_operand:MODEF 1 "register_operand" "f")
1425           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1426    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1427   "TARGET_80387
1428    && TARGET_SAHF && !TARGET_CMOVE"
1429   "#"
1430   "&& reload_completed"
1431   [(set (match_dup 0)
1432         (unspec:HI
1433           [(compare:CCFP (match_dup 1)(match_dup 2))]
1434         UNSPEC_FNSTSW))
1435    (set (reg:CC FLAGS_REG)
1436         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1437   ""
1438   [(set_attr "type" "multi")
1439    (set_attr "unit" "i387")
1440    (set_attr "mode" "<MODE>")])
1441
1442 (define_insn "*cmpfp_u"
1443   [(set (match_operand:HI 0 "register_operand" "=a")
1444         (unspec:HI
1445           [(compare:CCFPU
1446              (match_operand 1 "register_operand" "f")
1447              (match_operand 2 "register_operand" "f"))]
1448           UNSPEC_FNSTSW))]
1449   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1450    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1451   "* return output_fp_compare (insn, operands, 0, 1);"
1452   [(set_attr "type" "multi")
1453    (set_attr "unit" "i387")
1454    (set (attr "mode")
1455      (cond [(match_operand:SF 1 "" "")
1456               (const_string "SF")
1457             (match_operand:DF 1 "" "")
1458               (const_string "DF")
1459            ]
1460            (const_string "XF")))])
1461
1462 (define_insn_and_split "*cmpfp_u_cc"
1463   [(set (reg:CCFPU FLAGS_REG)
1464         (compare:CCFPU
1465           (match_operand 1 "register_operand" "f")
1466           (match_operand 2 "register_operand" "f")))
1467    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1468   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1469    && TARGET_SAHF && !TARGET_CMOVE
1470    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1471   "#"
1472   "&& reload_completed"
1473   [(set (match_dup 0)
1474         (unspec:HI
1475           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1476         UNSPEC_FNSTSW))
1477    (set (reg:CC FLAGS_REG)
1478         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1479   ""
1480   [(set_attr "type" "multi")
1481    (set_attr "unit" "i387")
1482    (set (attr "mode")
1483      (cond [(match_operand:SF 1 "" "")
1484               (const_string "SF")
1485             (match_operand:DF 1 "" "")
1486               (const_string "DF")
1487            ]
1488            (const_string "XF")))])
1489
1490 (define_insn "*cmpfp_<mode>"
1491   [(set (match_operand:HI 0 "register_operand" "=a")
1492         (unspec:HI
1493           [(compare:CCFP
1494              (match_operand 1 "register_operand" "f")
1495              (match_operator 3 "float_operator"
1496                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1497           UNSPEC_FNSTSW))]
1498   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1499    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1500    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1501   "* return output_fp_compare (insn, operands, 0, 0);"
1502   [(set_attr "type" "multi")
1503    (set_attr "unit" "i387")
1504    (set_attr "fp_int_src" "true")
1505    (set_attr "mode" "<MODE>")])
1506
1507 (define_insn_and_split "*cmpfp_<mode>_cc"
1508   [(set (reg:CCFP FLAGS_REG)
1509         (compare:CCFP
1510           (match_operand 1 "register_operand" "f")
1511           (match_operator 3 "float_operator"
1512             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1513    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1514   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1515    && TARGET_SAHF && !TARGET_CMOVE
1516    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1517    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1518   "#"
1519   "&& reload_completed"
1520   [(set (match_dup 0)
1521         (unspec:HI
1522           [(compare:CCFP
1523              (match_dup 1)
1524              (match_op_dup 3 [(match_dup 2)]))]
1525         UNSPEC_FNSTSW))
1526    (set (reg:CC FLAGS_REG)
1527         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1528   ""
1529   [(set_attr "type" "multi")
1530    (set_attr "unit" "i387")
1531    (set_attr "fp_int_src" "true")
1532    (set_attr "mode" "<MODE>")])
1533
1534 ;; FP compares, step 2
1535 ;; Move the fpsw to ax.
1536
1537 (define_insn "x86_fnstsw_1"
1538   [(set (match_operand:HI 0 "register_operand" "=a")
1539         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1540   "TARGET_80387"
1541   "fnstsw\t%0"
1542   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1543    (set_attr "mode" "SI")
1544    (set_attr "unit" "i387")])
1545
1546 ;; FP compares, step 3
1547 ;; Get ax into flags, general case.
1548
1549 (define_insn "x86_sahf_1"
1550   [(set (reg:CC FLAGS_REG)
1551         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1552                    UNSPEC_SAHF))]
1553   "TARGET_SAHF"
1554 {
1555 #ifdef HAVE_AS_IX86_SAHF
1556   return "sahf";
1557 #else
1558   return ".byte\t0x9e";
1559 #endif
1560 }
1561   [(set_attr "length" "1")
1562    (set_attr "athlon_decode" "vector")
1563    (set_attr "amdfam10_decode" "direct")
1564    (set_attr "mode" "SI")])
1565
1566 ;; Pentium Pro can do steps 1 through 3 in one go.
1567 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1568 (define_insn "*cmpfp_i_mixed"
1569   [(set (reg:CCFP FLAGS_REG)
1570         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1571                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1572   "TARGET_MIX_SSE_I387
1573    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1574    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1575   "* return output_fp_compare (insn, operands, 1, 0);"
1576   [(set_attr "type" "fcmp,ssecomi")
1577    (set_attr "prefix" "orig,maybe_vex")
1578    (set (attr "mode")
1579      (if_then_else (match_operand:SF 1 "" "")
1580         (const_string "SF")
1581         (const_string "DF")))
1582    (set (attr "prefix_rep")
1583         (if_then_else (eq_attr "type" "ssecomi")
1584                       (const_string "0")
1585                       (const_string "*")))
1586    (set (attr "prefix_data16")
1587         (cond [(eq_attr "type" "fcmp")
1588                  (const_string "*")
1589                (eq_attr "mode" "DF")
1590                  (const_string "1")
1591               ]
1592               (const_string "0")))
1593    (set_attr "athlon_decode" "vector")
1594    (set_attr "amdfam10_decode" "direct")])
1595
1596 (define_insn "*cmpfp_i_sse"
1597   [(set (reg:CCFP FLAGS_REG)
1598         (compare:CCFP (match_operand 0 "register_operand" "x")
1599                       (match_operand 1 "nonimmediate_operand" "xm")))]
1600   "TARGET_SSE_MATH
1601    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1602    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1603   "* return output_fp_compare (insn, operands, 1, 0);"
1604   [(set_attr "type" "ssecomi")
1605    (set_attr "prefix" "maybe_vex")
1606    (set (attr "mode")
1607      (if_then_else (match_operand:SF 1 "" "")
1608         (const_string "SF")
1609         (const_string "DF")))
1610    (set_attr "prefix_rep" "0")
1611    (set (attr "prefix_data16")
1612         (if_then_else (eq_attr "mode" "DF")
1613                       (const_string "1")
1614                       (const_string "0")))
1615    (set_attr "athlon_decode" "vector")
1616    (set_attr "amdfam10_decode" "direct")])
1617
1618 (define_insn "*cmpfp_i_i387"
1619   [(set (reg:CCFP FLAGS_REG)
1620         (compare:CCFP (match_operand 0 "register_operand" "f")
1621                       (match_operand 1 "register_operand" "f")))]
1622   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1623    && TARGET_CMOVE
1624    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1625    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1626   "* return output_fp_compare (insn, operands, 1, 0);"
1627   [(set_attr "type" "fcmp")
1628    (set (attr "mode")
1629      (cond [(match_operand:SF 1 "" "")
1630               (const_string "SF")
1631             (match_operand:DF 1 "" "")
1632               (const_string "DF")
1633            ]
1634            (const_string "XF")))
1635    (set_attr "athlon_decode" "vector")
1636    (set_attr "amdfam10_decode" "direct")])
1637
1638 (define_insn "*cmpfp_iu_mixed"
1639   [(set (reg:CCFPU FLAGS_REG)
1640         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1641                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1642   "TARGET_MIX_SSE_I387
1643    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1644    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1645   "* return output_fp_compare (insn, operands, 1, 1);"
1646   [(set_attr "type" "fcmp,ssecomi")
1647    (set_attr "prefix" "orig,maybe_vex")
1648    (set (attr "mode")
1649      (if_then_else (match_operand:SF 1 "" "")
1650         (const_string "SF")
1651         (const_string "DF")))
1652    (set (attr "prefix_rep")
1653         (if_then_else (eq_attr "type" "ssecomi")
1654                       (const_string "0")
1655                       (const_string "*")))
1656    (set (attr "prefix_data16")
1657         (cond [(eq_attr "type" "fcmp")
1658                  (const_string "*")
1659                (eq_attr "mode" "DF")
1660                  (const_string "1")
1661               ]
1662               (const_string "0")))
1663    (set_attr "athlon_decode" "vector")
1664    (set_attr "amdfam10_decode" "direct")])
1665
1666 (define_insn "*cmpfp_iu_sse"
1667   [(set (reg:CCFPU FLAGS_REG)
1668         (compare:CCFPU (match_operand 0 "register_operand" "x")
1669                        (match_operand 1 "nonimmediate_operand" "xm")))]
1670   "TARGET_SSE_MATH
1671    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1672    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1673   "* return output_fp_compare (insn, operands, 1, 1);"
1674   [(set_attr "type" "ssecomi")
1675    (set_attr "prefix" "maybe_vex")
1676    (set (attr "mode")
1677      (if_then_else (match_operand:SF 1 "" "")
1678         (const_string "SF")
1679         (const_string "DF")))
1680    (set_attr "prefix_rep" "0")
1681    (set (attr "prefix_data16")
1682         (if_then_else (eq_attr "mode" "DF")
1683                       (const_string "1")
1684                       (const_string "0")))
1685    (set_attr "athlon_decode" "vector")
1686    (set_attr "amdfam10_decode" "direct")])
1687
1688 (define_insn "*cmpfp_iu_387"
1689   [(set (reg:CCFPU FLAGS_REG)
1690         (compare:CCFPU (match_operand 0 "register_operand" "f")
1691                        (match_operand 1 "register_operand" "f")))]
1692   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1693    && TARGET_CMOVE
1694    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1695    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1696   "* return output_fp_compare (insn, operands, 1, 1);"
1697   [(set_attr "type" "fcmp")
1698    (set (attr "mode")
1699      (cond [(match_operand:SF 1 "" "")
1700               (const_string "SF")
1701             (match_operand:DF 1 "" "")
1702               (const_string "DF")
1703            ]
1704            (const_string "XF")))
1705    (set_attr "athlon_decode" "vector")
1706    (set_attr "amdfam10_decode" "direct")])
1707 \f
1708 ;; Move instructions.
1709
1710 ;; General case of fullword move.
1711
1712 (define_expand "movsi"
1713   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1714         (match_operand:SI 1 "general_operand" ""))]
1715   ""
1716   "ix86_expand_move (SImode, operands); DONE;")
1717
1718 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1719 ;; general_operand.
1720 ;;
1721 ;; %%% We don't use a post-inc memory reference because x86 is not a
1722 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1723 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1724 ;; targets without our curiosities, and it is just as easy to represent
1725 ;; this differently.
1726
1727 (define_insn "*pushsi2"
1728   [(set (match_operand:SI 0 "push_operand" "=<")
1729         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1730   "!TARGET_64BIT"
1731   "push{l}\t%1"
1732   [(set_attr "type" "push")
1733    (set_attr "mode" "SI")])
1734
1735 ;; For 64BIT abi we always round up to 8 bytes.
1736 (define_insn "*pushsi2_rex64"
1737   [(set (match_operand:SI 0 "push_operand" "=X")
1738         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1739   "TARGET_64BIT"
1740   "push{q}\t%q1"
1741   [(set_attr "type" "push")
1742    (set_attr "mode" "SI")])
1743
1744 (define_insn "*pushsi2_prologue"
1745   [(set (match_operand:SI 0 "push_operand" "=<")
1746         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1747    (clobber (mem:BLK (scratch)))]
1748   "!TARGET_64BIT"
1749   "push{l}\t%1"
1750   [(set_attr "type" "push")
1751    (set_attr "mode" "SI")])
1752
1753 (define_insn "*popsi1_epilogue"
1754   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1755         (mem:SI (reg:SI SP_REG)))
1756    (set (reg:SI SP_REG)
1757         (plus:SI (reg:SI SP_REG) (const_int 4)))
1758    (clobber (mem:BLK (scratch)))]
1759   "!TARGET_64BIT"
1760   "pop{l}\t%0"
1761   [(set_attr "type" "pop")
1762    (set_attr "mode" "SI")])
1763
1764 (define_insn "popsi1"
1765   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1766         (mem:SI (reg:SI SP_REG)))
1767    (set (reg:SI SP_REG)
1768         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1769   "!TARGET_64BIT"
1770   "pop{l}\t%0"
1771   [(set_attr "type" "pop")
1772    (set_attr "mode" "SI")])
1773
1774 (define_insn "*movsi_xor"
1775   [(set (match_operand:SI 0 "register_operand" "=r")
1776         (match_operand:SI 1 "const0_operand" ""))
1777    (clobber (reg:CC FLAGS_REG))]
1778   "reload_completed"
1779   "xor{l}\t%0, %0"
1780   [(set_attr "type" "alu1")
1781    (set_attr "mode" "SI")
1782    (set_attr "length_immediate" "0")])
1783
1784 (define_insn "*movsi_or"
1785   [(set (match_operand:SI 0 "register_operand" "=r")
1786         (match_operand:SI 1 "immediate_operand" "i"))
1787    (clobber (reg:CC FLAGS_REG))]
1788   "reload_completed
1789    && operands[1] == constm1_rtx"
1790 {
1791   operands[1] = constm1_rtx;
1792   return "or{l}\t{%1, %0|%0, %1}";
1793 }
1794   [(set_attr "type" "alu1")
1795    (set_attr "mode" "SI")
1796    (set_attr "length_immediate" "1")])
1797
1798 (define_insn "*movsi_1"
1799   [(set (match_operand:SI 0 "nonimmediate_operand"
1800                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1801         (match_operand:SI 1 "general_operand"
1802                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1803   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1804 {
1805   switch (get_attr_type (insn))
1806     {
1807     case TYPE_SSELOG1:
1808       if (get_attr_mode (insn) == MODE_TI)
1809         return "%vpxor\t%0, %d0";
1810       return "%vxorps\t%0, %d0";
1811
1812     case TYPE_SSEMOV:
1813       switch (get_attr_mode (insn))
1814         {
1815         case MODE_TI:
1816           return "%vmovdqa\t{%1, %0|%0, %1}";
1817         case MODE_V4SF:
1818           return "%vmovaps\t{%1, %0|%0, %1}";
1819         case MODE_SI:
1820           return "%vmovd\t{%1, %0|%0, %1}";
1821         case MODE_SF:
1822           return "%vmovss\t{%1, %0|%0, %1}";
1823         default:
1824           gcc_unreachable ();
1825         }
1826
1827     case TYPE_MMX:
1828       return "pxor\t%0, %0";
1829
1830     case TYPE_MMXMOV:
1831       if (get_attr_mode (insn) == MODE_DI)
1832         return "movq\t{%1, %0|%0, %1}";
1833       return "movd\t{%1, %0|%0, %1}";
1834
1835     case TYPE_LEA:
1836       return "lea{l}\t{%1, %0|%0, %1}";
1837
1838     default:
1839       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1840       return "mov{l}\t{%1, %0|%0, %1}";
1841     }
1842 }
1843   [(set (attr "type")
1844      (cond [(eq_attr "alternative" "2")
1845               (const_string "mmx")
1846             (eq_attr "alternative" "3,4,5")
1847               (const_string "mmxmov")
1848             (eq_attr "alternative" "6")
1849               (const_string "sselog1")
1850             (eq_attr "alternative" "7,8,9,10,11")
1851               (const_string "ssemov")
1852             (match_operand:DI 1 "pic_32bit_operand" "")
1853               (const_string "lea")
1854            ]
1855            (const_string "imov")))
1856    (set (attr "prefix")
1857      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1858        (const_string "orig")
1859        (const_string "maybe_vex")))
1860    (set (attr "prefix_data16")
1861      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1862        (const_string "1")
1863        (const_string "*")))
1864    (set (attr "mode")
1865      (cond [(eq_attr "alternative" "2,3")
1866               (const_string "DI")
1867             (eq_attr "alternative" "6,7")
1868               (if_then_else
1869                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1870                 (const_string "V4SF")
1871                 (const_string "TI"))
1872             (and (eq_attr "alternative" "8,9,10,11")
1873                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1874               (const_string "SF")
1875            ]
1876            (const_string "SI")))])
1877
1878 ;; Stores and loads of ax to arbitrary constant address.
1879 ;; We fake an second form of instruction to force reload to load address
1880 ;; into register when rax is not available
1881 (define_insn "*movabssi_1_rex64"
1882   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1883         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1884   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1885   "@
1886    movabs{l}\t{%1, %P0|%P0, %1}
1887    mov{l}\t{%1, %a0|%a0, %1}"
1888   [(set_attr "type" "imov")
1889    (set_attr "modrm" "0,*")
1890    (set_attr "length_address" "8,0")
1891    (set_attr "length_immediate" "0,*")
1892    (set_attr "memory" "store")
1893    (set_attr "mode" "SI")])
1894
1895 (define_insn "*movabssi_2_rex64"
1896   [(set (match_operand:SI 0 "register_operand" "=a,r")
1897         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1898   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1899   "@
1900    movabs{l}\t{%P1, %0|%0, %P1}
1901    mov{l}\t{%a1, %0|%0, %a1}"
1902   [(set_attr "type" "imov")
1903    (set_attr "modrm" "0,*")
1904    (set_attr "length_address" "8,0")
1905    (set_attr "length_immediate" "0")
1906    (set_attr "memory" "load")
1907    (set_attr "mode" "SI")])
1908
1909 (define_insn "*swapsi"
1910   [(set (match_operand:SI 0 "register_operand" "+r")
1911         (match_operand:SI 1 "register_operand" "+r"))
1912    (set (match_dup 1)
1913         (match_dup 0))]
1914   ""
1915   "xchg{l}\t%1, %0"
1916   [(set_attr "type" "imov")
1917    (set_attr "mode" "SI")
1918    (set_attr "pent_pair" "np")
1919    (set_attr "athlon_decode" "vector")
1920    (set_attr "amdfam10_decode" "double")])
1921
1922 (define_expand "movhi"
1923   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1924         (match_operand:HI 1 "general_operand" ""))]
1925   ""
1926   "ix86_expand_move (HImode, operands); DONE;")
1927
1928 (define_insn "*pushhi2"
1929   [(set (match_operand:HI 0 "push_operand" "=X")
1930         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1931   "!TARGET_64BIT"
1932   "push{l}\t%k1"
1933   [(set_attr "type" "push")
1934    (set_attr "mode" "SI")])
1935
1936 ;; For 64BIT abi we always round up to 8 bytes.
1937 (define_insn "*pushhi2_rex64"
1938   [(set (match_operand:HI 0 "push_operand" "=X")
1939         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1940   "TARGET_64BIT"
1941   "push{q}\t%q1"
1942   [(set_attr "type" "push")
1943    (set_attr "mode" "DI")])
1944
1945 (define_insn "*movhi_1"
1946   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1947         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1948   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1949 {
1950   switch (get_attr_type (insn))
1951     {
1952     case TYPE_IMOVX:
1953       /* movzwl is faster than movw on p2 due to partial word stalls,
1954          though not as fast as an aligned movl.  */
1955       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1956     default:
1957       if (get_attr_mode (insn) == MODE_SI)
1958         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1959       else
1960         return "mov{w}\t{%1, %0|%0, %1}";
1961     }
1962 }
1963   [(set (attr "type")
1964      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1965               (const_string "imov")
1966             (and (eq_attr "alternative" "0")
1967                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1968                           (const_int 0))
1969                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1970                           (const_int 0))))
1971               (const_string "imov")
1972             (and (eq_attr "alternative" "1,2")
1973                  (match_operand:HI 1 "aligned_operand" ""))
1974               (const_string "imov")
1975             (and (ne (symbol_ref "TARGET_MOVX")
1976                      (const_int 0))
1977                  (eq_attr "alternative" "0,2"))
1978               (const_string "imovx")
1979            ]
1980            (const_string "imov")))
1981     (set (attr "mode")
1982       (cond [(eq_attr "type" "imovx")
1983                (const_string "SI")
1984              (and (eq_attr "alternative" "1,2")
1985                   (match_operand:HI 1 "aligned_operand" ""))
1986                (const_string "SI")
1987              (and (eq_attr "alternative" "0")
1988                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1989                            (const_int 0))
1990                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1991                            (const_int 0))))
1992                (const_string "SI")
1993             ]
1994             (const_string "HI")))])
1995
1996 ;; Stores and loads of ax to arbitrary constant address.
1997 ;; We fake an second form of instruction to force reload to load address
1998 ;; into register when rax is not available
1999 (define_insn "*movabshi_1_rex64"
2000   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2001         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2002   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2003   "@
2004    movabs{w}\t{%1, %P0|%P0, %1}
2005    mov{w}\t{%1, %a0|%a0, %1}"
2006   [(set_attr "type" "imov")
2007    (set_attr "modrm" "0,*")
2008    (set_attr "length_address" "8,0")
2009    (set_attr "length_immediate" "0,*")
2010    (set_attr "memory" "store")
2011    (set_attr "mode" "HI")])
2012
2013 (define_insn "*movabshi_2_rex64"
2014   [(set (match_operand:HI 0 "register_operand" "=a,r")
2015         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2016   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2017   "@
2018    movabs{w}\t{%P1, %0|%0, %P1}
2019    mov{w}\t{%a1, %0|%0, %a1}"
2020   [(set_attr "type" "imov")
2021    (set_attr "modrm" "0,*")
2022    (set_attr "length_address" "8,0")
2023    (set_attr "length_immediate" "0")
2024    (set_attr "memory" "load")
2025    (set_attr "mode" "HI")])
2026
2027 (define_insn "*swaphi_1"
2028   [(set (match_operand:HI 0 "register_operand" "+r")
2029         (match_operand:HI 1 "register_operand" "+r"))
2030    (set (match_dup 1)
2031         (match_dup 0))]
2032   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2033   "xchg{l}\t%k1, %k0"
2034   [(set_attr "type" "imov")
2035    (set_attr "mode" "SI")
2036    (set_attr "pent_pair" "np")
2037    (set_attr "athlon_decode" "vector")
2038    (set_attr "amdfam10_decode" "double")])
2039
2040 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2041 (define_insn "*swaphi_2"
2042   [(set (match_operand:HI 0 "register_operand" "+r")
2043         (match_operand:HI 1 "register_operand" "+r"))
2044    (set (match_dup 1)
2045         (match_dup 0))]
2046   "TARGET_PARTIAL_REG_STALL"
2047   "xchg{w}\t%1, %0"
2048   [(set_attr "type" "imov")
2049    (set_attr "mode" "HI")
2050    (set_attr "pent_pair" "np")
2051    (set_attr "athlon_decode" "vector")])
2052
2053 (define_expand "movstricthi"
2054   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2055         (match_operand:HI 1 "general_operand" ""))]
2056   ""
2057 {
2058   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2059     FAIL;
2060   /* Don't generate memory->memory moves, go through a register */
2061   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2062     operands[1] = force_reg (HImode, operands[1]);
2063 })
2064
2065 (define_insn "*movstricthi_1"
2066   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2067         (match_operand:HI 1 "general_operand" "rn,m"))]
2068   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2069    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2070   "mov{w}\t{%1, %0|%0, %1}"
2071   [(set_attr "type" "imov")
2072    (set_attr "mode" "HI")])
2073
2074 (define_insn "*movstricthi_xor"
2075   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2076         (match_operand:HI 1 "const0_operand" ""))
2077    (clobber (reg:CC FLAGS_REG))]
2078   "reload_completed"
2079   "xor{w}\t%0, %0"
2080   [(set_attr "type" "alu1")
2081    (set_attr "mode" "HI")
2082    (set_attr "length_immediate" "0")])
2083
2084 (define_expand "movqi"
2085   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2086         (match_operand:QI 1 "general_operand" ""))]
2087   ""
2088   "ix86_expand_move (QImode, operands); DONE;")
2089
2090 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2091 ;; "push a byte".  But actually we use pushl, which has the effect
2092 ;; of rounding the amount pushed up to a word.
2093
2094 (define_insn "*pushqi2"
2095   [(set (match_operand:QI 0 "push_operand" "=X")
2096         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2097   "!TARGET_64BIT"
2098   "push{l}\t%k1"
2099   [(set_attr "type" "push")
2100    (set_attr "mode" "SI")])
2101
2102 ;; For 64BIT abi we always round up to 8 bytes.
2103 (define_insn "*pushqi2_rex64"
2104   [(set (match_operand:QI 0 "push_operand" "=X")
2105         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2106   "TARGET_64BIT"
2107   "push{q}\t%q1"
2108   [(set_attr "type" "push")
2109    (set_attr "mode" "DI")])
2110
2111 ;; Situation is quite tricky about when to choose full sized (SImode) move
2112 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2113 ;; partial register dependency machines (such as AMD Athlon), where QImode
2114 ;; moves issue extra dependency and for partial register stalls machines
2115 ;; that don't use QImode patterns (and QImode move cause stall on the next
2116 ;; instruction).
2117 ;;
2118 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2119 ;; register stall machines with, where we use QImode instructions, since
2120 ;; partial register stall can be caused there.  Then we use movzx.
2121 (define_insn "*movqi_1"
2122   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2123         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2124   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2125 {
2126   switch (get_attr_type (insn))
2127     {
2128     case TYPE_IMOVX:
2129       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2130       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2131     default:
2132       if (get_attr_mode (insn) == MODE_SI)
2133         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2134       else
2135         return "mov{b}\t{%1, %0|%0, %1}";
2136     }
2137 }
2138   [(set (attr "type")
2139      (cond [(and (eq_attr "alternative" "5")
2140                  (not (match_operand:QI 1 "aligned_operand" "")))
2141               (const_string "imovx")
2142             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2143               (const_string "imov")
2144             (and (eq_attr "alternative" "3")
2145                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2146                           (const_int 0))
2147                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2148                           (const_int 0))))
2149               (const_string "imov")
2150             (eq_attr "alternative" "3,5")
2151               (const_string "imovx")
2152             (and (ne (symbol_ref "TARGET_MOVX")
2153                      (const_int 0))
2154                  (eq_attr "alternative" "2"))
2155               (const_string "imovx")
2156            ]
2157            (const_string "imov")))
2158    (set (attr "mode")
2159       (cond [(eq_attr "alternative" "3,4,5")
2160                (const_string "SI")
2161              (eq_attr "alternative" "6")
2162                (const_string "QI")
2163              (eq_attr "type" "imovx")
2164                (const_string "SI")
2165              (and (eq_attr "type" "imov")
2166                   (and (eq_attr "alternative" "0,1")
2167                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2168                                 (const_int 0))
2169                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2170                                      (const_int 0))
2171                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2172                                      (const_int 0))))))
2173                (const_string "SI")
2174              ;; Avoid partial register stalls when not using QImode arithmetic
2175              (and (eq_attr "type" "imov")
2176                   (and (eq_attr "alternative" "0,1")
2177                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2178                                 (const_int 0))
2179                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2180                                 (const_int 0)))))
2181                (const_string "SI")
2182            ]
2183            (const_string "QI")))])
2184
2185 (define_insn "*swapqi_1"
2186   [(set (match_operand:QI 0 "register_operand" "+r")
2187         (match_operand:QI 1 "register_operand" "+r"))
2188    (set (match_dup 1)
2189         (match_dup 0))]
2190   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2191   "xchg{l}\t%k1, %k0"
2192   [(set_attr "type" "imov")
2193    (set_attr "mode" "SI")
2194    (set_attr "pent_pair" "np")
2195    (set_attr "athlon_decode" "vector")
2196    (set_attr "amdfam10_decode" "vector")])
2197
2198 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2199 (define_insn "*swapqi_2"
2200   [(set (match_operand:QI 0 "register_operand" "+q")
2201         (match_operand:QI 1 "register_operand" "+q"))
2202    (set (match_dup 1)
2203         (match_dup 0))]
2204   "TARGET_PARTIAL_REG_STALL"
2205   "xchg{b}\t%1, %0"
2206   [(set_attr "type" "imov")
2207    (set_attr "mode" "QI")
2208    (set_attr "pent_pair" "np")
2209    (set_attr "athlon_decode" "vector")])
2210
2211 (define_expand "movstrictqi"
2212   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2213         (match_operand:QI 1 "general_operand" ""))]
2214   ""
2215 {
2216   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2217     FAIL;
2218   /* Don't generate memory->memory moves, go through a register.  */
2219   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2220     operands[1] = force_reg (QImode, operands[1]);
2221 })
2222
2223 (define_insn "*movstrictqi_1"
2224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2225         (match_operand:QI 1 "general_operand" "*qn,m"))]
2226   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2228   "mov{b}\t{%1, %0|%0, %1}"
2229   [(set_attr "type" "imov")
2230    (set_attr "mode" "QI")])
2231
2232 (define_insn "*movstrictqi_xor"
2233   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2234         (match_operand:QI 1 "const0_operand" ""))
2235    (clobber (reg:CC FLAGS_REG))]
2236   "reload_completed"
2237   "xor{b}\t%0, %0"
2238   [(set_attr "type" "alu1")
2239    (set_attr "mode" "QI")
2240    (set_attr "length_immediate" "0")])
2241
2242 (define_insn "*movsi_extv_1"
2243   [(set (match_operand:SI 0 "register_operand" "=R")
2244         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2245                          (const_int 8)
2246                          (const_int 8)))]
2247   ""
2248   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2249   [(set_attr "type" "imovx")
2250    (set_attr "mode" "SI")])
2251
2252 (define_insn "*movhi_extv_1"
2253   [(set (match_operand:HI 0 "register_operand" "=R")
2254         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2255                          (const_int 8)
2256                          (const_int 8)))]
2257   ""
2258   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2259   [(set_attr "type" "imovx")
2260    (set_attr "mode" "SI")])
2261
2262 (define_insn "*movqi_extv_1"
2263   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2264         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2265                          (const_int 8)
2266                          (const_int 8)))]
2267   "!TARGET_64BIT"
2268 {
2269   switch (get_attr_type (insn))
2270     {
2271     case TYPE_IMOVX:
2272       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2273     default:
2274       return "mov{b}\t{%h1, %0|%0, %h1}";
2275     }
2276 }
2277   [(set (attr "type")
2278      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2279                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2280                              (ne (symbol_ref "TARGET_MOVX")
2281                                  (const_int 0))))
2282         (const_string "imovx")
2283         (const_string "imov")))
2284    (set (attr "mode")
2285      (if_then_else (eq_attr "type" "imovx")
2286         (const_string "SI")
2287         (const_string "QI")))])
2288
2289 (define_insn "*movqi_extv_1_rex64"
2290   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2291         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2292                          (const_int 8)
2293                          (const_int 8)))]
2294   "TARGET_64BIT"
2295 {
2296   switch (get_attr_type (insn))
2297     {
2298     case TYPE_IMOVX:
2299       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2300     default:
2301       return "mov{b}\t{%h1, %0|%0, %h1}";
2302     }
2303 }
2304   [(set (attr "type")
2305      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2306                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2307                              (ne (symbol_ref "TARGET_MOVX")
2308                                  (const_int 0))))
2309         (const_string "imovx")
2310         (const_string "imov")))
2311    (set (attr "mode")
2312      (if_then_else (eq_attr "type" "imovx")
2313         (const_string "SI")
2314         (const_string "QI")))])
2315
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsqi_1_rex64"
2320   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2322   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2323   "@
2324    movabs{b}\t{%1, %P0|%P0, %1}
2325    mov{b}\t{%1, %a0|%a0, %1}"
2326   [(set_attr "type" "imov")
2327    (set_attr "modrm" "0,*")
2328    (set_attr "length_address" "8,0")
2329    (set_attr "length_immediate" "0,*")
2330    (set_attr "memory" "store")
2331    (set_attr "mode" "QI")])
2332
2333 (define_insn "*movabsqi_2_rex64"
2334   [(set (match_operand:QI 0 "register_operand" "=a,r")
2335         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2337   "@
2338    movabs{b}\t{%P1, %0|%0, %P1}
2339    mov{b}\t{%a1, %0|%0, %a1}"
2340   [(set_attr "type" "imov")
2341    (set_attr "modrm" "0,*")
2342    (set_attr "length_address" "8,0")
2343    (set_attr "length_immediate" "0")
2344    (set_attr "memory" "load")
2345    (set_attr "mode" "QI")])
2346
2347 (define_insn "*movdi_extzv_1"
2348   [(set (match_operand:DI 0 "register_operand" "=R")
2349         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2350                          (const_int 8)
2351                          (const_int 8)))]
2352   "TARGET_64BIT"
2353   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2354   [(set_attr "type" "imovx")
2355    (set_attr "mode" "SI")])
2356
2357 (define_insn "*movsi_extzv_1"
2358   [(set (match_operand:SI 0 "register_operand" "=R")
2359         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2360                          (const_int 8)
2361                          (const_int 8)))]
2362   ""
2363   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2364   [(set_attr "type" "imovx")
2365    (set_attr "mode" "SI")])
2366
2367 (define_insn "*movqi_extzv_2"
2368   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2369         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2370                                     (const_int 8)
2371                                     (const_int 8)) 0))]
2372   "!TARGET_64BIT"
2373 {
2374   switch (get_attr_type (insn))
2375     {
2376     case TYPE_IMOVX:
2377       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2378     default:
2379       return "mov{b}\t{%h1, %0|%0, %h1}";
2380     }
2381 }
2382   [(set (attr "type")
2383      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2384                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2385                              (ne (symbol_ref "TARGET_MOVX")
2386                                  (const_int 0))))
2387         (const_string "imovx")
2388         (const_string "imov")))
2389    (set (attr "mode")
2390      (if_then_else (eq_attr "type" "imovx")
2391         (const_string "SI")
2392         (const_string "QI")))])
2393
2394 (define_insn "*movqi_extzv_2_rex64"
2395   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2396         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2397                                     (const_int 8)
2398                                     (const_int 8)) 0))]
2399   "TARGET_64BIT"
2400 {
2401   switch (get_attr_type (insn))
2402     {
2403     case TYPE_IMOVX:
2404       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2405     default:
2406       return "mov{b}\t{%h1, %0|%0, %h1}";
2407     }
2408 }
2409   [(set (attr "type")
2410      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2411                         (ne (symbol_ref "TARGET_MOVX")
2412                             (const_int 0)))
2413         (const_string "imovx")
2414         (const_string "imov")))
2415    (set (attr "mode")
2416      (if_then_else (eq_attr "type" "imovx")
2417         (const_string "SI")
2418         (const_string "QI")))])
2419
2420 (define_insn "movsi_insv_1"
2421   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2422                          (const_int 8)
2423                          (const_int 8))
2424         (match_operand:SI 1 "general_operand" "Qmn"))]
2425   "!TARGET_64BIT"
2426   "mov{b}\t{%b1, %h0|%h0, %b1}"
2427   [(set_attr "type" "imov")
2428    (set_attr "mode" "QI")])
2429
2430 (define_insn "*movsi_insv_1_rex64"
2431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2432                          (const_int 8)
2433                          (const_int 8))
2434         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2435   "TARGET_64BIT"
2436   "mov{b}\t{%b1, %h0|%h0, %b1}"
2437   [(set_attr "type" "imov")
2438    (set_attr "mode" "QI")])
2439
2440 (define_insn "movdi_insv_1_rex64"
2441   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2442                          (const_int 8)
2443                          (const_int 8))
2444         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2445   "TARGET_64BIT"
2446   "mov{b}\t{%b1, %h0|%h0, %b1}"
2447   [(set_attr "type" "imov")
2448    (set_attr "mode" "QI")])
2449
2450 (define_insn "*movqi_insv_2"
2451   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2452                          (const_int 8)
2453                          (const_int 8))
2454         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2455                      (const_int 8)))]
2456   ""
2457   "mov{b}\t{%h1, %h0|%h0, %h1}"
2458   [(set_attr "type" "imov")
2459    (set_attr "mode" "QI")])
2460
2461 (define_expand "movdi"
2462   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2463         (match_operand:DI 1 "general_operand" ""))]
2464   ""
2465   "ix86_expand_move (DImode, operands); DONE;")
2466
2467 (define_insn "*pushdi"
2468   [(set (match_operand:DI 0 "push_operand" "=<")
2469         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2470   "!TARGET_64BIT"
2471   "#")
2472
2473 (define_insn "*pushdi2_rex64"
2474   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2475         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2476   "TARGET_64BIT"
2477   "@
2478    push{q}\t%1
2479    #"
2480   [(set_attr "type" "push,multi")
2481    (set_attr "mode" "DI")])
2482
2483 ;; Convert impossible pushes of immediate to existing instructions.
2484 ;; First try to get scratch register and go through it.  In case this
2485 ;; fails, push sign extended lower part first and then overwrite
2486 ;; upper part by 32bit move.
2487 (define_peephole2
2488   [(match_scratch:DI 2 "r")
2489    (set (match_operand:DI 0 "push_operand" "")
2490         (match_operand:DI 1 "immediate_operand" ""))]
2491   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2492    && !x86_64_immediate_operand (operands[1], DImode)"
2493   [(set (match_dup 2) (match_dup 1))
2494    (set (match_dup 0) (match_dup 2))]
2495   "")
2496
2497 ;; We need to define this as both peepholer and splitter for case
2498 ;; peephole2 pass is not run.
2499 ;; "&& 1" is needed to keep it from matching the previous pattern.
2500 (define_peephole2
2501   [(set (match_operand:DI 0 "push_operand" "")
2502         (match_operand:DI 1 "immediate_operand" ""))]
2503   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2504    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2505   [(set (match_dup 0) (match_dup 1))
2506    (set (match_dup 2) (match_dup 3))]
2507   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2508    operands[1] = gen_lowpart (DImode, operands[2]);
2509    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2510                                                     GEN_INT (4)));
2511   ")
2512
2513 (define_split
2514   [(set (match_operand:DI 0 "push_operand" "")
2515         (match_operand:DI 1 "immediate_operand" ""))]
2516   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2517                     ? epilogue_completed : reload_completed)
2518    && !symbolic_operand (operands[1], DImode)
2519    && !x86_64_immediate_operand (operands[1], DImode)"
2520   [(set (match_dup 0) (match_dup 1))
2521    (set (match_dup 2) (match_dup 3))]
2522   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2523    operands[1] = gen_lowpart (DImode, operands[2]);
2524    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2525                                                     GEN_INT (4)));
2526   ")
2527
2528 (define_insn "*pushdi2_prologue_rex64"
2529   [(set (match_operand:DI 0 "push_operand" "=<")
2530         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2531    (clobber (mem:BLK (scratch)))]
2532   "TARGET_64BIT"
2533   "push{q}\t%1"
2534   [(set_attr "type" "push")
2535    (set_attr "mode" "DI")])
2536
2537 (define_insn "*popdi1_epilogue_rex64"
2538   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2539         (mem:DI (reg:DI SP_REG)))
2540    (set (reg:DI SP_REG)
2541         (plus:DI (reg:DI SP_REG) (const_int 8)))
2542    (clobber (mem:BLK (scratch)))]
2543   "TARGET_64BIT"
2544   "pop{q}\t%0"
2545   [(set_attr "type" "pop")
2546    (set_attr "mode" "DI")])
2547
2548 (define_insn "popdi1"
2549   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2550         (mem:DI (reg:DI SP_REG)))
2551    (set (reg:DI SP_REG)
2552         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2553   "TARGET_64BIT"
2554   "pop{q}\t%0"
2555   [(set_attr "type" "pop")
2556    (set_attr "mode" "DI")])
2557
2558 (define_insn "*movdi_xor_rex64"
2559   [(set (match_operand:DI 0 "register_operand" "=r")
2560         (match_operand:DI 1 "const0_operand" ""))
2561    (clobber (reg:CC FLAGS_REG))]
2562   "TARGET_64BIT
2563    && reload_completed"
2564   "xor{l}\t%k0, %k0";
2565   [(set_attr "type" "alu1")
2566    (set_attr "mode" "SI")
2567    (set_attr "length_immediate" "0")])
2568
2569 (define_insn "*movdi_or_rex64"
2570   [(set (match_operand:DI 0 "register_operand" "=r")
2571         (match_operand:DI 1 "const_int_operand" "i"))
2572    (clobber (reg:CC FLAGS_REG))]
2573   "TARGET_64BIT
2574    && reload_completed
2575    && operands[1] == constm1_rtx"
2576 {
2577   operands[1] = constm1_rtx;
2578   return "or{q}\t{%1, %0|%0, %1}";
2579 }
2580   [(set_attr "type" "alu1")
2581    (set_attr "mode" "DI")
2582    (set_attr "length_immediate" "1")])
2583
2584 (define_insn "*movdi_2"
2585   [(set (match_operand:DI 0 "nonimmediate_operand"
2586                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2587         (match_operand:DI 1 "general_operand"
2588                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2589   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2590   "@
2591    #
2592    #
2593    pxor\t%0, %0
2594    movq\t{%1, %0|%0, %1}
2595    movq\t{%1, %0|%0, %1}
2596    %vpxor\t%0, %d0
2597    %vmovq\t{%1, %0|%0, %1}
2598    %vmovdqa\t{%1, %0|%0, %1}
2599    %vmovq\t{%1, %0|%0, %1}
2600    xorps\t%0, %0
2601    movlps\t{%1, %0|%0, %1}
2602    movaps\t{%1, %0|%0, %1}
2603    movlps\t{%1, %0|%0, %1}"
2604   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2605    (set (attr "prefix")
2606      (if_then_else (eq_attr "alternative" "5,6,7,8")
2607        (const_string "vex")
2608        (const_string "orig")))
2609    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2610
2611 (define_split
2612   [(set (match_operand:DI 0 "push_operand" "")
2613         (match_operand:DI 1 "general_operand" ""))]
2614   "!TARGET_64BIT && reload_completed
2615    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2616   [(const_int 0)]
2617   "ix86_split_long_move (operands); DONE;")
2618
2619 ;; %%% This multiword shite has got to go.
2620 (define_split
2621   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2622         (match_operand:DI 1 "general_operand" ""))]
2623   "!TARGET_64BIT && reload_completed
2624    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2625    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2626   [(const_int 0)]
2627   "ix86_split_long_move (operands); DONE;")
2628
2629 (define_insn "*movdi_1_rex64"
2630   [(set (match_operand:DI 0 "nonimmediate_operand"
2631           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2632         (match_operand:DI 1 "general_operand"
2633           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2634   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2635 {
2636   switch (get_attr_type (insn))
2637     {
2638     case TYPE_SSECVT:
2639       if (SSE_REG_P (operands[0]))
2640         return "movq2dq\t{%1, %0|%0, %1}";
2641       else
2642         return "movdq2q\t{%1, %0|%0, %1}";
2643
2644     case TYPE_SSEMOV:
2645       if (TARGET_AVX)
2646         {
2647           if (get_attr_mode (insn) == MODE_TI)
2648             return "vmovdqa\t{%1, %0|%0, %1}";
2649           else
2650             return "vmovq\t{%1, %0|%0, %1}";
2651         }
2652
2653       if (get_attr_mode (insn) == MODE_TI)
2654         return "movdqa\t{%1, %0|%0, %1}";
2655       /* FALLTHRU */
2656
2657     case TYPE_MMXMOV:
2658       /* Moves from and into integer register is done using movd
2659          opcode with REX prefix.  */
2660       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2661         return "movd\t{%1, %0|%0, %1}";
2662       return "movq\t{%1, %0|%0, %1}";
2663
2664     case TYPE_SSELOG1:
2665       return "%vpxor\t%0, %d0";
2666
2667     case TYPE_MMX:
2668       return "pxor\t%0, %0";
2669
2670     case TYPE_MULTI:
2671       return "#";
2672
2673     case TYPE_LEA:
2674       return "lea{q}\t{%a1, %0|%0, %a1}";
2675
2676     default:
2677       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2678       if (get_attr_mode (insn) == MODE_SI)
2679         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2680       else if (which_alternative == 2)
2681         return "movabs{q}\t{%1, %0|%0, %1}";
2682       else
2683         return "mov{q}\t{%1, %0|%0, %1}";
2684     }
2685 }
2686   [(set (attr "type")
2687      (cond [(eq_attr "alternative" "5")
2688               (const_string "mmx")
2689             (eq_attr "alternative" "6,7,8,9,10")
2690               (const_string "mmxmov")
2691             (eq_attr "alternative" "11")
2692               (const_string "sselog1")
2693             (eq_attr "alternative" "12,13,14,15,16")
2694               (const_string "ssemov")
2695             (eq_attr "alternative" "17,18")
2696               (const_string "ssecvt")
2697             (eq_attr "alternative" "4")
2698               (const_string "multi")
2699             (match_operand:DI 1 "pic_32bit_operand" "")
2700               (const_string "lea")
2701            ]
2702            (const_string "imov")))
2703    (set (attr "modrm")
2704      (if_then_else
2705        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2706          (const_string "0")
2707          (const_string "*")))
2708    (set (attr "length_immediate")
2709      (if_then_else
2710        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2711          (const_string "8")
2712          (const_string "*")))
2713    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2714    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2715    (set (attr "prefix")
2716      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2717        (const_string "maybe_vex")
2718        (const_string "orig")))
2719    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2720
2721 ;; Stores and loads of ax to arbitrary constant address.
2722 ;; We fake an second form of instruction to force reload to load address
2723 ;; into register when rax is not available
2724 (define_insn "*movabsdi_1_rex64"
2725   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2726         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2727   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2728   "@
2729    movabs{q}\t{%1, %P0|%P0, %1}
2730    mov{q}\t{%1, %a0|%a0, %1}"
2731   [(set_attr "type" "imov")
2732    (set_attr "modrm" "0,*")
2733    (set_attr "length_address" "8,0")
2734    (set_attr "length_immediate" "0,*")
2735    (set_attr "memory" "store")
2736    (set_attr "mode" "DI")])
2737
2738 (define_insn "*movabsdi_2_rex64"
2739   [(set (match_operand:DI 0 "register_operand" "=a,r")
2740         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2741   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2742   "@
2743    movabs{q}\t{%P1, %0|%0, %P1}
2744    mov{q}\t{%a1, %0|%0, %a1}"
2745   [(set_attr "type" "imov")
2746    (set_attr "modrm" "0,*")
2747    (set_attr "length_address" "8,0")
2748    (set_attr "length_immediate" "0")
2749    (set_attr "memory" "load")
2750    (set_attr "mode" "DI")])
2751
2752 ;; Convert impossible stores of immediate to existing instructions.
2753 ;; First try to get scratch register and go through it.  In case this
2754 ;; fails, move by 32bit parts.
2755 (define_peephole2
2756   [(match_scratch:DI 2 "r")
2757    (set (match_operand:DI 0 "memory_operand" "")
2758         (match_operand:DI 1 "immediate_operand" ""))]
2759   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2760    && !x86_64_immediate_operand (operands[1], DImode)"
2761   [(set (match_dup 2) (match_dup 1))
2762    (set (match_dup 0) (match_dup 2))]
2763   "")
2764
2765 ;; We need to define this as both peepholer and splitter for case
2766 ;; peephole2 pass is not run.
2767 ;; "&& 1" is needed to keep it from matching the previous pattern.
2768 (define_peephole2
2769   [(set (match_operand:DI 0 "memory_operand" "")
2770         (match_operand:DI 1 "immediate_operand" ""))]
2771   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2772    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2773   [(set (match_dup 2) (match_dup 3))
2774    (set (match_dup 4) (match_dup 5))]
2775   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2776
2777 (define_split
2778   [(set (match_operand:DI 0 "memory_operand" "")
2779         (match_operand:DI 1 "immediate_operand" ""))]
2780   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2781                     ? epilogue_completed : reload_completed)
2782    && !symbolic_operand (operands[1], DImode)
2783    && !x86_64_immediate_operand (operands[1], DImode)"
2784   [(set (match_dup 2) (match_dup 3))
2785    (set (match_dup 4) (match_dup 5))]
2786   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2787
2788 (define_insn "*swapdi_rex64"
2789   [(set (match_operand:DI 0 "register_operand" "+r")
2790         (match_operand:DI 1 "register_operand" "+r"))
2791    (set (match_dup 1)
2792         (match_dup 0))]
2793   "TARGET_64BIT"
2794   "xchg{q}\t%1, %0"
2795   [(set_attr "type" "imov")
2796    (set_attr "mode" "DI")
2797    (set_attr "pent_pair" "np")
2798    (set_attr "athlon_decode" "vector")
2799    (set_attr "amdfam10_decode" "double")])
2800
2801 (define_expand "movoi"
2802   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2803         (match_operand:OI 1 "general_operand" ""))]
2804   "TARGET_AVX"
2805   "ix86_expand_move (OImode, operands); DONE;")
2806
2807 (define_insn "*movoi_internal"
2808   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2809         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2810   "TARGET_AVX
2811    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2812 {
2813   switch (which_alternative)
2814     {
2815     case 0:
2816       return "vxorps\t%0, %0, %0";
2817     case 1:
2818     case 2:
2819       if (misaligned_operand (operands[0], OImode)
2820           || misaligned_operand (operands[1], OImode))
2821         return "vmovdqu\t{%1, %0|%0, %1}";
2822       else
2823         return "vmovdqa\t{%1, %0|%0, %1}";
2824     default:
2825       gcc_unreachable ();
2826     }
2827 }
2828   [(set_attr "type" "sselog1,ssemov,ssemov")
2829    (set_attr "prefix" "vex")
2830    (set_attr "mode" "OI")])
2831
2832 (define_expand "movti"
2833   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2834         (match_operand:TI 1 "nonimmediate_operand" ""))]
2835   "TARGET_SSE || TARGET_64BIT"
2836 {
2837   if (TARGET_64BIT)
2838     ix86_expand_move (TImode, operands);
2839   else if (push_operand (operands[0], TImode))
2840     ix86_expand_push (TImode, operands[1]);
2841   else
2842     ix86_expand_vector_move (TImode, operands);
2843   DONE;
2844 })
2845
2846 (define_insn "*movti_internal"
2847   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2848         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2849   "TARGET_SSE && !TARGET_64BIT
2850    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2851 {
2852   switch (which_alternative)
2853     {
2854     case 0:
2855       if (get_attr_mode (insn) == MODE_V4SF)
2856         return "%vxorps\t%0, %d0";
2857       else
2858         return "%vpxor\t%0, %d0";
2859     case 1:
2860     case 2:
2861       /* TDmode values are passed as TImode on the stack.  Moving them
2862          to stack may result in unaligned memory access.  */
2863       if (misaligned_operand (operands[0], TImode)
2864           || misaligned_operand (operands[1], TImode))
2865         {
2866           if (get_attr_mode (insn) == MODE_V4SF)
2867             return "%vmovups\t{%1, %0|%0, %1}";
2868          else
2869            return "%vmovdqu\t{%1, %0|%0, %1}";
2870         }
2871       else
2872         {
2873           if (get_attr_mode (insn) == MODE_V4SF)
2874             return "%vmovaps\t{%1, %0|%0, %1}";
2875          else
2876            return "%vmovdqa\t{%1, %0|%0, %1}";
2877         }
2878     default:
2879       gcc_unreachable ();
2880     }
2881 }
2882   [(set_attr "type" "sselog1,ssemov,ssemov")
2883    (set_attr "prefix" "maybe_vex")
2884    (set (attr "mode")
2885         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2886                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2887                  (const_string "V4SF")
2888                (and (eq_attr "alternative" "2")
2889                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2890                         (const_int 0)))
2891                  (const_string "V4SF")]
2892               (const_string "TI")))])
2893
2894 (define_insn "*movti_rex64"
2895   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2896         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2897   "TARGET_64BIT
2898    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2899 {
2900   switch (which_alternative)
2901     {
2902     case 0:
2903     case 1:
2904       return "#";
2905     case 2:
2906       if (get_attr_mode (insn) == MODE_V4SF)
2907         return "%vxorps\t%0, %d0";
2908       else
2909         return "%vpxor\t%0, %d0";
2910     case 3:
2911     case 4:
2912       /* TDmode values are passed as TImode on the stack.  Moving them
2913          to stack may result in unaligned memory access.  */
2914       if (misaligned_operand (operands[0], TImode)
2915           || misaligned_operand (operands[1], TImode))
2916         {
2917           if (get_attr_mode (insn) == MODE_V4SF)
2918             return "%vmovups\t{%1, %0|%0, %1}";
2919          else
2920            return "%vmovdqu\t{%1, %0|%0, %1}";
2921         }
2922       else
2923         {
2924           if (get_attr_mode (insn) == MODE_V4SF)
2925             return "%vmovaps\t{%1, %0|%0, %1}";
2926          else
2927            return "%vmovdqa\t{%1, %0|%0, %1}";
2928         }
2929     default:
2930       gcc_unreachable ();
2931     }
2932 }
2933   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2934    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2935    (set (attr "mode")
2936         (cond [(eq_attr "alternative" "2,3")
2937                  (if_then_else
2938                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2939                        (const_int 0))
2940                    (const_string "V4SF")
2941                    (const_string "TI"))
2942                (eq_attr "alternative" "4")
2943                  (if_then_else
2944                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2945                             (const_int 0))
2946                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2947                             (const_int 0)))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))]
2950                (const_string "DI")))])
2951
2952 (define_split
2953   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2954         (match_operand:TI 1 "general_operand" ""))]
2955   "reload_completed && !SSE_REG_P (operands[0])
2956    && !SSE_REG_P (operands[1])"
2957   [(const_int 0)]
2958   "ix86_split_long_move (operands); DONE;")
2959
2960 ;; This expands to what emit_move_complex would generate if we didn't
2961 ;; have a movti pattern.  Having this avoids problems with reload on
2962 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2963 ;; to have around all the time.
2964 (define_expand "movcdi"
2965   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2966         (match_operand:CDI 1 "general_operand" ""))]
2967   ""
2968 {
2969   if (push_operand (operands[0], CDImode))
2970     emit_move_complex_push (CDImode, operands[0], operands[1]);
2971   else
2972     emit_move_complex_parts (operands[0], operands[1]);
2973   DONE;
2974 })
2975
2976 (define_expand "movsf"
2977   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2978         (match_operand:SF 1 "general_operand" ""))]
2979   ""
2980   "ix86_expand_move (SFmode, operands); DONE;")
2981
2982 (define_insn "*pushsf"
2983   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2984         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2985   "!TARGET_64BIT"
2986 {
2987   /* Anything else should be already split before reg-stack.  */
2988   gcc_assert (which_alternative == 1);
2989   return "push{l}\t%1";
2990 }
2991   [(set_attr "type" "multi,push,multi")
2992    (set_attr "unit" "i387,*,*")
2993    (set_attr "mode" "SF,SI,SF")])
2994
2995 (define_insn "*pushsf_rex64"
2996   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2997         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2998   "TARGET_64BIT"
2999 {
3000   /* Anything else should be already split before reg-stack.  */
3001   gcc_assert (which_alternative == 1);
3002   return "push{q}\t%q1";
3003 }
3004   [(set_attr "type" "multi,push,multi")
3005    (set_attr "unit" "i387,*,*")
3006    (set_attr "mode" "SF,DI,SF")])
3007
3008 (define_split
3009   [(set (match_operand:SF 0 "push_operand" "")
3010         (match_operand:SF 1 "memory_operand" ""))]
3011   "reload_completed
3012    && MEM_P (operands[1])
3013    && (operands[2] = find_constant_src (insn))"
3014   [(set (match_dup 0)
3015         (match_dup 2))])
3016
3017
3018 ;; %%% Kill this when call knows how to work this out.
3019 (define_split
3020   [(set (match_operand:SF 0 "push_operand" "")
3021         (match_operand:SF 1 "any_fp_register_operand" ""))]
3022   "!TARGET_64BIT"
3023   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3024    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3025
3026 (define_split
3027   [(set (match_operand:SF 0 "push_operand" "")
3028         (match_operand:SF 1 "any_fp_register_operand" ""))]
3029   "TARGET_64BIT"
3030   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3031    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3032
3033 (define_insn "*movsf_1"
3034   [(set (match_operand:SF 0 "nonimmediate_operand"
3035           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3036         (match_operand:SF 1 "general_operand"
3037           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3038   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3039    && (reload_in_progress || reload_completed
3040        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3041        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3042            && standard_80387_constant_p (operands[1]))
3043        || GET_CODE (operands[1]) != CONST_DOUBLE
3044        || memory_operand (operands[0], SFmode))"
3045 {
3046   switch (which_alternative)
3047     {
3048     case 0:
3049     case 1:
3050       return output_387_reg_move (insn, operands);
3051
3052     case 2:
3053       return standard_80387_constant_opcode (operands[1]);
3054
3055     case 3:
3056     case 4:
3057       return "mov{l}\t{%1, %0|%0, %1}";
3058     case 5:
3059       if (get_attr_mode (insn) == MODE_TI)
3060         return "%vpxor\t%0, %d0";
3061       else
3062         return "%vxorps\t%0, %d0";
3063     case 6:
3064       if (get_attr_mode (insn) == MODE_V4SF)
3065         return "%vmovaps\t{%1, %0|%0, %1}";
3066       else
3067         return "%vmovss\t{%1, %d0|%d0, %1}";
3068     case 7:
3069       if (TARGET_AVX)
3070         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3071                                    : "vmovss\t{%1, %0|%0, %1}";
3072       else
3073         return "movss\t{%1, %0|%0, %1}";
3074     case 8:
3075       return "%vmovss\t{%1, %0|%0, %1}";
3076
3077     case 9: case 10: case 14: case 15:
3078       return "movd\t{%1, %0|%0, %1}";
3079     case 12: case 13:
3080       return "%vmovd\t{%1, %0|%0, %1}";
3081
3082     case 11:
3083       return "movq\t{%1, %0|%0, %1}";
3084
3085     default:
3086       gcc_unreachable ();
3087     }
3088 }
3089   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3090    (set (attr "prefix")
3091      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3092        (const_string "maybe_vex")
3093        (const_string "orig")))
3094    (set (attr "mode")
3095         (cond [(eq_attr "alternative" "3,4,9,10")
3096                  (const_string "SI")
3097                (eq_attr "alternative" "5")
3098                  (if_then_else
3099                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3100                                  (const_int 0))
3101                              (ne (symbol_ref "TARGET_SSE2")
3102                                  (const_int 0)))
3103                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3104                             (const_int 0)))
3105                    (const_string "TI")
3106                    (const_string "V4SF"))
3107                /* For architectures resolving dependencies on
3108                   whole SSE registers use APS move to break dependency
3109                   chains, otherwise use short move to avoid extra work.
3110
3111                   Do the same for architectures resolving dependencies on
3112                   the parts.  While in DF mode it is better to always handle
3113                   just register parts, the SF mode is different due to lack
3114                   of instructions to load just part of the register.  It is
3115                   better to maintain the whole registers in single format
3116                   to avoid problems on using packed logical operations.  */
3117                (eq_attr "alternative" "6")
3118                  (if_then_else
3119                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3120                             (const_int 0))
3121                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3122                             (const_int 0)))
3123                    (const_string "V4SF")
3124                    (const_string "SF"))
3125                (eq_attr "alternative" "11")
3126                  (const_string "DI")]
3127                (const_string "SF")))])
3128
3129 (define_insn "*swapsf"
3130   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3131         (match_operand:SF 1 "fp_register_operand" "+f"))
3132    (set (match_dup 1)
3133         (match_dup 0))]
3134   "reload_completed || TARGET_80387"
3135 {
3136   if (STACK_TOP_P (operands[0]))
3137     return "fxch\t%1";
3138   else
3139     return "fxch\t%0";
3140 }
3141   [(set_attr "type" "fxch")
3142    (set_attr "mode" "SF")])
3143
3144 (define_expand "movdf"
3145   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3146         (match_operand:DF 1 "general_operand" ""))]
3147   ""
3148   "ix86_expand_move (DFmode, operands); DONE;")
3149
3150 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3151 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3152 ;; On the average, pushdf using integers can be still shorter.  Allow this
3153 ;; pattern for optimize_size too.
3154
3155 (define_insn "*pushdf_nointeger"
3156   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3157         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3158   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3159 {
3160   /* This insn should be already split before reg-stack.  */
3161   gcc_unreachable ();
3162 }
3163   [(set_attr "type" "multi")
3164    (set_attr "unit" "i387,*,*,*")
3165    (set_attr "mode" "DF,SI,SI,DF")])
3166
3167 (define_insn "*pushdf_integer"
3168   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3169         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3170   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3171 {
3172   /* This insn should be already split before reg-stack.  */
3173   gcc_unreachable ();
3174 }
3175   [(set_attr "type" "multi")
3176    (set_attr "unit" "i387,*,*")
3177    (set_attr "mode" "DF,SI,DF")])
3178
3179 ;; %%% Kill this when call knows how to work this out.
3180 (define_split
3181   [(set (match_operand:DF 0 "push_operand" "")
3182         (match_operand:DF 1 "any_fp_register_operand" ""))]
3183   "reload_completed"
3184   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3185    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3186   "")
3187
3188 (define_split
3189   [(set (match_operand:DF 0 "push_operand" "")
3190         (match_operand:DF 1 "general_operand" ""))]
3191   "reload_completed"
3192   [(const_int 0)]
3193   "ix86_split_long_move (operands); DONE;")
3194
3195 ;; Moving is usually shorter when only FP registers are used. This separate
3196 ;; movdf pattern avoids the use of integer registers for FP operations
3197 ;; when optimizing for size.
3198
3199 (define_insn "*movdf_nointeger"
3200   [(set (match_operand:DF 0 "nonimmediate_operand"
3201                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3202         (match_operand:DF 1 "general_operand"
3203                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3204   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3205    && ((optimize_function_for_size_p (cfun)
3206        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3207    && (reload_in_progress || reload_completed
3208        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3209        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3210            && optimize_function_for_size_p (cfun)
3211            && !memory_operand (operands[0], DFmode)
3212            && standard_80387_constant_p (operands[1]))
3213        || GET_CODE (operands[1]) != CONST_DOUBLE
3214        || ((optimize_function_for_size_p (cfun)
3215             || !TARGET_MEMORY_MISMATCH_STALL
3216             || reload_in_progress || reload_completed)
3217            && memory_operand (operands[0], DFmode)))"
3218 {
3219   switch (which_alternative)
3220     {
3221     case 0:
3222     case 1:
3223       return output_387_reg_move (insn, operands);
3224
3225     case 2:
3226       return standard_80387_constant_opcode (operands[1]);
3227
3228     case 3:
3229     case 4:
3230       return "#";
3231     case 5:
3232       switch (get_attr_mode (insn))
3233         {
3234         case MODE_V4SF:
3235           return "%vxorps\t%0, %d0";
3236         case MODE_V2DF:
3237           return "%vxorpd\t%0, %d0";
3238         case MODE_TI:
3239           return "%vpxor\t%0, %d0";
3240         default:
3241           gcc_unreachable ();
3242         }
3243     case 6:
3244     case 7:
3245     case 8:
3246       switch (get_attr_mode (insn))
3247         {
3248         case MODE_V4SF:
3249           return "%vmovaps\t{%1, %0|%0, %1}";
3250         case MODE_V2DF:
3251           return "%vmovapd\t{%1, %0|%0, %1}";
3252         case MODE_TI:
3253           return "%vmovdqa\t{%1, %0|%0, %1}";
3254         case MODE_DI:
3255           return "%vmovq\t{%1, %0|%0, %1}";
3256         case MODE_DF:
3257           if (TARGET_AVX)
3258             {
3259               if (REG_P (operands[0]) && REG_P (operands[1]))
3260                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3261               else
3262                 return "vmovsd\t{%1, %0|%0, %1}";
3263             }
3264           else
3265             return "movsd\t{%1, %0|%0, %1}";
3266         case MODE_V1DF:
3267           if (TARGET_AVX)
3268             {
3269               if (REG_P (operands[0]))
3270                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3271               else
3272                 return "vmovlpd\t{%1, %0|%0, %1}";
3273             }
3274           else
3275             return "movlpd\t{%1, %0|%0, %1}";
3276         case MODE_V2SF:
3277           if (TARGET_AVX)
3278             {
3279               if (REG_P (operands[0]))
3280                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3281               else
3282                 return "vmovlps\t{%1, %0|%0, %1}";
3283             }
3284           else
3285             return "movlps\t{%1, %0|%0, %1}";
3286         default:
3287           gcc_unreachable ();
3288         }
3289
3290     default:
3291       gcc_unreachable ();
3292     }
3293 }
3294   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3295    (set (attr "prefix")
3296      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3297        (const_string "orig")
3298        (const_string "maybe_vex")))
3299    (set (attr "prefix_data16")
3300      (if_then_else (eq_attr "mode" "V1DF")
3301        (const_string "1")
3302        (const_string "*")))
3303    (set (attr "mode")
3304         (cond [(eq_attr "alternative" "0,1,2")
3305                  (const_string "DF")
3306                (eq_attr "alternative" "3,4")
3307                  (const_string "SI")
3308
3309                /* For SSE1, we have many fewer alternatives.  */
3310                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3311                  (cond [(eq_attr "alternative" "5,6")
3312                           (const_string "V4SF")
3313                        ]
3314                    (const_string "V2SF"))
3315
3316                /* xorps is one byte shorter.  */
3317                (eq_attr "alternative" "5")
3318                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3319                             (const_int 0))
3320                           (const_string "V4SF")
3321                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3322                             (const_int 0))
3323                           (const_string "TI")
3324                        ]
3325                        (const_string "V2DF"))
3326
3327                /* For architectures resolving dependencies on
3328                   whole SSE registers use APD move to break dependency
3329                   chains, otherwise use short move to avoid extra work.
3330
3331                   movaps encodes one byte shorter.  */
3332                (eq_attr "alternative" "6")
3333                  (cond
3334                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3335                         (const_int 0))
3336                       (const_string "V4SF")
3337                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3338                         (const_int 0))
3339                       (const_string "V2DF")
3340                    ]
3341                    (const_string "DF"))
3342                /* For architectures resolving dependencies on register
3343                   parts we may avoid extra work to zero out upper part
3344                   of register.  */
3345                (eq_attr "alternative" "7")
3346                  (if_then_else
3347                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3348                        (const_int 0))
3349                    (const_string "V1DF")
3350                    (const_string "DF"))
3351               ]
3352               (const_string "DF")))])
3353
3354 (define_insn "*movdf_integer_rex64"
3355   [(set (match_operand:DF 0 "nonimmediate_operand"
3356                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3357         (match_operand:DF 1 "general_operand"
3358                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3359   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360    && (reload_in_progress || reload_completed
3361        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3362        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3363            && optimize_function_for_size_p (cfun)
3364            && standard_80387_constant_p (operands[1]))
3365        || GET_CODE (operands[1]) != CONST_DOUBLE
3366        || memory_operand (operands[0], DFmode))"
3367 {
3368   switch (which_alternative)
3369     {
3370     case 0:
3371     case 1:
3372       return output_387_reg_move (insn, operands);
3373
3374     case 2:
3375       return standard_80387_constant_opcode (operands[1]);
3376
3377     case 3:
3378     case 4:
3379       return "#";
3380
3381     case 5:
3382       switch (get_attr_mode (insn))
3383         {
3384         case MODE_V4SF:
3385           return "%vxorps\t%0, %d0";
3386         case MODE_V2DF:
3387           return "%vxorpd\t%0, %d0";
3388         case MODE_TI:
3389           return "%vpxor\t%0, %d0";
3390         default:
3391           gcc_unreachable ();
3392         }
3393     case 6:
3394     case 7:
3395     case 8:
3396       switch (get_attr_mode (insn))
3397         {
3398         case MODE_V4SF:
3399           return "%vmovaps\t{%1, %0|%0, %1}";
3400         case MODE_V2DF:
3401           return "%vmovapd\t{%1, %0|%0, %1}";
3402         case MODE_TI:
3403           return "%vmovdqa\t{%1, %0|%0, %1}";
3404         case MODE_DI:
3405           return "%vmovq\t{%1, %0|%0, %1}";
3406         case MODE_DF:
3407           if (TARGET_AVX)
3408             {
3409               if (REG_P (operands[0]) && REG_P (operands[1]))
3410                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3411               else
3412                 return "vmovsd\t{%1, %0|%0, %1}";
3413             }
3414           else
3415             return "movsd\t{%1, %0|%0, %1}";
3416         case MODE_V1DF:
3417           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3418         case MODE_V2SF:
3419           return "%vmovlps\t{%1, %d0|%d0, %1}";
3420         default:
3421           gcc_unreachable ();
3422         }
3423
3424     case 9:
3425     case 10:
3426     return "%vmovd\t{%1, %0|%0, %1}";
3427
3428     default:
3429       gcc_unreachable();
3430     }
3431 }
3432   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3433    (set (attr "prefix")
3434      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3435        (const_string "orig")
3436        (const_string "maybe_vex")))
3437    (set (attr "prefix_data16")
3438      (if_then_else (eq_attr "mode" "V1DF")
3439        (const_string "1")
3440        (const_string "*")))
3441    (set (attr "mode")
3442         (cond [(eq_attr "alternative" "0,1,2")
3443                  (const_string "DF")
3444                (eq_attr "alternative" "3,4,9,10")
3445                  (const_string "DI")
3446
3447                /* For SSE1, we have many fewer alternatives.  */
3448                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3449                  (cond [(eq_attr "alternative" "5,6")
3450                           (const_string "V4SF")
3451                        ]
3452                    (const_string "V2SF"))
3453
3454                /* xorps is one byte shorter.  */
3455                (eq_attr "alternative" "5")
3456                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3457                             (const_int 0))
3458                           (const_string "V4SF")
3459                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3460                             (const_int 0))
3461                           (const_string "TI")
3462                        ]
3463                        (const_string "V2DF"))
3464
3465                /* For architectures resolving dependencies on
3466                   whole SSE registers use APD move to break dependency
3467                   chains, otherwise use short move to avoid extra work.
3468
3469                   movaps encodes one byte shorter.  */
3470                (eq_attr "alternative" "6")
3471                  (cond
3472                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3473                         (const_int 0))
3474                       (const_string "V4SF")
3475                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3476                         (const_int 0))
3477                       (const_string "V2DF")
3478                    ]
3479                    (const_string "DF"))
3480                /* For architectures resolving dependencies on register
3481                   parts we may avoid extra work to zero out upper part
3482                   of register.  */
3483                (eq_attr "alternative" "7")
3484                  (if_then_else
3485                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3486                        (const_int 0))
3487                    (const_string "V1DF")
3488                    (const_string "DF"))
3489               ]
3490               (const_string "DF")))])
3491
3492 (define_insn "*movdf_integer"
3493   [(set (match_operand:DF 0 "nonimmediate_operand"
3494                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3495         (match_operand:DF 1 "general_operand"
3496                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3497   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3498    && optimize_function_for_speed_p (cfun)
3499    && TARGET_INTEGER_DFMODE_MOVES
3500    && (reload_in_progress || reload_completed
3501        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3502        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3503            && optimize_function_for_size_p (cfun)
3504            && standard_80387_constant_p (operands[1]))
3505        || GET_CODE (operands[1]) != CONST_DOUBLE
3506        || memory_operand (operands[0], DFmode))"
3507 {
3508   switch (which_alternative)
3509     {
3510     case 0:
3511     case 1:
3512       return output_387_reg_move (insn, operands);
3513
3514     case 2:
3515       return standard_80387_constant_opcode (operands[1]);
3516
3517     case 3:
3518     case 4:
3519       return "#";
3520
3521     case 5:
3522       switch (get_attr_mode (insn))
3523         {
3524         case MODE_V4SF:
3525           return "xorps\t%0, %0";
3526         case MODE_V2DF:
3527           return "xorpd\t%0, %0";
3528         case MODE_TI:
3529           return "pxor\t%0, %0";
3530         default:
3531           gcc_unreachable ();
3532         }
3533     case 6:
3534     case 7:
3535     case 8:
3536       switch (get_attr_mode (insn))
3537         {
3538         case MODE_V4SF:
3539           return "movaps\t{%1, %0|%0, %1}";
3540         case MODE_V2DF:
3541           return "movapd\t{%1, %0|%0, %1}";
3542         case MODE_TI:
3543           return "movdqa\t{%1, %0|%0, %1}";
3544         case MODE_DI:
3545           return "movq\t{%1, %0|%0, %1}";
3546         case MODE_DF:
3547           return "movsd\t{%1, %0|%0, %1}";
3548         case MODE_V1DF:
3549           return "movlpd\t{%1, %0|%0, %1}";
3550         case MODE_V2SF:
3551           return "movlps\t{%1, %0|%0, %1}";
3552         default:
3553           gcc_unreachable ();
3554         }
3555
3556     default:
3557       gcc_unreachable();
3558     }
3559 }
3560   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3561    (set (attr "prefix_data16")
3562      (if_then_else (eq_attr "mode" "V1DF")
3563        (const_string "1")
3564        (const_string "*")))
3565    (set (attr "mode")
3566         (cond [(eq_attr "alternative" "0,1,2")
3567                  (const_string "DF")
3568                (eq_attr "alternative" "3,4")
3569                  (const_string "SI")
3570
3571                /* For SSE1, we have many fewer alternatives.  */
3572                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3573                  (cond [(eq_attr "alternative" "5,6")
3574                           (const_string "V4SF")
3575                        ]
3576                    (const_string "V2SF"))
3577
3578                /* xorps is one byte shorter.  */
3579                (eq_attr "alternative" "5")
3580                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3581                             (const_int 0))
3582                           (const_string "V4SF")
3583                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3584                             (const_int 0))
3585                           (const_string "TI")
3586                        ]
3587                        (const_string "V2DF"))
3588
3589                /* For architectures resolving dependencies on
3590                   whole SSE registers use APD move to break dependency
3591                   chains, otherwise use short move to avoid extra work.
3592
3593                   movaps encodes one byte shorter.  */
3594                (eq_attr "alternative" "6")
3595                  (cond
3596                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3597                         (const_int 0))
3598                       (const_string "V4SF")
3599                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3600                         (const_int 0))
3601                       (const_string "V2DF")
3602                    ]
3603                    (const_string "DF"))
3604                /* For architectures resolving dependencies on register
3605                   parts we may avoid extra work to zero out upper part
3606                   of register.  */
3607                (eq_attr "alternative" "7")
3608                  (if_then_else
3609                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3610                        (const_int 0))
3611                    (const_string "V1DF")
3612                    (const_string "DF"))
3613               ]
3614               (const_string "DF")))])
3615
3616 (define_split
3617   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3618         (match_operand:DF 1 "general_operand" ""))]
3619   "reload_completed
3620    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3621    && ! (ANY_FP_REG_P (operands[0]) ||
3622          (GET_CODE (operands[0]) == SUBREG
3623           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3624    && ! (ANY_FP_REG_P (operands[1]) ||
3625          (GET_CODE (operands[1]) == SUBREG
3626           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3627   [(const_int 0)]
3628   "ix86_split_long_move (operands); DONE;")
3629
3630 (define_insn "*swapdf"
3631   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3632         (match_operand:DF 1 "fp_register_operand" "+f"))
3633    (set (match_dup 1)
3634         (match_dup 0))]
3635   "reload_completed || TARGET_80387"
3636 {
3637   if (STACK_TOP_P (operands[0]))
3638     return "fxch\t%1";
3639   else
3640     return "fxch\t%0";
3641 }
3642   [(set_attr "type" "fxch")
3643    (set_attr "mode" "DF")])
3644
3645 (define_expand "movxf"
3646   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3647         (match_operand:XF 1 "general_operand" ""))]
3648   ""
3649   "ix86_expand_move (XFmode, operands); DONE;")
3650
3651 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3652 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3653 ;; Pushing using integer instructions is longer except for constants
3654 ;; and direct memory references.
3655 ;; (assuming that any given constant is pushed only once, but this ought to be
3656 ;;  handled elsewhere).
3657
3658 (define_insn "*pushxf_nointeger"
3659   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3660         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3661   "optimize_function_for_size_p (cfun)"
3662 {
3663   /* This insn should be already split before reg-stack.  */
3664   gcc_unreachable ();
3665 }
3666   [(set_attr "type" "multi")
3667    (set_attr "unit" "i387,*,*")
3668    (set_attr "mode" "XF,SI,SI")])
3669
3670 (define_insn "*pushxf_integer"
3671   [(set (match_operand:XF 0 "push_operand" "=<,<")
3672         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3673   "optimize_function_for_speed_p (cfun)"
3674 {
3675   /* This insn should be already split before reg-stack.  */
3676   gcc_unreachable ();
3677 }
3678   [(set_attr "type" "multi")
3679    (set_attr "unit" "i387,*")
3680    (set_attr "mode" "XF,SI")])
3681
3682 (define_split
3683   [(set (match_operand 0 "push_operand" "")
3684         (match_operand 1 "general_operand" ""))]
3685   "reload_completed
3686    && (GET_MODE (operands[0]) == XFmode
3687        || GET_MODE (operands[0]) == DFmode)
3688    && !ANY_FP_REG_P (operands[1])"
3689   [(const_int 0)]
3690   "ix86_split_long_move (operands); DONE;")
3691
3692 (define_split
3693   [(set (match_operand:XF 0 "push_operand" "")
3694         (match_operand:XF 1 "any_fp_register_operand" ""))]
3695   ""
3696   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3697    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3698   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3699
3700 ;; Do not use integer registers when optimizing for size
3701 (define_insn "*movxf_nointeger"
3702   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3703         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3704   "optimize_function_for_size_p (cfun)
3705    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3706    && (reload_in_progress || reload_completed
3707        || standard_80387_constant_p (operands[1])
3708        || GET_CODE (operands[1]) != CONST_DOUBLE
3709        || memory_operand (operands[0], XFmode))"
3710 {
3711   switch (which_alternative)
3712     {
3713     case 0:
3714     case 1:
3715       return output_387_reg_move (insn, operands);
3716
3717     case 2:
3718       return standard_80387_constant_opcode (operands[1]);
3719
3720     case 3: case 4:
3721       return "#";
3722     default:
3723       gcc_unreachable ();
3724     }
3725 }
3726   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3727    (set_attr "mode" "XF,XF,XF,SI,SI")])
3728
3729 (define_insn "*movxf_integer"
3730   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3731         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3732   "optimize_function_for_speed_p (cfun)
3733    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3734    && (reload_in_progress || reload_completed
3735        || GET_CODE (operands[1]) != CONST_DOUBLE
3736        || memory_operand (operands[0], XFmode))"
3737 {
3738   switch (which_alternative)
3739     {
3740     case 0:
3741     case 1:
3742       return output_387_reg_move (insn, operands);
3743
3744     case 2:
3745       return standard_80387_constant_opcode (operands[1]);
3746
3747     case 3: case 4:
3748       return "#";
3749
3750     default:
3751       gcc_unreachable ();
3752     }
3753 }
3754   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3755    (set_attr "mode" "XF,XF,XF,SI,SI")])
3756
3757 (define_expand "movtf"
3758   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3759         (match_operand:TF 1 "nonimmediate_operand" ""))]
3760   "TARGET_SSE2"
3761 {
3762   ix86_expand_move (TFmode, operands);
3763   DONE;
3764 })
3765
3766 (define_insn "*movtf_internal"
3767   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3768         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3769   "TARGET_SSE2
3770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3771 {
3772   switch (which_alternative)
3773     {
3774     case 0:
3775     case 1:
3776       if (get_attr_mode (insn) == MODE_V4SF)
3777         return "%vmovaps\t{%1, %0|%0, %1}";
3778       else
3779         return "%vmovdqa\t{%1, %0|%0, %1}";
3780     case 2:
3781       if (get_attr_mode (insn) == MODE_V4SF)
3782         return "%vxorps\t%0, %d0";
3783       else
3784         return "%vpxor\t%0, %d0";
3785     case 3:
3786     case 4:
3787         return "#";
3788     default:
3789       gcc_unreachable ();
3790     }
3791 }
3792   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3793    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3794    (set (attr "mode")
3795         (cond [(eq_attr "alternative" "0,2")
3796                  (if_then_else
3797                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3798                        (const_int 0))
3799                    (const_string "V4SF")
3800                    (const_string "TI"))
3801                (eq_attr "alternative" "1")
3802                  (if_then_else
3803                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3804                             (const_int 0))
3805                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3806                             (const_int 0)))
3807                    (const_string "V4SF")
3808                    (const_string "TI"))]
3809                (const_string "DI")))])
3810
3811 (define_insn "*pushtf_sse"
3812   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3813         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3814   "TARGET_SSE2"
3815 {
3816   /* This insn should be already split before reg-stack.  */
3817   gcc_unreachable ();
3818 }
3819   [(set_attr "type" "multi")
3820    (set_attr "unit" "sse,*,*")
3821    (set_attr "mode" "TF,SI,SI")])
3822
3823 (define_split
3824   [(set (match_operand:TF 0 "push_operand" "")
3825         (match_operand:TF 1 "general_operand" ""))]
3826   "TARGET_SSE2 && reload_completed
3827    && !SSE_REG_P (operands[1])"
3828   [(const_int 0)]
3829   "ix86_split_long_move (operands); DONE;")
3830
3831 (define_split
3832   [(set (match_operand:TF 0 "push_operand" "")
3833         (match_operand:TF 1 "any_fp_register_operand" ""))]
3834   "TARGET_SSE2"
3835   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3836    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3837   "")
3838
3839 (define_split
3840   [(set (match_operand 0 "nonimmediate_operand" "")
3841         (match_operand 1 "general_operand" ""))]
3842   "reload_completed
3843    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3844    && GET_MODE (operands[0]) == XFmode
3845    && ! (ANY_FP_REG_P (operands[0]) ||
3846          (GET_CODE (operands[0]) == SUBREG
3847           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3848    && ! (ANY_FP_REG_P (operands[1]) ||
3849          (GET_CODE (operands[1]) == SUBREG
3850           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3851   [(const_int 0)]
3852   "ix86_split_long_move (operands); DONE;")
3853
3854 (define_split
3855   [(set (match_operand 0 "register_operand" "")
3856         (match_operand 1 "memory_operand" ""))]
3857   "reload_completed
3858    && MEM_P (operands[1])
3859    && (GET_MODE (operands[0]) == TFmode
3860        || GET_MODE (operands[0]) == XFmode
3861        || GET_MODE (operands[0]) == SFmode
3862        || GET_MODE (operands[0]) == DFmode)
3863    && (operands[2] = find_constant_src (insn))"
3864   [(set (match_dup 0) (match_dup 2))]
3865 {
3866   rtx c = operands[2];
3867   rtx r = operands[0];
3868
3869   if (GET_CODE (r) == SUBREG)
3870     r = SUBREG_REG (r);
3871
3872   if (SSE_REG_P (r))
3873     {
3874       if (!standard_sse_constant_p (c))
3875         FAIL;
3876     }
3877   else if (FP_REG_P (r))
3878     {
3879       if (!standard_80387_constant_p (c))
3880         FAIL;
3881     }
3882   else if (MMX_REG_P (r))
3883     FAIL;
3884 })
3885
3886 (define_split
3887   [(set (match_operand 0 "register_operand" "")
3888         (float_extend (match_operand 1 "memory_operand" "")))]
3889   "reload_completed
3890    && MEM_P (operands[1])
3891    && (GET_MODE (operands[0]) == TFmode
3892        || GET_MODE (operands[0]) == XFmode
3893        || GET_MODE (operands[0]) == SFmode
3894        || GET_MODE (operands[0]) == DFmode)
3895    && (operands[2] = find_constant_src (insn))"
3896   [(set (match_dup 0) (match_dup 2))]
3897 {
3898   rtx c = operands[2];
3899   rtx r = operands[0];
3900
3901   if (GET_CODE (r) == SUBREG)
3902     r = SUBREG_REG (r);
3903
3904   if (SSE_REG_P (r))
3905     {
3906       if (!standard_sse_constant_p (c))
3907         FAIL;
3908     }
3909   else if (FP_REG_P (r))
3910     {
3911       if (!standard_80387_constant_p (c))
3912         FAIL;
3913     }
3914   else if (MMX_REG_P (r))
3915     FAIL;
3916 })
3917
3918 (define_insn "swapxf"
3919   [(set (match_operand:XF 0 "register_operand" "+f")
3920         (match_operand:XF 1 "register_operand" "+f"))
3921    (set (match_dup 1)
3922         (match_dup 0))]
3923   "TARGET_80387"
3924 {
3925   if (STACK_TOP_P (operands[0]))
3926     return "fxch\t%1";
3927   else
3928     return "fxch\t%0";
3929 }
3930   [(set_attr "type" "fxch")
3931    (set_attr "mode" "XF")])
3932
3933 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3934 (define_split
3935   [(set (match_operand:X87MODEF 0 "register_operand" "")
3936         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3937   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3938    && (standard_80387_constant_p (operands[1]) == 8
3939        || standard_80387_constant_p (operands[1]) == 9)"
3940   [(set (match_dup 0)(match_dup 1))
3941    (set (match_dup 0)
3942         (neg:X87MODEF (match_dup 0)))]
3943 {
3944   REAL_VALUE_TYPE r;
3945
3946   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3947   if (real_isnegzero (&r))
3948     operands[1] = CONST0_RTX (<MODE>mode);
3949   else
3950     operands[1] = CONST1_RTX (<MODE>mode);
3951 })
3952
3953 (define_split
3954   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3955         (match_operand:TF 1 "general_operand" ""))]
3956   "reload_completed
3957    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3958   [(const_int 0)]
3959   "ix86_split_long_move (operands); DONE;")
3960 \f
3961 ;; Zero extension instructions
3962
3963 (define_expand "zero_extendhisi2"
3964   [(set (match_operand:SI 0 "register_operand" "")
3965      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3966   ""
3967 {
3968   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3969     {
3970       operands[1] = force_reg (HImode, operands[1]);
3971       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3972       DONE;
3973     }
3974 })
3975
3976 (define_insn "zero_extendhisi2_and"
3977   [(set (match_operand:SI 0 "register_operand" "=r")
3978      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3979    (clobber (reg:CC FLAGS_REG))]
3980   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3981   "#"
3982   [(set_attr "type" "alu1")
3983    (set_attr "mode" "SI")])
3984
3985 (define_split
3986   [(set (match_operand:SI 0 "register_operand" "")
3987         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3988    (clobber (reg:CC FLAGS_REG))]
3989   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3990    && optimize_function_for_speed_p (cfun)"
3991   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "")
3994
3995 (define_insn "*zero_extendhisi2_movzwl"
3996   [(set (match_operand:SI 0 "register_operand" "=r")
3997      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3998   "!TARGET_ZERO_EXTEND_WITH_AND
3999    || optimize_function_for_size_p (cfun)"
4000   "movz{wl|x}\t{%1, %0|%0, %1}"
4001   [(set_attr "type" "imovx")
4002    (set_attr "mode" "SI")])
4003
4004 (define_expand "zero_extendqihi2"
4005   [(parallel
4006     [(set (match_operand:HI 0 "register_operand" "")
4007        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4008      (clobber (reg:CC FLAGS_REG))])]
4009   ""
4010   "")
4011
4012 (define_insn "*zero_extendqihi2_and"
4013   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4014      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4015    (clobber (reg:CC FLAGS_REG))]
4016   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4017   "#"
4018   [(set_attr "type" "alu1")
4019    (set_attr "mode" "HI")])
4020
4021 (define_insn "*zero_extendqihi2_movzbw_and"
4022   [(set (match_operand:HI 0 "register_operand" "=r,r")
4023      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4024    (clobber (reg:CC FLAGS_REG))]
4025   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4026   "#"
4027   [(set_attr "type" "imovx,alu1")
4028    (set_attr "mode" "HI")])
4029
4030 ; zero extend to SImode here to avoid partial register stalls
4031 (define_insn "*zero_extendqihi2_movzbl"
4032   [(set (match_operand:HI 0 "register_operand" "=r")
4033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4034   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4035    && reload_completed"
4036   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4037   [(set_attr "type" "imovx")
4038    (set_attr "mode" "SI")])
4039
4040 ;; For the movzbw case strip only the clobber
4041 (define_split
4042   [(set (match_operand:HI 0 "register_operand" "")
4043         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4044    (clobber (reg:CC FLAGS_REG))]
4045   "reload_completed
4046    && (!TARGET_ZERO_EXTEND_WITH_AND
4047        || optimize_function_for_size_p (cfun))
4048    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4049   [(set (match_operand:HI 0 "register_operand" "")
4050         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4051
4052 ;; When source and destination does not overlap, clear destination
4053 ;; first and then do the movb
4054 (define_split
4055   [(set (match_operand:HI 0 "register_operand" "")
4056         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4057    (clobber (reg:CC FLAGS_REG))]
4058   "reload_completed
4059    && ANY_QI_REG_P (operands[0])
4060    && (TARGET_ZERO_EXTEND_WITH_AND
4061        && optimize_function_for_speed_p (cfun))
4062    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4063   [(set (match_dup 0) (const_int 0))
4064    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4065   "operands[2] = gen_lowpart (QImode, operands[0]);")
4066
4067 ;; Rest is handled by single and.
4068 (define_split
4069   [(set (match_operand:HI 0 "register_operand" "")
4070         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4071    (clobber (reg:CC FLAGS_REG))]
4072   "reload_completed
4073    && true_regnum (operands[0]) == true_regnum (operands[1])"
4074   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4075               (clobber (reg:CC FLAGS_REG))])]
4076   "")
4077
4078 (define_expand "zero_extendqisi2"
4079   [(parallel
4080     [(set (match_operand:SI 0 "register_operand" "")
4081        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4082      (clobber (reg:CC FLAGS_REG))])]
4083   ""
4084   "")
4085
4086 (define_insn "*zero_extendqisi2_and"
4087   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4088      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4089    (clobber (reg:CC FLAGS_REG))]
4090   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4091   "#"
4092   [(set_attr "type" "alu1")
4093    (set_attr "mode" "SI")])
4094
4095 (define_insn "*zero_extendqisi2_movzbw_and"
4096   [(set (match_operand:SI 0 "register_operand" "=r,r")
4097      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4098    (clobber (reg:CC FLAGS_REG))]
4099   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4100   "#"
4101   [(set_attr "type" "imovx,alu1")
4102    (set_attr "mode" "SI")])
4103
4104 (define_insn "*zero_extendqisi2_movzbw"
4105   [(set (match_operand:SI 0 "register_operand" "=r")
4106      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4107   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4108    && reload_completed"
4109   "movz{bl|x}\t{%1, %0|%0, %1}"
4110   [(set_attr "type" "imovx")
4111    (set_attr "mode" "SI")])
4112
4113 ;; For the movzbl case strip only the clobber
4114 (define_split
4115   [(set (match_operand:SI 0 "register_operand" "")
4116         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4117    (clobber (reg:CC FLAGS_REG))]
4118   "reload_completed
4119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4121   [(set (match_dup 0)
4122         (zero_extend:SI (match_dup 1)))])
4123
4124 ;; When source and destination does not overlap, clear destination
4125 ;; first and then do the movb
4126 (define_split
4127   [(set (match_operand:SI 0 "register_operand" "")
4128         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4129    (clobber (reg:CC FLAGS_REG))]
4130   "reload_completed
4131    && ANY_QI_REG_P (operands[0])
4132    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4133    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4134    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4135   [(set (match_dup 0) (const_int 0))
4136    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4137   "operands[2] = gen_lowpart (QImode, operands[0]);")
4138
4139 ;; Rest is handled by single and.
4140 (define_split
4141   [(set (match_operand:SI 0 "register_operand" "")
4142         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4143    (clobber (reg:CC FLAGS_REG))]
4144   "reload_completed
4145    && true_regnum (operands[0]) == true_regnum (operands[1])"
4146   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4147               (clobber (reg:CC FLAGS_REG))])]
4148   "")
4149
4150 ;; %%% Kill me once multi-word ops are sane.
4151 (define_expand "zero_extendsidi2"
4152   [(set (match_operand:DI 0 "register_operand" "")
4153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4154   ""
4155 {
4156   if (!TARGET_64BIT)
4157     {
4158       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4159       DONE;
4160     }
4161 })
4162
4163 (define_insn "zero_extendsidi2_32"
4164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4165         (zero_extend:DI
4166          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4167    (clobber (reg:CC FLAGS_REG))]
4168   "!TARGET_64BIT"
4169   "@
4170    #
4171    #
4172    #
4173    movd\t{%1, %0|%0, %1}
4174    movd\t{%1, %0|%0, %1}
4175    %vmovd\t{%1, %0|%0, %1}
4176    %vmovd\t{%1, %0|%0, %1}"
4177   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4178    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4179    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4180
4181 (define_insn "zero_extendsidi2_rex64"
4182   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4183      (zero_extend:DI
4184        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4185   "TARGET_64BIT"
4186   "@
4187    mov\t{%k1, %k0|%k0, %k1}
4188    #
4189    movd\t{%1, %0|%0, %1}
4190    movd\t{%1, %0|%0, %1}
4191    %vmovd\t{%1, %0|%0, %1}
4192    %vmovd\t{%1, %0|%0, %1}"
4193   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4194    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4195    (set_attr "prefix_0f" "0,*,*,*,*,*")
4196    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4197
4198 (define_split
4199   [(set (match_operand:DI 0 "memory_operand" "")
4200      (zero_extend:DI (match_dup 0)))]
4201   "TARGET_64BIT"
4202   [(set (match_dup 4) (const_int 0))]
4203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4204
4205 (define_split
4206   [(set (match_operand:DI 0 "register_operand" "")
4207         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4208    (clobber (reg:CC FLAGS_REG))]
4209   "!TARGET_64BIT && reload_completed
4210    && true_regnum (operands[0]) == true_regnum (operands[1])"
4211   [(set (match_dup 4) (const_int 0))]
4212   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4213
4214 (define_split
4215   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4216         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4217    (clobber (reg:CC FLAGS_REG))]
4218   "!TARGET_64BIT && reload_completed
4219    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4220   [(set (match_dup 3) (match_dup 1))
4221    (set (match_dup 4) (const_int 0))]
4222   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4223
4224 (define_insn "zero_extendhidi2"
4225   [(set (match_operand:DI 0 "register_operand" "=r")
4226      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4227   "TARGET_64BIT"
4228   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4229   [(set_attr "type" "imovx")
4230    (set_attr "mode" "SI")])
4231
4232 (define_insn "zero_extendqidi2"
4233   [(set (match_operand:DI 0 "register_operand" "=r")
4234      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4235   "TARGET_64BIT"
4236   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4237   [(set_attr "type" "imovx")
4238    (set_attr "mode" "SI")])
4239 \f
4240 ;; Sign extension instructions
4241
4242 (define_expand "extendsidi2"
4243   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4244                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4245               (clobber (reg:CC FLAGS_REG))
4246               (clobber (match_scratch:SI 2 ""))])]
4247   ""
4248 {
4249   if (TARGET_64BIT)
4250     {
4251       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4252       DONE;
4253     }
4254 })
4255
4256 (define_insn "*extendsidi2_1"
4257   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4258         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4259    (clobber (reg:CC FLAGS_REG))
4260    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4261   "!TARGET_64BIT"
4262   "#")
4263
4264 (define_insn "extendsidi2_rex64"
4265   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4266         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4267   "TARGET_64BIT"
4268   "@
4269    {cltq|cdqe}
4270    movs{lq|x}\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "imovx")
4272    (set_attr "mode" "DI")
4273    (set_attr "prefix_0f" "0")
4274    (set_attr "modrm" "0,1")])
4275
4276 (define_insn "extendhidi2"
4277   [(set (match_operand:DI 0 "register_operand" "=r")
4278         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4279   "TARGET_64BIT"
4280   "movs{wq|x}\t{%1, %0|%0, %1}"
4281   [(set_attr "type" "imovx")
4282    (set_attr "mode" "DI")])
4283
4284 (define_insn "extendqidi2"
4285   [(set (match_operand:DI 0 "register_operand" "=r")
4286         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4287   "TARGET_64BIT"
4288   "movs{bq|x}\t{%1, %0|%0, %1}"
4289    [(set_attr "type" "imovx")
4290     (set_attr "mode" "DI")])
4291
4292 ;; Extend to memory case when source register does die.
4293 (define_split
4294   [(set (match_operand:DI 0 "memory_operand" "")
4295         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4296    (clobber (reg:CC FLAGS_REG))
4297    (clobber (match_operand:SI 2 "register_operand" ""))]
4298   "(reload_completed
4299     && dead_or_set_p (insn, operands[1])
4300     && !reg_mentioned_p (operands[1], operands[0]))"
4301   [(set (match_dup 3) (match_dup 1))
4302    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4303               (clobber (reg:CC FLAGS_REG))])
4304    (set (match_dup 4) (match_dup 1))]
4305   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4306
4307 ;; Extend to memory case when source register does not die.
4308 (define_split
4309   [(set (match_operand:DI 0 "memory_operand" "")
4310         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4311    (clobber (reg:CC FLAGS_REG))
4312    (clobber (match_operand:SI 2 "register_operand" ""))]
4313   "reload_completed"
4314   [(const_int 0)]
4315 {
4316   split_di (&operands[0], 1, &operands[3], &operands[4]);
4317
4318   emit_move_insn (operands[3], operands[1]);
4319
4320   /* Generate a cltd if possible and doing so it profitable.  */
4321   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4322       && true_regnum (operands[1]) == AX_REG
4323       && true_regnum (operands[2]) == DX_REG)
4324     {
4325       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4326     }
4327   else
4328     {
4329       emit_move_insn (operands[2], operands[1]);
4330       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4331     }
4332   emit_move_insn (operands[4], operands[2]);
4333   DONE;
4334 })
4335
4336 ;; Extend to register case.  Optimize case where source and destination
4337 ;; registers match and cases where we can use cltd.
4338 (define_split
4339   [(set (match_operand:DI 0 "register_operand" "")
4340         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4341    (clobber (reg:CC FLAGS_REG))
4342    (clobber (match_scratch:SI 2 ""))]
4343   "reload_completed"
4344   [(const_int 0)]
4345 {
4346   split_di (&operands[0], 1, &operands[3], &operands[4]);
4347
4348   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4349     emit_move_insn (operands[3], operands[1]);
4350
4351   /* Generate a cltd if possible and doing so it profitable.  */
4352   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4353       && true_regnum (operands[3]) == AX_REG)
4354     {
4355       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4356       DONE;
4357     }
4358
4359   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4360     emit_move_insn (operands[4], operands[1]);
4361
4362   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4363   DONE;
4364 })
4365
4366 (define_insn "extendhisi2"
4367   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4368         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4369   ""
4370 {
4371   switch (get_attr_prefix_0f (insn))
4372     {
4373     case 0:
4374       return "{cwtl|cwde}";
4375     default:
4376       return "movs{wl|x}\t{%1, %0|%0, %1}";
4377     }
4378 }
4379   [(set_attr "type" "imovx")
4380    (set_attr "mode" "SI")
4381    (set (attr "prefix_0f")
4382      ;; movsx is short decodable while cwtl is vector decoded.
4383      (if_then_else (and (eq_attr "cpu" "!k6")
4384                         (eq_attr "alternative" "0"))
4385         (const_string "0")
4386         (const_string "1")))
4387    (set (attr "modrm")
4388      (if_then_else (eq_attr "prefix_0f" "0")
4389         (const_string "0")
4390         (const_string "1")))])
4391
4392 (define_insn "*extendhisi2_zext"
4393   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4394         (zero_extend:DI
4395           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4396   "TARGET_64BIT"
4397 {
4398   switch (get_attr_prefix_0f (insn))
4399     {
4400     case 0:
4401       return "{cwtl|cwde}";
4402     default:
4403       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4404     }
4405 }
4406   [(set_attr "type" "imovx")
4407    (set_attr "mode" "SI")
4408    (set (attr "prefix_0f")
4409      ;; movsx is short decodable while cwtl is vector decoded.
4410      (if_then_else (and (eq_attr "cpu" "!k6")
4411                         (eq_attr "alternative" "0"))
4412         (const_string "0")
4413         (const_string "1")))
4414    (set (attr "modrm")
4415      (if_then_else (eq_attr "prefix_0f" "0")
4416         (const_string "0")
4417         (const_string "1")))])
4418
4419 (define_insn "extendqihi2"
4420   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4421         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4422   ""
4423 {
4424   switch (get_attr_prefix_0f (insn))
4425     {
4426     case 0:
4427       return "{cbtw|cbw}";
4428     default:
4429       return "movs{bw|x}\t{%1, %0|%0, %1}";
4430     }
4431 }
4432   [(set_attr "type" "imovx")
4433    (set_attr "mode" "HI")
4434    (set (attr "prefix_0f")
4435      ;; movsx is short decodable while cwtl is vector decoded.
4436      (if_then_else (and (eq_attr "cpu" "!k6")
4437                         (eq_attr "alternative" "0"))
4438         (const_string "0")
4439         (const_string "1")))
4440    (set (attr "modrm")
4441      (if_then_else (eq_attr "prefix_0f" "0")
4442         (const_string "0")
4443         (const_string "1")))])
4444
4445 (define_insn "extendqisi2"
4446   [(set (match_operand:SI 0 "register_operand" "=r")
4447         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4448   ""
4449   "movs{bl|x}\t{%1, %0|%0, %1}"
4450    [(set_attr "type" "imovx")
4451     (set_attr "mode" "SI")])
4452
4453 (define_insn "*extendqisi2_zext"
4454   [(set (match_operand:DI 0 "register_operand" "=r")
4455         (zero_extend:DI
4456           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4457   "TARGET_64BIT"
4458   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4459    [(set_attr "type" "imovx")
4460     (set_attr "mode" "SI")])
4461 \f
4462 ;; Conversions between float and double.
4463
4464 ;; These are all no-ops in the model used for the 80387.  So just
4465 ;; emit moves.
4466
4467 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4468 (define_insn "*dummy_extendsfdf2"
4469   [(set (match_operand:DF 0 "push_operand" "=<")
4470         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4471   "0"
4472   "#")
4473
4474 (define_split
4475   [(set (match_operand:DF 0 "push_operand" "")
4476         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4477   ""
4478   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4479    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4480
4481 (define_insn "*dummy_extendsfxf2"
4482   [(set (match_operand:XF 0 "push_operand" "=<")
4483         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4484   "0"
4485   "#")
4486
4487 (define_split
4488   [(set (match_operand:XF 0 "push_operand" "")
4489         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4490   ""
4491   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4492    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4494
4495 (define_split
4496   [(set (match_operand:XF 0 "push_operand" "")
4497         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4498   ""
4499   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4500    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4501   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4502
4503 (define_expand "extendsfdf2"
4504   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4505         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4506   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4507 {
4508   /* ??? Needed for compress_float_constant since all fp constants
4509      are LEGITIMATE_CONSTANT_P.  */
4510   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4511     {
4512       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4513           && standard_80387_constant_p (operands[1]) > 0)
4514         {
4515           operands[1] = simplify_const_unary_operation
4516             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4517           emit_move_insn_1 (operands[0], operands[1]);
4518           DONE;
4519         }
4520       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4521     }
4522 })
4523
4524 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4525    cvtss2sd:
4526       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4527       cvtps2pd xmm2,xmm1
4528    We do the conversion post reload to avoid producing of 128bit spills
4529    that might lead to ICE on 32bit target.  The sequence unlikely combine
4530    anyway.  */
4531 (define_split
4532   [(set (match_operand:DF 0 "register_operand" "")
4533         (float_extend:DF
4534           (match_operand:SF 1 "nonimmediate_operand" "")))]
4535   "TARGET_USE_VECTOR_FP_CONVERTS
4536    && optimize_insn_for_speed_p ()
4537    && reload_completed && SSE_REG_P (operands[0])"
4538    [(set (match_dup 2)
4539          (float_extend:V2DF
4540            (vec_select:V2SF
4541              (match_dup 3)
4542              (parallel [(const_int 0) (const_int 1)]))))]
4543 {
4544   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4545   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4546   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4547      Try to avoid move when unpacking can be done in source.  */
4548   if (REG_P (operands[1]))
4549     {
4550       /* If it is unsafe to overwrite upper half of source, we need
4551          to move to destination and unpack there.  */
4552       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4554           && true_regnum (operands[0]) != true_regnum (operands[1]))
4555         {
4556           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4557           emit_move_insn (tmp, operands[1]);
4558         }
4559       else
4560         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4561       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4562     }
4563   else
4564     emit_insn (gen_vec_setv4sf_0 (operands[3],
4565                                   CONST0_RTX (V4SFmode), operands[1]));
4566 })
4567
4568 (define_insn "*extendsfdf2_mixed"
4569   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4570         (float_extend:DF
4571           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4572   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4573 {
4574   switch (which_alternative)
4575     {
4576     case 0:
4577     case 1:
4578       return output_387_reg_move (insn, operands);
4579
4580     case 2:
4581       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4582
4583     default:
4584       gcc_unreachable ();
4585     }
4586 }
4587   [(set_attr "type" "fmov,fmov,ssecvt")
4588    (set_attr "prefix" "orig,orig,maybe_vex")
4589    (set_attr "mode" "SF,XF,DF")])
4590
4591 (define_insn "*extendsfdf2_sse"
4592   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4593         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4594   "TARGET_SSE2 && TARGET_SSE_MATH"
4595   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4596   [(set_attr "type" "ssecvt")
4597    (set_attr "prefix" "maybe_vex")
4598    (set_attr "mode" "DF")])
4599
4600 (define_insn "*extendsfdf2_i387"
4601   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4602         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4603   "TARGET_80387"
4604   "* return output_387_reg_move (insn, operands);"
4605   [(set_attr "type" "fmov")
4606    (set_attr "mode" "SF,XF")])
4607
4608 (define_expand "extend<mode>xf2"
4609   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4610         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4611   "TARGET_80387"
4612 {
4613   /* ??? Needed for compress_float_constant since all fp constants
4614      are LEGITIMATE_CONSTANT_P.  */
4615   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4616     {
4617       if (standard_80387_constant_p (operands[1]) > 0)
4618         {
4619           operands[1] = simplify_const_unary_operation
4620             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4621           emit_move_insn_1 (operands[0], operands[1]);
4622           DONE;
4623         }
4624       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4625     }
4626 })
4627
4628 (define_insn "*extend<mode>xf2_i387"
4629   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4630         (float_extend:XF
4631           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4632   "TARGET_80387"
4633   "* return output_387_reg_move (insn, operands);"
4634   [(set_attr "type" "fmov")
4635    (set_attr "mode" "<MODE>,XF")])
4636
4637 ;; %%% This seems bad bad news.
4638 ;; This cannot output into an f-reg because there is no way to be sure
4639 ;; of truncating in that case.  Otherwise this is just like a simple move
4640 ;; insn.  So we pretend we can output to a reg in order to get better
4641 ;; register preferencing, but we really use a stack slot.
4642
4643 ;; Conversion from DFmode to SFmode.
4644
4645 (define_expand "truncdfsf2"
4646   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4647         (float_truncate:SF
4648           (match_operand:DF 1 "nonimmediate_operand" "")))]
4649   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4650 {
4651   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4652     ;
4653   else if (flag_unsafe_math_optimizations)
4654     ;
4655   else
4656     {
4657       enum ix86_stack_slot slot = (virtuals_instantiated
4658                                    ? SLOT_TEMP
4659                                    : SLOT_VIRTUAL);
4660       rtx temp = assign_386_stack_local (SFmode, slot);
4661       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4662       DONE;
4663     }
4664 })
4665
4666 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4667    cvtsd2ss:
4668       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4669       cvtpd2ps xmm2,xmm1
4670    We do the conversion post reload to avoid producing of 128bit spills
4671    that might lead to ICE on 32bit target.  The sequence unlikely combine
4672    anyway.  */
4673 (define_split
4674   [(set (match_operand:SF 0 "register_operand" "")
4675         (float_truncate:SF
4676           (match_operand:DF 1 "nonimmediate_operand" "")))]
4677   "TARGET_USE_VECTOR_FP_CONVERTS
4678    && optimize_insn_for_speed_p ()
4679    && reload_completed && SSE_REG_P (operands[0])"
4680    [(set (match_dup 2)
4681          (vec_concat:V4SF
4682            (float_truncate:V2SF
4683              (match_dup 4))
4684            (match_dup 3)))]
4685 {
4686   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4687   operands[3] = CONST0_RTX (V2SFmode);
4688   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4689   /* Use movsd for loading from memory, unpcklpd for registers.
4690      Try to avoid move when unpacking can be done in source, or SSE3
4691      movddup is available.  */
4692   if (REG_P (operands[1]))
4693     {
4694       if (!TARGET_SSE3
4695           && true_regnum (operands[0]) != true_regnum (operands[1])
4696           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4697               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4698         {
4699           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4700           emit_move_insn (tmp, operands[1]);
4701           operands[1] = tmp;
4702         }
4703       else if (!TARGET_SSE3)
4704         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4705       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4706     }
4707   else
4708     emit_insn (gen_sse2_loadlpd (operands[4],
4709                                  CONST0_RTX (V2DFmode), operands[1]));
4710 })
4711
4712 (define_expand "truncdfsf2_with_temp"
4713   [(parallel [(set (match_operand:SF 0 "" "")
4714                    (float_truncate:SF (match_operand:DF 1 "" "")))
4715               (clobber (match_operand:SF 2 "" ""))])]
4716   "")
4717
4718 (define_insn "*truncdfsf_fast_mixed"
4719   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4720         (float_truncate:SF
4721           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4722   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4723 {
4724   switch (which_alternative)
4725     {
4726     case 0:
4727       return output_387_reg_move (insn, operands);
4728     case 1:
4729       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4730     default:
4731       gcc_unreachable ();
4732     }
4733 }
4734   [(set_attr "type" "fmov,ssecvt")
4735    (set_attr "prefix" "orig,maybe_vex")
4736    (set_attr "mode" "SF")])
4737
4738 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4739 ;; because nothing we do here is unsafe.
4740 (define_insn "*truncdfsf_fast_sse"
4741   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4742         (float_truncate:SF
4743           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4744   "TARGET_SSE2 && TARGET_SSE_MATH"
4745   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4746   [(set_attr "type" "ssecvt")
4747    (set_attr "prefix" "maybe_vex")
4748    (set_attr "mode" "SF")])
4749
4750 (define_insn "*truncdfsf_fast_i387"
4751   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4752         (float_truncate:SF
4753           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4754   "TARGET_80387 && flag_unsafe_math_optimizations"
4755   "* return output_387_reg_move (insn, operands);"
4756   [(set_attr "type" "fmov")
4757    (set_attr "mode" "SF")])
4758
4759 (define_insn "*truncdfsf_mixed"
4760   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4761         (float_truncate:SF
4762           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4763    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4764   "TARGET_MIX_SSE_I387"
4765 {
4766   switch (which_alternative)
4767     {
4768     case 0:
4769       return output_387_reg_move (insn, operands);
4770     case 1:
4771       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4772
4773     default:
4774       return "#";
4775     }
4776 }
4777   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4778    (set_attr "unit" "*,*,i387,i387,i387")
4779    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4780    (set_attr "mode" "SF")])
4781
4782 (define_insn "*truncdfsf_i387"
4783   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4784         (float_truncate:SF
4785           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4786    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4787   "TARGET_80387"
4788 {
4789   switch (which_alternative)
4790     {
4791     case 0:
4792       return output_387_reg_move (insn, operands);
4793
4794     default:
4795       return "#";
4796     }
4797 }
4798   [(set_attr "type" "fmov,multi,multi,multi")
4799    (set_attr "unit" "*,i387,i387,i387")
4800    (set_attr "mode" "SF")])
4801
4802 (define_insn "*truncdfsf2_i387_1"
4803   [(set (match_operand:SF 0 "memory_operand" "=m")
4804         (float_truncate:SF
4805           (match_operand:DF 1 "register_operand" "f")))]
4806   "TARGET_80387
4807    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4808    && !TARGET_MIX_SSE_I387"
4809   "* return output_387_reg_move (insn, operands);"
4810   [(set_attr "type" "fmov")
4811    (set_attr "mode" "SF")])
4812
4813 (define_split
4814   [(set (match_operand:SF 0 "register_operand" "")
4815         (float_truncate:SF
4816          (match_operand:DF 1 "fp_register_operand" "")))
4817    (clobber (match_operand 2 "" ""))]
4818   "reload_completed"
4819   [(set (match_dup 2) (match_dup 1))
4820    (set (match_dup 0) (match_dup 2))]
4821 {
4822   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4823 })
4824
4825 ;; Conversion from XFmode to {SF,DF}mode
4826
4827 (define_expand "truncxf<mode>2"
4828   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4829                    (float_truncate:MODEF
4830                      (match_operand:XF 1 "register_operand" "")))
4831               (clobber (match_dup 2))])]
4832   "TARGET_80387"
4833 {
4834   if (flag_unsafe_math_optimizations)
4835     {
4836       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4837       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4838       if (reg != operands[0])
4839         emit_move_insn (operands[0], reg);
4840       DONE;
4841     }
4842   else
4843     {
4844      enum ix86_stack_slot slot = (virtuals_instantiated
4845                                   ? SLOT_TEMP
4846                                   : SLOT_VIRTUAL);
4847       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4848     }
4849 })
4850
4851 (define_insn "*truncxfsf2_mixed"
4852   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4853         (float_truncate:SF
4854           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4855    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4856   "TARGET_80387"
4857 {
4858   gcc_assert (!which_alternative);
4859   return output_387_reg_move (insn, operands);
4860 }
4861   [(set_attr "type" "fmov,multi,multi,multi")
4862    (set_attr "unit" "*,i387,i387,i387")
4863    (set_attr "mode" "SF")])
4864
4865 (define_insn "*truncxfdf2_mixed"
4866   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4867         (float_truncate:DF
4868           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4869    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4870   "TARGET_80387"
4871 {
4872   gcc_assert (!which_alternative);
4873   return output_387_reg_move (insn, operands);
4874 }
4875   [(set_attr "type" "fmov,multi,multi,multi")
4876    (set_attr "unit" "*,i387,i387,i387")
4877    (set_attr "mode" "DF")])
4878
4879 (define_insn "truncxf<mode>2_i387_noop"
4880   [(set (match_operand:MODEF 0 "register_operand" "=f")
4881         (float_truncate:MODEF
4882           (match_operand:XF 1 "register_operand" "f")))]
4883   "TARGET_80387 && flag_unsafe_math_optimizations"
4884   "* return output_387_reg_move (insn, operands);"
4885   [(set_attr "type" "fmov")
4886    (set_attr "mode" "<MODE>")])
4887
4888 (define_insn "*truncxf<mode>2_i387"
4889   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4890         (float_truncate:MODEF
4891           (match_operand:XF 1 "register_operand" "f")))]
4892   "TARGET_80387"
4893   "* return output_387_reg_move (insn, operands);"
4894   [(set_attr "type" "fmov")
4895    (set_attr "mode" "<MODE>")])
4896
4897 (define_split
4898   [(set (match_operand:MODEF 0 "register_operand" "")
4899         (float_truncate:MODEF
4900           (match_operand:XF 1 "register_operand" "")))
4901    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4902   "TARGET_80387 && reload_completed"
4903   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4904    (set (match_dup 0) (match_dup 2))]
4905   "")
4906
4907 (define_split
4908   [(set (match_operand:MODEF 0 "memory_operand" "")
4909         (float_truncate:MODEF
4910           (match_operand:XF 1 "register_operand" "")))
4911    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4912   "TARGET_80387"
4913   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4914   "")
4915 \f
4916 ;; Signed conversion to DImode.
4917
4918 (define_expand "fix_truncxfdi2"
4919   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4920                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4921               (clobber (reg:CC FLAGS_REG))])]
4922   "TARGET_80387"
4923 {
4924   if (TARGET_FISTTP)
4925    {
4926      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4927      DONE;
4928    }
4929 })
4930
4931 (define_expand "fix_trunc<mode>di2"
4932   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4934               (clobber (reg:CC FLAGS_REG))])]
4935   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4936 {
4937   if (TARGET_FISTTP
4938       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4939    {
4940      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4941      DONE;
4942    }
4943   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4944    {
4945      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4946      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4947      if (out != operands[0])
4948         emit_move_insn (operands[0], out);
4949      DONE;
4950    }
4951 })
4952
4953 ;; Signed conversion to SImode.
4954
4955 (define_expand "fix_truncxfsi2"
4956   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4957                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4958               (clobber (reg:CC FLAGS_REG))])]
4959   "TARGET_80387"
4960 {
4961   if (TARGET_FISTTP)
4962    {
4963      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4964      DONE;
4965    }
4966 })
4967
4968 (define_expand "fix_trunc<mode>si2"
4969   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4970                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4971               (clobber (reg:CC FLAGS_REG))])]
4972   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4973 {
4974   if (TARGET_FISTTP
4975       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4976    {
4977      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4978      DONE;
4979    }
4980   if (SSE_FLOAT_MODE_P (<MODE>mode))
4981    {
4982      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4983      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4984      if (out != operands[0])
4985         emit_move_insn (operands[0], out);
4986      DONE;
4987    }
4988 })
4989
4990 ;; Signed conversion to HImode.
4991
4992 (define_expand "fix_trunc<mode>hi2"
4993   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4994                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4995               (clobber (reg:CC FLAGS_REG))])]
4996   "TARGET_80387
4997    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4998 {
4999   if (TARGET_FISTTP)
5000    {
5001      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5002      DONE;
5003    }
5004 })
5005
5006 ;; Unsigned conversion to SImode.
5007
5008 (define_expand "fixuns_trunc<mode>si2"
5009   [(parallel
5010     [(set (match_operand:SI 0 "register_operand" "")
5011           (unsigned_fix:SI
5012             (match_operand:MODEF 1 "nonimmediate_operand" "")))
5013      (use (match_dup 2))
5014      (clobber (match_scratch:<ssevecmode> 3 ""))
5015      (clobber (match_scratch:<ssevecmode> 4 ""))])]
5016   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5017 {
5018   enum machine_mode mode = <MODE>mode;
5019   enum machine_mode vecmode = <ssevecmode>mode;
5020   REAL_VALUE_TYPE TWO31r;
5021   rtx two31;
5022
5023   if (optimize_insn_for_size_p ())
5024     FAIL;
5025
5026   real_ldexp (&TWO31r, &dconst1, 31);
5027   two31 = const_double_from_real_value (TWO31r, mode);
5028   two31 = ix86_build_const_vector (mode, true, two31);
5029   operands[2] = force_reg (vecmode, two31);
5030 })
5031
5032 (define_insn_and_split "*fixuns_trunc<mode>_1"
5033   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5034         (unsigned_fix:SI
5035           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5036    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5037    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5038    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5039   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5040    && optimize_function_for_speed_p (cfun)"
5041   "#"
5042   "&& reload_completed"
5043   [(const_int 0)]
5044 {
5045   ix86_split_convert_uns_si_sse (operands);
5046   DONE;
5047 })
5048
5049 ;; Unsigned conversion to HImode.
5050 ;; Without these patterns, we'll try the unsigned SI conversion which
5051 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5052
5053 (define_expand "fixuns_trunc<mode>hi2"
5054   [(set (match_dup 2)
5055         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5056    (set (match_operand:HI 0 "nonimmediate_operand" "")
5057         (subreg:HI (match_dup 2) 0))]
5058   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5059   "operands[2] = gen_reg_rtx (SImode);")
5060
5061 ;; When SSE is available, it is always faster to use it!
5062 (define_insn "fix_trunc<mode>di_sse"
5063   [(set (match_operand:DI 0 "register_operand" "=r,r")
5064         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5065   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5066    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5067   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5068   [(set_attr "type" "sseicvt")
5069    (set_attr "prefix" "maybe_vex")
5070    (set_attr "prefix_rex" "1")
5071    (set_attr "mode" "<MODE>")
5072    (set_attr "athlon_decode" "double,vector")
5073    (set_attr "amdfam10_decode" "double,double")])
5074
5075 (define_insn "fix_trunc<mode>si_sse"
5076   [(set (match_operand:SI 0 "register_operand" "=r,r")
5077         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5078   "SSE_FLOAT_MODE_P (<MODE>mode)
5079    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5080   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5081   [(set_attr "type" "sseicvt")
5082    (set_attr "prefix" "maybe_vex")
5083    (set_attr "mode" "<MODE>")
5084    (set_attr "athlon_decode" "double,vector")
5085    (set_attr "amdfam10_decode" "double,double")])
5086
5087 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5088 (define_peephole2
5089   [(set (match_operand:MODEF 0 "register_operand" "")
5090         (match_operand:MODEF 1 "memory_operand" ""))
5091    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5092         (fix:SSEMODEI24 (match_dup 0)))]
5093   "TARGET_SHORTEN_X87_SSE
5094    && peep2_reg_dead_p (2, operands[0])"
5095   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5096   "")
5097
5098 ;; Avoid vector decoded forms of the instruction.
5099 (define_peephole2
5100   [(match_scratch:DF 2 "Y2")
5101    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5102         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5103   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5104   [(set (match_dup 2) (match_dup 1))
5105    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5106   "")
5107
5108 (define_peephole2
5109   [(match_scratch:SF 2 "x")
5110    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5111         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5112   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5113   [(set (match_dup 2) (match_dup 1))
5114    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5115   "")
5116
5117 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5118   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5119         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5120   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121    && TARGET_FISTTP
5122    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5123          && (TARGET_64BIT || <MODE>mode != DImode))
5124         && TARGET_SSE_MATH)
5125    && !(reload_completed || reload_in_progress)"
5126   "#"
5127   "&& 1"
5128   [(const_int 0)]
5129 {
5130   if (memory_operand (operands[0], VOIDmode))
5131     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5132   else
5133     {
5134       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5135       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5136                                                             operands[1],
5137                                                             operands[2]));
5138     }
5139   DONE;
5140 }
5141   [(set_attr "type" "fisttp")
5142    (set_attr "mode" "<MODE>")])
5143
5144 (define_insn "fix_trunc<mode>_i387_fisttp"
5145   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5146         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5147    (clobber (match_scratch:XF 2 "=&1f"))]
5148   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5149    && TARGET_FISTTP
5150    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5151          && (TARGET_64BIT || <MODE>mode != DImode))
5152         && TARGET_SSE_MATH)"
5153   "* return output_fix_trunc (insn, operands, 1);"
5154   [(set_attr "type" "fisttp")
5155    (set_attr "mode" "<MODE>")])
5156
5157 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5158   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5159         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5160    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5161    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5162   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5163    && TARGET_FISTTP
5164    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5165         && (TARGET_64BIT || <MODE>mode != DImode))
5166         && TARGET_SSE_MATH)"
5167   "#"
5168   [(set_attr "type" "fisttp")
5169    (set_attr "mode" "<MODE>")])
5170
5171 (define_split
5172   [(set (match_operand:X87MODEI 0 "register_operand" "")
5173         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5174    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5175    (clobber (match_scratch 3 ""))]
5176   "reload_completed"
5177   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5178               (clobber (match_dup 3))])
5179    (set (match_dup 0) (match_dup 2))]
5180   "")
5181
5182 (define_split
5183   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5184         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5185    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5186    (clobber (match_scratch 3 ""))]
5187   "reload_completed"
5188   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5189               (clobber (match_dup 3))])]
5190   "")
5191
5192 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5193 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5194 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5195 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5196 ;; function in i386.c.
5197 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5198   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5199         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5200    (clobber (reg:CC FLAGS_REG))]
5201   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5202    && !TARGET_FISTTP
5203    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5204          && (TARGET_64BIT || <MODE>mode != DImode))
5205    && !(reload_completed || reload_in_progress)"
5206   "#"
5207   "&& 1"
5208   [(const_int 0)]
5209 {
5210   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5211
5212   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5213   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5214   if (memory_operand (operands[0], VOIDmode))
5215     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5216                                          operands[2], operands[3]));
5217   else
5218     {
5219       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5220       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5221                                                      operands[2], operands[3],
5222                                                      operands[4]));
5223     }
5224   DONE;
5225 }
5226   [(set_attr "type" "fistp")
5227    (set_attr "i387_cw" "trunc")
5228    (set_attr "mode" "<MODE>")])
5229
5230 (define_insn "fix_truncdi_i387"
5231   [(set (match_operand:DI 0 "memory_operand" "=m")
5232         (fix:DI (match_operand 1 "register_operand" "f")))
5233    (use (match_operand:HI 2 "memory_operand" "m"))
5234    (use (match_operand:HI 3 "memory_operand" "m"))
5235    (clobber (match_scratch:XF 4 "=&1f"))]
5236   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5237    && !TARGET_FISTTP
5238    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5239   "* return output_fix_trunc (insn, operands, 0);"
5240   [(set_attr "type" "fistp")
5241    (set_attr "i387_cw" "trunc")
5242    (set_attr "mode" "DI")])
5243
5244 (define_insn "fix_truncdi_i387_with_temp"
5245   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5246         (fix:DI (match_operand 1 "register_operand" "f,f")))
5247    (use (match_operand:HI 2 "memory_operand" "m,m"))
5248    (use (match_operand:HI 3 "memory_operand" "m,m"))
5249    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5250    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5251   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5252    && !TARGET_FISTTP
5253    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5254   "#"
5255   [(set_attr "type" "fistp")
5256    (set_attr "i387_cw" "trunc")
5257    (set_attr "mode" "DI")])
5258
5259 (define_split
5260   [(set (match_operand:DI 0 "register_operand" "")
5261         (fix:DI (match_operand 1 "register_operand" "")))
5262    (use (match_operand:HI 2 "memory_operand" ""))
5263    (use (match_operand:HI 3 "memory_operand" ""))
5264    (clobber (match_operand:DI 4 "memory_operand" ""))
5265    (clobber (match_scratch 5 ""))]
5266   "reload_completed"
5267   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5268               (use (match_dup 2))
5269               (use (match_dup 3))
5270               (clobber (match_dup 5))])
5271    (set (match_dup 0) (match_dup 4))]
5272   "")
5273
5274 (define_split
5275   [(set (match_operand:DI 0 "memory_operand" "")
5276         (fix:DI (match_operand 1 "register_operand" "")))
5277    (use (match_operand:HI 2 "memory_operand" ""))
5278    (use (match_operand:HI 3 "memory_operand" ""))
5279    (clobber (match_operand:DI 4 "memory_operand" ""))
5280    (clobber (match_scratch 5 ""))]
5281   "reload_completed"
5282   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5283               (use (match_dup 2))
5284               (use (match_dup 3))
5285               (clobber (match_dup 5))])]
5286   "")
5287
5288 (define_insn "fix_trunc<mode>_i387"
5289   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5290         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5291    (use (match_operand:HI 2 "memory_operand" "m"))
5292    (use (match_operand:HI 3 "memory_operand" "m"))]
5293   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5294    && !TARGET_FISTTP
5295    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5296   "* return output_fix_trunc (insn, operands, 0);"
5297   [(set_attr "type" "fistp")
5298    (set_attr "i387_cw" "trunc")
5299    (set_attr "mode" "<MODE>")])
5300
5301 (define_insn "fix_trunc<mode>_i387_with_temp"
5302   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5303         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5304    (use (match_operand:HI 2 "memory_operand" "m,m"))
5305    (use (match_operand:HI 3 "memory_operand" "m,m"))
5306    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5307   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5308    && !TARGET_FISTTP
5309    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5310   "#"
5311   [(set_attr "type" "fistp")
5312    (set_attr "i387_cw" "trunc")
5313    (set_attr "mode" "<MODE>")])
5314
5315 (define_split
5316   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5317         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5318    (use (match_operand:HI 2 "memory_operand" ""))
5319    (use (match_operand:HI 3 "memory_operand" ""))
5320    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5321   "reload_completed"
5322   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5323               (use (match_dup 2))
5324               (use (match_dup 3))])
5325    (set (match_dup 0) (match_dup 4))]
5326   "")
5327
5328 (define_split
5329   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5330         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5331    (use (match_operand:HI 2 "memory_operand" ""))
5332    (use (match_operand:HI 3 "memory_operand" ""))
5333    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5334   "reload_completed"
5335   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5336               (use (match_dup 2))
5337               (use (match_dup 3))])]
5338   "")
5339
5340 (define_insn "x86_fnstcw_1"
5341   [(set (match_operand:HI 0 "memory_operand" "=m")
5342         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5343   "TARGET_80387"
5344   "fnstcw\t%0"
5345   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5346    (set_attr "mode" "HI")
5347    (set_attr "unit" "i387")])
5348
5349 (define_insn "x86_fldcw_1"
5350   [(set (reg:HI FPCR_REG)
5351         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5352   "TARGET_80387"
5353   "fldcw\t%0"
5354   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5355    (set_attr "mode" "HI")
5356    (set_attr "unit" "i387")
5357    (set_attr "athlon_decode" "vector")
5358    (set_attr "amdfam10_decode" "vector")])
5359 \f
5360 ;; Conversion between fixed point and floating point.
5361
5362 ;; Even though we only accept memory inputs, the backend _really_
5363 ;; wants to be able to do this between registers.
5364
5365 (define_expand "floathi<mode>2"
5366   [(set (match_operand:X87MODEF 0 "register_operand" "")
5367         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5368   "TARGET_80387
5369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5370        || TARGET_MIX_SSE_I387)"
5371   "")
5372
5373 ;; Pre-reload splitter to add memory clobber to the pattern.
5374 (define_insn_and_split "*floathi<mode>2_1"
5375   [(set (match_operand:X87MODEF 0 "register_operand" "")
5376         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5377   "TARGET_80387
5378    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5379        || TARGET_MIX_SSE_I387)
5380    && !(reload_completed || reload_in_progress)"
5381   "#"
5382   "&& 1"
5383   [(parallel [(set (match_dup 0)
5384               (float:X87MODEF (match_dup 1)))
5385    (clobber (match_dup 2))])]
5386   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5387
5388 (define_insn "*floathi<mode>2_i387_with_temp"
5389   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5390         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5391   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5392   "TARGET_80387
5393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5394        || TARGET_MIX_SSE_I387)"
5395   "#"
5396   [(set_attr "type" "fmov,multi")
5397    (set_attr "mode" "<MODE>")
5398    (set_attr "unit" "*,i387")
5399    (set_attr "fp_int_src" "true")])
5400
5401 (define_insn "*floathi<mode>2_i387"
5402   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5403         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5404   "TARGET_80387
5405    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5406        || TARGET_MIX_SSE_I387)"
5407   "fild%Z1\t%1"
5408   [(set_attr "type" "fmov")
5409    (set_attr "mode" "<MODE>")
5410    (set_attr "fp_int_src" "true")])
5411
5412 (define_split
5413   [(set (match_operand:X87MODEF 0 "register_operand" "")
5414         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5415    (clobber (match_operand:HI 2 "memory_operand" ""))]
5416   "TARGET_80387
5417    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5418        || TARGET_MIX_SSE_I387)
5419    && reload_completed"
5420   [(set (match_dup 2) (match_dup 1))
5421    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5422   "")
5423
5424 (define_split
5425   [(set (match_operand:X87MODEF 0 "register_operand" "")
5426         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5427    (clobber (match_operand:HI 2 "memory_operand" ""))]
5428    "TARGET_80387
5429     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5430         || TARGET_MIX_SSE_I387)
5431     && reload_completed"
5432   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5433   "")
5434
5435 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5436   [(set (match_operand:X87MODEF 0 "register_operand" "")
5437         (float:X87MODEF
5438           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5439   "TARGET_80387
5440    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5441        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5442   "
5443 {
5444   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5445         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5446       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5447     {
5448       rtx reg = gen_reg_rtx (XFmode);
5449       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5450 /* Avoid references to nonexistent function in dead code in XFmode case.  */
5451 #define gen_truncxfxf2 gen_truncxfdf2
5452       emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5453 #undef gen_truncxfxf2
5454       DONE;
5455     }
5456 }")
5457
5458 ;; Pre-reload splitter to add memory clobber to the pattern.
5459 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5460   [(set (match_operand:X87MODEF 0 "register_operand" "")
5461         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5462   "((TARGET_80387
5463      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5464      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5466          || TARGET_MIX_SSE_I387))
5467     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5469         && ((<SSEMODEI24:MODE>mode == SImode
5470              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5471              && optimize_function_for_speed_p (cfun)
5472              && flag_trapping_math)
5473             || !(TARGET_INTER_UNIT_CONVERSIONS
5474                  || optimize_function_for_size_p (cfun)))))
5475    && !(reload_completed || reload_in_progress)"
5476   "#"
5477   "&& 1"
5478   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5479               (clobber (match_dup 2))])]
5480 {
5481   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5482
5483   /* Avoid store forwarding (partial memory) stall penalty
5484      by passing DImode value through XMM registers.  */
5485   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5486       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5487       && optimize_function_for_speed_p (cfun))
5488     {
5489       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5490                                                             operands[1],
5491                                                             operands[2]));
5492       DONE;
5493     }
5494 })
5495
5496 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5497   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5498         (float:MODEF
5499           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5500    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5501   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5502    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5503   "#"
5504   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5505    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5506    (set_attr "unit" "*,i387,*,*,*")
5507    (set_attr "athlon_decode" "*,*,double,direct,double")
5508    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5509    (set_attr "fp_int_src" "true")])
5510
5511 (define_insn "*floatsi<mode>2_vector_mixed"
5512   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5513         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5514   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5515    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5516   "@
5517    fild%Z1\t%1
5518    #"
5519   [(set_attr "type" "fmov,sseicvt")
5520    (set_attr "mode" "<MODE>,<ssevecmode>")
5521    (set_attr "unit" "i387,*")
5522    (set_attr "athlon_decode" "*,direct")
5523    (set_attr "amdfam10_decode" "*,double")
5524    (set_attr "fp_int_src" "true")])
5525
5526 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5527   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5528         (float:MODEF
5529           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5530   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5531   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5532    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5533   "#"
5534   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5535    (set_attr "mode" "<MODEF:MODE>")
5536    (set_attr "unit" "*,i387,*,*")
5537    (set_attr "athlon_decode" "*,*,double,direct")
5538    (set_attr "amdfam10_decode" "*,*,vector,double")
5539    (set_attr "fp_int_src" "true")])
5540
5541 (define_split
5542   [(set (match_operand:MODEF 0 "register_operand" "")
5543         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5544    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5545   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5546    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5547    && TARGET_INTER_UNIT_CONVERSIONS
5548    && reload_completed
5549    && (SSE_REG_P (operands[0])
5550        || (GET_CODE (operands[0]) == SUBREG
5551            && SSE_REG_P (operands[0])))"
5552   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5553   "")
5554
5555 (define_split
5556   [(set (match_operand:MODEF 0 "register_operand" "")
5557         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5558    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5559   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5560    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5561    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5562    && reload_completed
5563    && (SSE_REG_P (operands[0])
5564        || (GET_CODE (operands[0]) == SUBREG
5565            && SSE_REG_P (operands[0])))"
5566   [(set (match_dup 2) (match_dup 1))
5567    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5568   "")
5569
5570 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5571   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5572         (float:MODEF
5573           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5574   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5575    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5576    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5577   "@
5578    fild%Z1\t%1
5579    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5580    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5581   [(set_attr "type" "fmov,sseicvt,sseicvt")
5582    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5583    (set_attr "mode" "<MODEF:MODE>")
5584    (set (attr "prefix_rex")
5585      (if_then_else
5586        (and (eq_attr "prefix" "maybe_vex")
5587             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5588        (const_string "1")
5589        (const_string "*")))
5590    (set_attr "unit" "i387,*,*")
5591    (set_attr "athlon_decode" "*,double,direct")
5592    (set_attr "amdfam10_decode" "*,vector,double")
5593    (set_attr "fp_int_src" "true")])
5594
5595 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5596   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5597         (float:MODEF
5598           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5599   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5600    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5601    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5602   "@
5603    fild%Z1\t%1
5604    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5605   [(set_attr "type" "fmov,sseicvt")
5606    (set_attr "prefix" "orig,maybe_vex")
5607    (set_attr "mode" "<MODEF:MODE>")
5608    (set (attr "prefix_rex")
5609      (if_then_else
5610        (and (eq_attr "prefix" "maybe_vex")
5611             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5612        (const_string "1")
5613        (const_string "*")))
5614    (set_attr "athlon_decode" "*,direct")
5615    (set_attr "amdfam10_decode" "*,double")
5616    (set_attr "fp_int_src" "true")])
5617
5618 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5619   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5620         (float:MODEF
5621           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5622    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5623   "TARGET_SSE2 && TARGET_SSE_MATH
5624    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5625   "#"
5626   [(set_attr "type" "sseicvt")
5627    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5628    (set_attr "athlon_decode" "double,direct,double")
5629    (set_attr "amdfam10_decode" "vector,double,double")
5630    (set_attr "fp_int_src" "true")])
5631
5632 (define_insn "*floatsi<mode>2_vector_sse"
5633   [(set (match_operand:MODEF 0 "register_operand" "=x")
5634         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5635   "TARGET_SSE2 && TARGET_SSE_MATH
5636    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5637   "#"
5638   [(set_attr "type" "sseicvt")
5639    (set_attr "mode" "<MODE>")
5640    (set_attr "athlon_decode" "direct")
5641    (set_attr "amdfam10_decode" "double")
5642    (set_attr "fp_int_src" "true")])
5643
5644 (define_split
5645   [(set (match_operand:MODEF 0 "register_operand" "")
5646         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5647    (clobber (match_operand:SI 2 "memory_operand" ""))]
5648   "TARGET_SSE2 && TARGET_SSE_MATH
5649    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5650    && reload_completed
5651    && (SSE_REG_P (operands[0])
5652        || (GET_CODE (operands[0]) == SUBREG
5653            && SSE_REG_P (operands[0])))"
5654   [(const_int 0)]
5655 {
5656   rtx op1 = operands[1];
5657
5658   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5659                                      <MODE>mode, 0);
5660   if (GET_CODE (op1) == SUBREG)
5661     op1 = SUBREG_REG (op1);
5662
5663   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5664     {
5665       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5666       emit_insn (gen_sse2_loadld (operands[4],
5667                                   CONST0_RTX (V4SImode), operands[1]));
5668     }
5669   /* We can ignore possible trapping value in the
5670      high part of SSE register for non-trapping math. */
5671   else if (SSE_REG_P (op1) && !flag_trapping_math)
5672     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5673   else
5674     {
5675       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5676       emit_move_insn (operands[2], operands[1]);
5677       emit_insn (gen_sse2_loadld (operands[4],
5678                                   CONST0_RTX (V4SImode), operands[2]));
5679     }
5680   emit_insn
5681     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5682   DONE;
5683 })
5684
5685 (define_split
5686   [(set (match_operand:MODEF 0 "register_operand" "")
5687         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5688    (clobber (match_operand:SI 2 "memory_operand" ""))]
5689   "TARGET_SSE2 && TARGET_SSE_MATH
5690    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5691    && reload_completed
5692    && (SSE_REG_P (operands[0])
5693        || (GET_CODE (operands[0]) == SUBREG
5694            && SSE_REG_P (operands[0])))"
5695   [(const_int 0)]
5696 {
5697   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5698                                      <MODE>mode, 0);
5699   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5700
5701   emit_insn (gen_sse2_loadld (operands[4],
5702                               CONST0_RTX (V4SImode), operands[1]));
5703   emit_insn
5704     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5705   DONE;
5706 })
5707
5708 (define_split
5709   [(set (match_operand:MODEF 0 "register_operand" "")
5710         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5711   "TARGET_SSE2 && TARGET_SSE_MATH
5712    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5713    && reload_completed
5714    && (SSE_REG_P (operands[0])
5715        || (GET_CODE (operands[0]) == SUBREG
5716            && SSE_REG_P (operands[0])))"
5717   [(const_int 0)]
5718 {
5719   rtx op1 = operands[1];
5720
5721   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5722                                      <MODE>mode, 0);
5723   if (GET_CODE (op1) == SUBREG)
5724     op1 = SUBREG_REG (op1);
5725
5726   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5727     {
5728       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5729       emit_insn (gen_sse2_loadld (operands[4],
5730                                   CONST0_RTX (V4SImode), operands[1]));
5731     }
5732   /* We can ignore possible trapping value in the
5733      high part of SSE register for non-trapping math. */
5734   else if (SSE_REG_P (op1) && !flag_trapping_math)
5735     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5736   else
5737     gcc_unreachable ();
5738   emit_insn
5739     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5740   DONE;
5741 })
5742
5743 (define_split
5744   [(set (match_operand:MODEF 0 "register_operand" "")
5745         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5746   "TARGET_SSE2 && TARGET_SSE_MATH
5747    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5748    && reload_completed
5749    && (SSE_REG_P (operands[0])
5750        || (GET_CODE (operands[0]) == SUBREG
5751            && SSE_REG_P (operands[0])))"
5752   [(const_int 0)]
5753 {
5754   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5755                                      <MODE>mode, 0);
5756   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5757
5758   emit_insn (gen_sse2_loadld (operands[4],
5759                               CONST0_RTX (V4SImode), operands[1]));
5760   emit_insn
5761     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5762   DONE;
5763 })
5764
5765 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5766   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5767         (float:MODEF
5768           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5769   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5770   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5771    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5772   "#"
5773   [(set_attr "type" "sseicvt")
5774    (set_attr "mode" "<MODEF:MODE>")
5775    (set_attr "athlon_decode" "double,direct")
5776    (set_attr "amdfam10_decode" "vector,double")
5777    (set_attr "fp_int_src" "true")])
5778
5779 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5780   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5781         (float:MODEF
5782           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5783   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5784    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5785    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5786   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5787   [(set_attr "type" "sseicvt")
5788    (set_attr "prefix" "maybe_vex")
5789    (set_attr "mode" "<MODEF:MODE>")
5790    (set (attr "prefix_rex")
5791      (if_then_else
5792        (and (eq_attr "prefix" "maybe_vex")
5793             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5794        (const_string "1")
5795        (const_string "*")))
5796    (set_attr "athlon_decode" "double,direct")
5797    (set_attr "amdfam10_decode" "vector,double")
5798    (set_attr "fp_int_src" "true")])
5799
5800 (define_split
5801   [(set (match_operand:MODEF 0 "register_operand" "")
5802         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5803    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5804   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5805    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5806    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5807    && reload_completed
5808    && (SSE_REG_P (operands[0])
5809        || (GET_CODE (operands[0]) == SUBREG
5810            && SSE_REG_P (operands[0])))"
5811   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5812   "")
5813
5814 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5815   [(set (match_operand:MODEF 0 "register_operand" "=x")
5816         (float:MODEF
5817           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5818   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5819    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5820    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5821   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5822   [(set_attr "type" "sseicvt")
5823    (set_attr "prefix" "maybe_vex")
5824    (set_attr "mode" "<MODEF:MODE>")
5825    (set (attr "prefix_rex")
5826      (if_then_else
5827        (and (eq_attr "prefix" "maybe_vex")
5828             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5829        (const_string "1")
5830        (const_string "*")))
5831    (set_attr "athlon_decode" "direct")
5832    (set_attr "amdfam10_decode" "double")
5833    (set_attr "fp_int_src" "true")])
5834
5835 (define_split
5836   [(set (match_operand:MODEF 0 "register_operand" "")
5837         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5838    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5839   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5840    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5841    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5842    && reload_completed
5843    && (SSE_REG_P (operands[0])
5844        || (GET_CODE (operands[0]) == SUBREG
5845            && SSE_REG_P (operands[0])))"
5846   [(set (match_dup 2) (match_dup 1))
5847    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5848   "")
5849
5850 (define_split
5851   [(set (match_operand:MODEF 0 "register_operand" "")
5852         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5853    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5854   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5855    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5856    && reload_completed
5857    && (SSE_REG_P (operands[0])
5858        || (GET_CODE (operands[0]) == SUBREG
5859            && SSE_REG_P (operands[0])))"
5860   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5861   "")
5862
5863 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5864   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5865         (float:X87MODEF
5866           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5867   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5868   "TARGET_80387
5869    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5870   "@
5871    fild%Z1\t%1
5872    #"
5873   [(set_attr "type" "fmov,multi")
5874    (set_attr "mode" "<X87MODEF:MODE>")
5875    (set_attr "unit" "*,i387")
5876    (set_attr "fp_int_src" "true")])
5877
5878 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5879   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5880         (float:X87MODEF
5881           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5882   "TARGET_80387
5883    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5884   "fild%Z1\t%1"
5885   [(set_attr "type" "fmov")
5886    (set_attr "mode" "<X87MODEF:MODE>")
5887    (set_attr "fp_int_src" "true")])
5888
5889 (define_split
5890   [(set (match_operand:X87MODEF 0 "register_operand" "")
5891         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5892    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5893   "TARGET_80387
5894    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5895    && reload_completed
5896    && FP_REG_P (operands[0])"
5897   [(set (match_dup 2) (match_dup 1))
5898    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5899   "")
5900
5901 (define_split
5902   [(set (match_operand:X87MODEF 0 "register_operand" "")
5903         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5904    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5905   "TARGET_80387
5906    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5907    && reload_completed
5908    && FP_REG_P (operands[0])"
5909   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5910   "")
5911
5912 ;; Avoid store forwarding (partial memory) stall penalty
5913 ;; by passing DImode value through XMM registers.  */
5914
5915 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5916   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5917         (float:X87MODEF
5918           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5919    (clobber (match_scratch:V4SI 3 "=X,x"))
5920    (clobber (match_scratch:V4SI 4 "=X,x"))
5921    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5922   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5923    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5924    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5925   "#"
5926   [(set_attr "type" "multi")
5927    (set_attr "mode" "<X87MODEF:MODE>")
5928    (set_attr "unit" "i387")
5929    (set_attr "fp_int_src" "true")])
5930
5931 (define_split
5932   [(set (match_operand:X87MODEF 0 "register_operand" "")
5933         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5934    (clobber (match_scratch:V4SI 3 ""))
5935    (clobber (match_scratch:V4SI 4 ""))
5936    (clobber (match_operand:DI 2 "memory_operand" ""))]
5937   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5938    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5939    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5940    && reload_completed
5941    && FP_REG_P (operands[0])"
5942   [(set (match_dup 2) (match_dup 3))
5943    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5944 {
5945   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5946      Assemble the 64-bit DImode value in an xmm register.  */
5947   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5948                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5949   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5950                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5951   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5952
5953   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5954 })
5955
5956 (define_split
5957   [(set (match_operand:X87MODEF 0 "register_operand" "")
5958         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5959    (clobber (match_scratch:V4SI 3 ""))
5960    (clobber (match_scratch:V4SI 4 ""))
5961    (clobber (match_operand:DI 2 "memory_operand" ""))]
5962   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5963    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5964    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5965    && reload_completed
5966    && FP_REG_P (operands[0])"
5967   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5968   "")
5969
5970 ;; Avoid store forwarding (partial memory) stall penalty by extending
5971 ;; SImode value to DImode through XMM register instead of pushing two
5972 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5973 ;; targets benefit from this optimization. Also note that fild
5974 ;; loads from memory only.
5975
5976 (define_insn "*floatunssi<mode>2_1"
5977   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5978         (unsigned_float:X87MODEF
5979           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5980    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5981    (clobber (match_scratch:SI 3 "=X,x"))]
5982   "!TARGET_64BIT
5983    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5984    && TARGET_SSE"
5985   "#"
5986   [(set_attr "type" "multi")
5987    (set_attr "mode" "<MODE>")])
5988
5989 (define_split
5990   [(set (match_operand:X87MODEF 0 "register_operand" "")
5991         (unsigned_float:X87MODEF
5992           (match_operand:SI 1 "register_operand" "")))
5993    (clobber (match_operand:DI 2 "memory_operand" ""))
5994    (clobber (match_scratch:SI 3 ""))]
5995   "!TARGET_64BIT
5996    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5997    && TARGET_SSE
5998    && reload_completed"
5999   [(set (match_dup 2) (match_dup 1))
6000    (set (match_dup 0)
6001         (float:X87MODEF (match_dup 2)))]
6002   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6003
6004 (define_split
6005   [(set (match_operand:X87MODEF 0 "register_operand" "")
6006         (unsigned_float:X87MODEF
6007           (match_operand:SI 1 "memory_operand" "")))
6008    (clobber (match_operand:DI 2 "memory_operand" ""))
6009    (clobber (match_scratch:SI 3 ""))]
6010   "!TARGET_64BIT
6011    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6012    && TARGET_SSE
6013    && reload_completed"
6014   [(set (match_dup 2) (match_dup 3))
6015    (set (match_dup 0)
6016         (float:X87MODEF (match_dup 2)))]
6017 {
6018   emit_move_insn (operands[3], operands[1]);
6019   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6020 })
6021
6022 (define_expand "floatunssi<mode>2"
6023   [(parallel
6024      [(set (match_operand:X87MODEF 0 "register_operand" "")
6025            (unsigned_float:X87MODEF
6026              (match_operand:SI 1 "nonimmediate_operand" "")))
6027       (clobber (match_dup 2))
6028       (clobber (match_scratch:SI 3 ""))])]
6029   "!TARGET_64BIT
6030    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6031         && TARGET_SSE)
6032        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6033 {
6034   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6035     {
6036       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6037       DONE;
6038     }
6039   else
6040     {
6041       enum ix86_stack_slot slot = (virtuals_instantiated
6042                                    ? SLOT_TEMP
6043                                    : SLOT_VIRTUAL);
6044       operands[2] = assign_386_stack_local (DImode, slot);
6045     }
6046 })
6047
6048 (define_expand "floatunsdisf2"
6049   [(use (match_operand:SF 0 "register_operand" ""))
6050    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6051   "TARGET_64BIT && TARGET_SSE_MATH"
6052   "x86_emit_floatuns (operands); DONE;")
6053
6054 (define_expand "floatunsdidf2"
6055   [(use (match_operand:DF 0 "register_operand" ""))
6056    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6057   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6058    && TARGET_SSE2 && TARGET_SSE_MATH"
6059 {
6060   if (TARGET_64BIT)
6061     x86_emit_floatuns (operands);
6062   else
6063     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6064   DONE;
6065 })
6066 \f
6067 ;; Add instructions
6068
6069 ;; %%% splits for addditi3
6070
6071 (define_expand "addti3"
6072   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6073         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6074                  (match_operand:TI 2 "x86_64_general_operand" "")))]
6075   "TARGET_64BIT"
6076   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
6077
6078 (define_insn "*addti3_1"
6079   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6080         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
6081                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6082    (clobber (reg:CC FLAGS_REG))]
6083   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
6084   "#")
6085
6086 (define_split
6087   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6088         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6089                  (match_operand:TI 2 "x86_64_general_operand" "")))
6090    (clobber (reg:CC FLAGS_REG))]
6091   "TARGET_64BIT && reload_completed"
6092   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6093                                           UNSPEC_ADD_CARRY))
6094               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
6095    (parallel [(set (match_dup 3)
6096                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6097                                      (match_dup 4))
6098                             (match_dup 5)))
6099               (clobber (reg:CC FLAGS_REG))])]
6100   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
6101
6102 ;; %%% splits for addsidi3
6103 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6104 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
6105 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
6106
6107 (define_expand "adddi3"
6108   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6109         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6110                  (match_operand:DI 2 "x86_64_general_operand" "")))]
6111   ""
6112   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
6113
6114 (define_insn "*adddi3_1"
6115   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6116         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6117                  (match_operand:DI 2 "general_operand" "roiF,riF")))
6118    (clobber (reg:CC FLAGS_REG))]
6119   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6120   "#")
6121
6122 (define_split
6123   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6124         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6125                  (match_operand:DI 2 "general_operand" "")))
6126    (clobber (reg:CC FLAGS_REG))]
6127   "!TARGET_64BIT && reload_completed"
6128   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6129                                           UNSPEC_ADD_CARRY))
6130               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6131    (parallel [(set (match_dup 3)
6132                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6133                                      (match_dup 4))
6134                             (match_dup 5)))
6135               (clobber (reg:CC FLAGS_REG))])]
6136   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
6137
6138 (define_insn "adddi3_carry_rex64"
6139   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6140           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6141                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6142                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6143    (clobber (reg:CC FLAGS_REG))]
6144   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6145   "adc{q}\t{%2, %0|%0, %2}"
6146   [(set_attr "type" "alu")
6147    (set_attr "use_carry" "1")
6148    (set_attr "pent_pair" "pu")
6149    (set_attr "mode" "DI")])
6150
6151 (define_insn "*adddi3_cc_rex64"
6152   [(set (reg:CC FLAGS_REG)
6153         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6154                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6155                    UNSPEC_ADD_CARRY))
6156    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6157         (plus:DI (match_dup 1) (match_dup 2)))]
6158   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6159   "add{q}\t{%2, %0|%0, %2}"
6160   [(set_attr "type" "alu")
6161    (set_attr "mode" "DI")])
6162
6163 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6164   [(set (reg:CCC FLAGS_REG)
6165         (compare:CCC
6166             (plusminus:SWI
6167                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6168                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6169             (match_dup 1)))
6170    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6171         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6172   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6173   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6174   [(set_attr "type" "alu")
6175    (set_attr "mode" "<MODE>")])
6176
6177 (define_insn "*add<mode>3_cconly_overflow"
6178   [(set (reg:CCC FLAGS_REG)
6179         (compare:CCC
6180                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6181                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6182                 (match_dup 1)))
6183    (clobber (match_scratch:SWI 0 "=<r>"))]
6184   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6185   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6186   [(set_attr "type" "alu")
6187    (set_attr "mode" "<MODE>")])
6188
6189 (define_insn "*sub<mode>3_cconly_overflow"
6190   [(set (reg:CCC FLAGS_REG)
6191         (compare:CCC
6192              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6193                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6194              (match_dup 0)))]
6195   ""
6196   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6197   [(set_attr "type" "icmp")
6198    (set_attr "mode" "<MODE>")])
6199
6200 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6201   [(set (reg:CCC FLAGS_REG)
6202         (compare:CCC
6203             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6204                           (match_operand:SI 2 "general_operand" "g"))
6205             (match_dup 1)))
6206    (set (match_operand:DI 0 "register_operand" "=r")
6207         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6208   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6209   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6210   [(set_attr "type" "alu")
6211    (set_attr "mode" "SI")])
6212
6213 (define_insn "addqi3_carry"
6214   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6215           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6216                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
6217                    (match_operand:QI 2 "general_operand" "qn,qm")))
6218    (clobber (reg:CC FLAGS_REG))]
6219   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6220   "adc{b}\t{%2, %0|%0, %2}"
6221   [(set_attr "type" "alu")
6222    (set_attr "use_carry" "1")
6223    (set_attr "pent_pair" "pu")
6224    (set_attr "mode" "QI")])
6225
6226 (define_insn "addhi3_carry"
6227   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6228           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6229                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
6230                    (match_operand:HI 2 "general_operand" "rn,rm")))
6231    (clobber (reg:CC FLAGS_REG))]
6232   "ix86_binary_operator_ok (PLUS, HImode, operands)"
6233   "adc{w}\t{%2, %0|%0, %2}"
6234   [(set_attr "type" "alu")
6235    (set_attr "use_carry" "1")
6236    (set_attr "pent_pair" "pu")
6237    (set_attr "mode" "HI")])
6238
6239 (define_insn "addsi3_carry"
6240   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6241           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6242                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6243                    (match_operand:SI 2 "general_operand" "ri,rm")))
6244    (clobber (reg:CC FLAGS_REG))]
6245   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6246   "adc{l}\t{%2, %0|%0, %2}"
6247   [(set_attr "type" "alu")
6248    (set_attr "use_carry" "1")
6249    (set_attr "pent_pair" "pu")
6250    (set_attr "mode" "SI")])
6251
6252 (define_insn "*addsi3_carry_zext"
6253   [(set (match_operand:DI 0 "register_operand" "=r")
6254           (zero_extend:DI
6255             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6256                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
6257                      (match_operand:SI 2 "general_operand" "g"))))
6258    (clobber (reg:CC FLAGS_REG))]
6259   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6260   "adc{l}\t{%2, %k0|%k0, %2}"
6261   [(set_attr "type" "alu")
6262    (set_attr "use_carry" "1")
6263    (set_attr "pent_pair" "pu")
6264    (set_attr "mode" "SI")])
6265
6266 (define_insn "*addsi3_cc"
6267   [(set (reg:CC FLAGS_REG)
6268         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6269                     (match_operand:SI 2 "general_operand" "ri,rm")]
6270                    UNSPEC_ADD_CARRY))
6271    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6272         (plus:SI (match_dup 1) (match_dup 2)))]
6273   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6274   "add{l}\t{%2, %0|%0, %2}"
6275   [(set_attr "type" "alu")
6276    (set_attr "mode" "SI")])
6277
6278 (define_insn "addqi3_cc"
6279   [(set (reg:CC FLAGS_REG)
6280         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6281                     (match_operand:QI 2 "general_operand" "qn,qm")]
6282                    UNSPEC_ADD_CARRY))
6283    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6284         (plus:QI (match_dup 1) (match_dup 2)))]
6285   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6286   "add{b}\t{%2, %0|%0, %2}"
6287   [(set_attr "type" "alu")
6288    (set_attr "mode" "QI")])
6289
6290 (define_expand "addsi3"
6291   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6292         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6293                  (match_operand:SI 2 "general_operand" "")))]
6294   ""
6295   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6296
6297 (define_insn "*lea_1"
6298   [(set (match_operand:SI 0 "register_operand" "=r")
6299         (match_operand:SI 1 "no_seg_address_operand" "p"))]
6300   "!TARGET_64BIT"
6301   "lea{l}\t{%a1, %0|%0, %a1}"
6302   [(set_attr "type" "lea")
6303    (set_attr "mode" "SI")])
6304
6305 (define_insn "*lea_1_rex64"
6306   [(set (match_operand:SI 0 "register_operand" "=r")
6307         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6308   "TARGET_64BIT"
6309   "lea{l}\t{%a1, %0|%0, %a1}"
6310   [(set_attr "type" "lea")
6311    (set_attr "mode" "SI")])
6312
6313 (define_insn "*lea_1_zext"
6314   [(set (match_operand:DI 0 "register_operand" "=r")
6315         (zero_extend:DI
6316          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6317   "TARGET_64BIT"
6318   "lea{l}\t{%a1, %k0|%k0, %a1}"
6319   [(set_attr "type" "lea")
6320    (set_attr "mode" "SI")])
6321
6322 (define_insn "*lea_2_rex64"
6323   [(set (match_operand:DI 0 "register_operand" "=r")
6324         (match_operand:DI 1 "no_seg_address_operand" "p"))]
6325   "TARGET_64BIT"
6326   "lea{q}\t{%a1, %0|%0, %a1}"
6327   [(set_attr "type" "lea")
6328    (set_attr "mode" "DI")])
6329
6330 ;; The lea patterns for non-Pmodes needs to be matched by several
6331 ;; insns converted to real lea by splitters.
6332
6333 (define_insn_and_split "*lea_general_1"
6334   [(set (match_operand 0 "register_operand" "=r")
6335         (plus (plus (match_operand 1 "index_register_operand" "l")
6336                     (match_operand 2 "register_operand" "r"))
6337               (match_operand 3 "immediate_operand" "i")))]
6338   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6339     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6340    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6341    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6342    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6343    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6344        || GET_MODE (operands[3]) == VOIDmode)"
6345   "#"
6346   "&& reload_completed"
6347   [(const_int 0)]
6348 {
6349   rtx pat;
6350   operands[0] = gen_lowpart (SImode, operands[0]);
6351   operands[1] = gen_lowpart (Pmode, operands[1]);
6352   operands[2] = gen_lowpart (Pmode, operands[2]);
6353   operands[3] = gen_lowpart (Pmode, operands[3]);
6354   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6355                       operands[3]);
6356   if (Pmode != SImode)
6357     pat = gen_rtx_SUBREG (SImode, pat, 0);
6358   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6359   DONE;
6360 }
6361   [(set_attr "type" "lea")
6362    (set_attr "mode" "SI")])
6363
6364 (define_insn_and_split "*lea_general_1_zext"
6365   [(set (match_operand:DI 0 "register_operand" "=r")
6366         (zero_extend:DI
6367           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6368                             (match_operand:SI 2 "register_operand" "r"))
6369                    (match_operand:SI 3 "immediate_operand" "i"))))]
6370   "TARGET_64BIT"
6371   "#"
6372   "&& reload_completed"
6373   [(set (match_dup 0)
6374         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6375                                                      (match_dup 2))
6376                                             (match_dup 3)) 0)))]
6377 {
6378   operands[1] = gen_lowpart (Pmode, operands[1]);
6379   operands[2] = gen_lowpart (Pmode, operands[2]);
6380   operands[3] = gen_lowpart (Pmode, operands[3]);
6381 }
6382   [(set_attr "type" "lea")
6383    (set_attr "mode" "SI")])
6384
6385 (define_insn_and_split "*lea_general_2"
6386   [(set (match_operand 0 "register_operand" "=r")
6387         (plus (mult (match_operand 1 "index_register_operand" "l")
6388                     (match_operand 2 "const248_operand" "i"))
6389               (match_operand 3 "nonmemory_operand" "ri")))]
6390   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6391     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6392    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6393    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6394    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6395        || GET_MODE (operands[3]) == VOIDmode)"
6396   "#"
6397   "&& reload_completed"
6398   [(const_int 0)]
6399 {
6400   rtx pat;
6401   operands[0] = gen_lowpart (SImode, operands[0]);
6402   operands[1] = gen_lowpart (Pmode, operands[1]);
6403   operands[3] = gen_lowpart (Pmode, operands[3]);
6404   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6405                       operands[3]);
6406   if (Pmode != SImode)
6407     pat = gen_rtx_SUBREG (SImode, pat, 0);
6408   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6409   DONE;
6410 }
6411   [(set_attr "type" "lea")
6412    (set_attr "mode" "SI")])
6413
6414 (define_insn_and_split "*lea_general_2_zext"
6415   [(set (match_operand:DI 0 "register_operand" "=r")
6416         (zero_extend:DI
6417           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6418                             (match_operand:SI 2 "const248_operand" "n"))
6419                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6420   "TARGET_64BIT"
6421   "#"
6422   "&& reload_completed"
6423   [(set (match_dup 0)
6424         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6425                                                      (match_dup 2))
6426                                             (match_dup 3)) 0)))]
6427 {
6428   operands[1] = gen_lowpart (Pmode, operands[1]);
6429   operands[3] = gen_lowpart (Pmode, operands[3]);
6430 }
6431   [(set_attr "type" "lea")
6432    (set_attr "mode" "SI")])
6433
6434 (define_insn_and_split "*lea_general_3"
6435   [(set (match_operand 0 "register_operand" "=r")
6436         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6437                           (match_operand 2 "const248_operand" "i"))
6438                     (match_operand 3 "register_operand" "r"))
6439               (match_operand 4 "immediate_operand" "i")))]
6440   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6441     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6442    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6443    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6444    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6445   "#"
6446   "&& reload_completed"
6447   [(const_int 0)]
6448 {
6449   rtx pat;
6450   operands[0] = gen_lowpart (SImode, operands[0]);
6451   operands[1] = gen_lowpart (Pmode, operands[1]);
6452   operands[3] = gen_lowpart (Pmode, operands[3]);
6453   operands[4] = gen_lowpart (Pmode, operands[4]);
6454   pat = gen_rtx_PLUS (Pmode,
6455                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6456                                                          operands[2]),
6457                                     operands[3]),
6458                       operands[4]);
6459   if (Pmode != SImode)
6460     pat = gen_rtx_SUBREG (SImode, pat, 0);
6461   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6462   DONE;
6463 }
6464   [(set_attr "type" "lea")
6465    (set_attr "mode" "SI")])
6466
6467 (define_insn_and_split "*lea_general_3_zext"
6468   [(set (match_operand:DI 0 "register_operand" "=r")
6469         (zero_extend:DI
6470           (plus:SI (plus:SI (mult:SI
6471                               (match_operand:SI 1 "index_register_operand" "l")
6472                               (match_operand:SI 2 "const248_operand" "n"))
6473                             (match_operand:SI 3 "register_operand" "r"))
6474                    (match_operand:SI 4 "immediate_operand" "i"))))]
6475   "TARGET_64BIT"
6476   "#"
6477   "&& reload_completed"
6478   [(set (match_dup 0)
6479         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6480                                                               (match_dup 2))
6481                                                      (match_dup 3))
6482                                             (match_dup 4)) 0)))]
6483 {
6484   operands[1] = gen_lowpart (Pmode, operands[1]);
6485   operands[3] = gen_lowpart (Pmode, operands[3]);
6486   operands[4] = gen_lowpart (Pmode, operands[4]);
6487 }
6488   [(set_attr "type" "lea")
6489    (set_attr "mode" "SI")])
6490
6491 (define_insn "*adddi_1_rex64"
6492   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6493         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6494                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6497 {
6498   switch (get_attr_type (insn))
6499     {
6500     case TYPE_LEA:
6501       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6502       return "lea{q}\t{%a2, %0|%0, %a2}";
6503
6504     case TYPE_INCDEC:
6505       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6506       if (operands[2] == const1_rtx)
6507         return "inc{q}\t%0";
6508       else
6509         {
6510           gcc_assert (operands[2] == constm1_rtx);
6511           return "dec{q}\t%0";
6512         }
6513
6514     default:
6515       /* Use add as much as possible to replace lea for AGU optimization. */
6516       if (which_alternative == 2 && TARGET_OPT_AGU)
6517         return "add{q}\t{%1, %0|%0, %1}";
6518         
6519       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6520
6521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6523       if (CONST_INT_P (operands[2])
6524           /* Avoid overflows.  */
6525           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6526           && (INTVAL (operands[2]) == 128
6527               || (INTVAL (operands[2]) < 0
6528                   && INTVAL (operands[2]) != -128)))
6529         {
6530           operands[2] = GEN_INT (-INTVAL (operands[2]));
6531           return "sub{q}\t{%2, %0|%0, %2}";
6532         }
6533       return "add{q}\t{%2, %0|%0, %2}";
6534     }
6535 }
6536   [(set (attr "type")
6537      (cond [(and (eq_attr "alternative" "2") 
6538                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6539               (const_string "lea")
6540             (eq_attr "alternative" "3")
6541               (const_string "lea")
6542             ; Current assemblers are broken and do not allow @GOTOFF in
6543             ; ought but a memory context.
6544             (match_operand:DI 2 "pic_symbolic_operand" "")
6545               (const_string "lea")
6546             (match_operand:DI 2 "incdec_operand" "")
6547               (const_string "incdec")
6548            ]
6549            (const_string "alu")))
6550    (set (attr "length_immediate")
6551       (if_then_else
6552         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6553         (const_string "1")
6554         (const_string "*")))
6555    (set_attr "mode" "DI")])
6556
6557 ;; Convert lea to the lea pattern to avoid flags dependency.
6558 (define_split
6559   [(set (match_operand:DI 0 "register_operand" "")
6560         (plus:DI (match_operand:DI 1 "register_operand" "")
6561                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "TARGET_64BIT && reload_completed 
6564    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6565   [(set (match_dup 0)
6566         (plus:DI (match_dup 1)
6567                  (match_dup 2)))]
6568   "")
6569
6570 (define_insn "*adddi_2_rex64"
6571   [(set (reg FLAGS_REG)
6572         (compare
6573           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6574                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6575           (const_int 0)))
6576    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6577         (plus:DI (match_dup 1) (match_dup 2)))]
6578   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6579    && ix86_binary_operator_ok (PLUS, DImode, operands)
6580    /* Current assemblers are broken and do not allow @GOTOFF in
6581       ought but a memory context.  */
6582    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6583 {
6584   switch (get_attr_type (insn))
6585     {
6586     case TYPE_INCDEC:
6587       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6588       if (operands[2] == const1_rtx)
6589         return "inc{q}\t%0";
6590       else
6591         {
6592           gcc_assert (operands[2] == constm1_rtx);
6593           return "dec{q}\t%0";
6594         }
6595
6596     default:
6597       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6598       /* ???? We ought to handle there the 32bit case too
6599          - do we need new constraint?  */
6600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6602       if (CONST_INT_P (operands[2])
6603           /* Avoid overflows.  */
6604           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6605           && (INTVAL (operands[2]) == 128
6606               || (INTVAL (operands[2]) < 0
6607                   && INTVAL (operands[2]) != -128)))
6608         {
6609           operands[2] = GEN_INT (-INTVAL (operands[2]));
6610           return "sub{q}\t{%2, %0|%0, %2}";
6611         }
6612       return "add{q}\t{%2, %0|%0, %2}";
6613     }
6614 }
6615   [(set (attr "type")
6616      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6617         (const_string "incdec")
6618         (const_string "alu")))
6619    (set (attr "length_immediate")
6620       (if_then_else
6621         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6622         (const_string "1")
6623         (const_string "*")))
6624    (set_attr "mode" "DI")])
6625
6626 (define_insn "*adddi_3_rex64"
6627   [(set (reg FLAGS_REG)
6628         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6629                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6630    (clobber (match_scratch:DI 0 "=r"))]
6631   "TARGET_64BIT
6632    && ix86_match_ccmode (insn, CCZmode)
6633    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6634    /* Current assemblers are broken and do not allow @GOTOFF in
6635       ought but a memory context.  */
6636    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6637 {
6638   switch (get_attr_type (insn))
6639     {
6640     case TYPE_INCDEC:
6641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6642       if (operands[2] == const1_rtx)
6643         return "inc{q}\t%0";
6644       else
6645         {
6646           gcc_assert (operands[2] == constm1_rtx);
6647           return "dec{q}\t%0";
6648         }
6649
6650     default:
6651       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652       /* ???? We ought to handle there the 32bit case too
6653          - do we need new constraint?  */
6654       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6655          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6656       if (CONST_INT_P (operands[2])
6657           /* Avoid overflows.  */
6658           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6659           && (INTVAL (operands[2]) == 128
6660               || (INTVAL (operands[2]) < 0
6661                   && INTVAL (operands[2]) != -128)))
6662         {
6663           operands[2] = GEN_INT (-INTVAL (operands[2]));
6664           return "sub{q}\t{%2, %0|%0, %2}";
6665         }
6666       return "add{q}\t{%2, %0|%0, %2}";
6667     }
6668 }
6669   [(set (attr "type")
6670      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6671         (const_string "incdec")
6672         (const_string "alu")))
6673    (set (attr "length_immediate")
6674       (if_then_else
6675         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6676         (const_string "1")
6677         (const_string "*")))
6678    (set_attr "mode" "DI")])
6679
6680 ; For comparisons against 1, -1 and 128, we may generate better code
6681 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6682 ; is matched then.  We can't accept general immediate, because for
6683 ; case of overflows,  the result is messed up.
6684 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6685 ; when negated.
6686 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6687 ; only for comparisons not depending on it.
6688 (define_insn "*adddi_4_rex64"
6689   [(set (reg FLAGS_REG)
6690         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6691                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6692    (clobber (match_scratch:DI 0 "=rm"))]
6693   "TARGET_64BIT
6694    &&  ix86_match_ccmode (insn, CCGCmode)"
6695 {
6696   switch (get_attr_type (insn))
6697     {
6698     case TYPE_INCDEC:
6699       if (operands[2] == constm1_rtx)
6700         return "inc{q}\t%0";
6701       else
6702         {
6703           gcc_assert (operands[2] == const1_rtx);
6704           return "dec{q}\t%0";
6705         }
6706
6707     default:
6708       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6709       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6710          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6711       if ((INTVAL (operands[2]) == -128
6712            || (INTVAL (operands[2]) > 0
6713                && INTVAL (operands[2]) != 128))
6714           /* Avoid overflows.  */
6715           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6716         return "sub{q}\t{%2, %0|%0, %2}";
6717       operands[2] = GEN_INT (-INTVAL (operands[2]));
6718       return "add{q}\t{%2, %0|%0, %2}";
6719     }
6720 }
6721   [(set (attr "type")
6722      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6723         (const_string "incdec")
6724         (const_string "alu")))
6725    (set (attr "length_immediate")
6726       (if_then_else
6727         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6728         (const_string "1")
6729         (const_string "*")))
6730    (set_attr "mode" "DI")])
6731
6732 (define_insn "*adddi_5_rex64"
6733   [(set (reg FLAGS_REG)
6734         (compare
6735           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6736                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6737           (const_int 0)))
6738    (clobber (match_scratch:DI 0 "=r"))]
6739   "TARGET_64BIT
6740    && ix86_match_ccmode (insn, CCGOCmode)
6741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6742    /* Current assemblers are broken and do not allow @GOTOFF in
6743       ought but a memory context.  */
6744    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6745 {
6746   switch (get_attr_type (insn))
6747     {
6748     case TYPE_INCDEC:
6749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6750       if (operands[2] == const1_rtx)
6751         return "inc{q}\t%0";
6752       else
6753         {
6754           gcc_assert (operands[2] == constm1_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 (CONST_INT_P (operands[2])
6763           /* Avoid overflows.  */
6764           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6765           && (INTVAL (operands[2]) == 128
6766               || (INTVAL (operands[2]) < 0
6767                   && INTVAL (operands[2]) != -128)))
6768         {
6769           operands[2] = GEN_INT (-INTVAL (operands[2]));
6770           return "sub{q}\t{%2, %0|%0, %2}";
6771         }
6772       return "add{q}\t{%2, %0|%0, %2}";
6773     }
6774 }
6775   [(set (attr "type")
6776      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6777         (const_string "incdec")
6778         (const_string "alu")))
6779    (set (attr "length_immediate")
6780       (if_then_else
6781         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6782         (const_string "1")
6783         (const_string "*")))
6784    (set_attr "mode" "DI")])
6785
6786
6787 (define_insn "*addsi_1"
6788   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6789         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6790                  (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6791    (clobber (reg:CC FLAGS_REG))]
6792   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6793 {
6794   switch (get_attr_type (insn))
6795     {
6796     case TYPE_LEA:
6797       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6798       return "lea{l}\t{%a2, %0|%0, %a2}";
6799
6800     case TYPE_INCDEC:
6801       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802       if (operands[2] == const1_rtx)
6803         return "inc{l}\t%0";
6804       else
6805         {
6806           gcc_assert (operands[2] == constm1_rtx);
6807           return "dec{l}\t%0";
6808         }
6809
6810     default:
6811       /* Use add as much as possible to replace lea for AGU optimization. */
6812       if (which_alternative == 2 && TARGET_OPT_AGU)
6813         return "add{l}\t{%1, %0|%0, %1}";
6814
6815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6816
6817       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6818          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6819       if (CONST_INT_P (operands[2])
6820           && (INTVAL (operands[2]) == 128
6821               || (INTVAL (operands[2]) < 0
6822                   && INTVAL (operands[2]) != -128)))
6823         {
6824           operands[2] = GEN_INT (-INTVAL (operands[2]));
6825           return "sub{l}\t{%2, %0|%0, %2}";
6826         }
6827       return "add{l}\t{%2, %0|%0, %2}";
6828     }
6829 }
6830   [(set (attr "type")
6831      (cond [(and (eq_attr "alternative" "2") 
6832                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6833                (const_string "lea")
6834             (eq_attr "alternative" "3")
6835               (const_string "lea")
6836             ; Current assemblers are broken and do not allow @GOTOFF in
6837             ; ought but a memory context.
6838             (match_operand:SI 2 "pic_symbolic_operand" "")
6839               (const_string "lea")
6840             (match_operand:SI 2 "incdec_operand" "")
6841               (const_string "incdec")
6842            ]
6843            (const_string "alu")))
6844    (set (attr "length_immediate")
6845       (if_then_else
6846         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6847         (const_string "1")
6848         (const_string "*")))
6849    (set_attr "mode" "SI")])
6850
6851 ;; Convert lea to the lea pattern to avoid flags dependency.
6852 (define_split
6853   [(set (match_operand 0 "register_operand" "")
6854         (plus (match_operand 1 "register_operand" "")
6855               (match_operand 2 "nonmemory_operand" "")))
6856    (clobber (reg:CC FLAGS_REG))]
6857   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6858   [(const_int 0)]
6859 {
6860   rtx pat;
6861   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6862      may confuse gen_lowpart.  */
6863   if (GET_MODE (operands[0]) != Pmode)
6864     {
6865       operands[1] = gen_lowpart (Pmode, operands[1]);
6866       operands[2] = gen_lowpart (Pmode, operands[2]);
6867     }
6868   operands[0] = gen_lowpart (SImode, operands[0]);
6869   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6870   if (Pmode != SImode)
6871     pat = gen_rtx_SUBREG (SImode, pat, 0);
6872   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6873   DONE;
6874 })
6875
6876 ;; It may seem that nonimmediate operand is proper one for operand 1.
6877 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6878 ;; we take care in ix86_binary_operator_ok to not allow two memory
6879 ;; operands so proper swapping will be done in reload.  This allow
6880 ;; patterns constructed from addsi_1 to match.
6881 (define_insn "addsi_1_zext"
6882   [(set (match_operand:DI 0 "register_operand" "=r,r")
6883         (zero_extend:DI
6884           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6885                    (match_operand:SI 2 "general_operand" "g,li"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6888 {
6889   switch (get_attr_type (insn))
6890     {
6891     case TYPE_LEA:
6892       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6893       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6894
6895     case TYPE_INCDEC:
6896       if (operands[2] == const1_rtx)
6897         return "inc{l}\t%k0";
6898       else
6899         {
6900           gcc_assert (operands[2] == constm1_rtx);
6901           return "dec{l}\t%k0";
6902         }
6903
6904     default:
6905       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6906          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6907       if (CONST_INT_P (operands[2])
6908           && (INTVAL (operands[2]) == 128
6909               || (INTVAL (operands[2]) < 0
6910                   && INTVAL (operands[2]) != -128)))
6911         {
6912           operands[2] = GEN_INT (-INTVAL (operands[2]));
6913           return "sub{l}\t{%2, %k0|%k0, %2}";
6914         }
6915       return "add{l}\t{%2, %k0|%k0, %2}";
6916     }
6917 }
6918   [(set (attr "type")
6919      (cond [(eq_attr "alternative" "1")
6920               (const_string "lea")
6921             ; Current assemblers are broken and do not allow @GOTOFF in
6922             ; ought but a memory context.
6923             (match_operand:SI 2 "pic_symbolic_operand" "")
6924               (const_string "lea")
6925             (match_operand:SI 2 "incdec_operand" "")
6926               (const_string "incdec")
6927            ]
6928            (const_string "alu")))
6929    (set (attr "length_immediate")
6930       (if_then_else
6931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6932         (const_string "1")
6933         (const_string "*")))
6934    (set_attr "mode" "SI")])
6935
6936 ;; Convert lea to the lea pattern to avoid flags dependency.
6937 (define_split
6938   [(set (match_operand:DI 0 "register_operand" "")
6939         (zero_extend:DI
6940           (plus:SI (match_operand:SI 1 "register_operand" "")
6941                    (match_operand:SI 2 "nonmemory_operand" ""))))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "TARGET_64BIT && reload_completed
6944    && true_regnum (operands[0]) != true_regnum (operands[1])"
6945   [(set (match_dup 0)
6946         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6947 {
6948   operands[1] = gen_lowpart (Pmode, operands[1]);
6949   operands[2] = gen_lowpart (Pmode, operands[2]);
6950 })
6951
6952 (define_insn "*addsi_2"
6953   [(set (reg FLAGS_REG)
6954         (compare
6955           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6956                    (match_operand:SI 2 "general_operand" "g,ri"))
6957           (const_int 0)))
6958    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6959         (plus:SI (match_dup 1) (match_dup 2)))]
6960   "ix86_match_ccmode (insn, CCGOCmode)
6961    && ix86_binary_operator_ok (PLUS, SImode, operands)
6962    /* Current assemblers are broken and do not allow @GOTOFF in
6963       ought but a memory context.  */
6964    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6965 {
6966   switch (get_attr_type (insn))
6967     {
6968     case TYPE_INCDEC:
6969       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6970       if (operands[2] == const1_rtx)
6971         return "inc{l}\t%0";
6972       else
6973         {
6974           gcc_assert (operands[2] == constm1_rtx);
6975           return "dec{l}\t%0";
6976         }
6977
6978     default:
6979       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6980       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6981          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6982       if (CONST_INT_P (operands[2])
6983           && (INTVAL (operands[2]) == 128
6984               || (INTVAL (operands[2]) < 0
6985                   && INTVAL (operands[2]) != -128)))
6986         {
6987           operands[2] = GEN_INT (-INTVAL (operands[2]));
6988           return "sub{l}\t{%2, %0|%0, %2}";
6989         }
6990       return "add{l}\t{%2, %0|%0, %2}";
6991     }
6992 }
6993   [(set (attr "type")
6994      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6995         (const_string "incdec")
6996         (const_string "alu")))
6997    (set (attr "length_immediate")
6998       (if_then_else
6999         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7000         (const_string "1")
7001         (const_string "*")))
7002    (set_attr "mode" "SI")])
7003
7004 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7005 (define_insn "*addsi_2_zext"
7006   [(set (reg FLAGS_REG)
7007         (compare
7008           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7009                    (match_operand:SI 2 "general_operand" "g"))
7010           (const_int 0)))
7011    (set (match_operand:DI 0 "register_operand" "=r")
7012         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7013   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7014    && ix86_binary_operator_ok (PLUS, SImode, operands)
7015    /* Current assemblers are broken and do not allow @GOTOFF in
7016       ought but a memory context.  */
7017    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7018 {
7019   switch (get_attr_type (insn))
7020     {
7021     case TYPE_INCDEC:
7022       if (operands[2] == const1_rtx)
7023         return "inc{l}\t%k0";
7024       else
7025         {
7026           gcc_assert (operands[2] == constm1_rtx);
7027           return "dec{l}\t%k0";
7028         }
7029
7030     default:
7031       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7032          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7033       if (CONST_INT_P (operands[2])
7034           && (INTVAL (operands[2]) == 128
7035               || (INTVAL (operands[2]) < 0
7036                   && INTVAL (operands[2]) != -128)))
7037         {
7038           operands[2] = GEN_INT (-INTVAL (operands[2]));
7039           return "sub{l}\t{%2, %k0|%k0, %2}";
7040         }
7041       return "add{l}\t{%2, %k0|%k0, %2}";
7042     }
7043 }
7044   [(set (attr "type")
7045      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7046         (const_string "incdec")
7047         (const_string "alu")))
7048    (set (attr "length_immediate")
7049       (if_then_else
7050         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7051         (const_string "1")
7052         (const_string "*")))
7053    (set_attr "mode" "SI")])
7054
7055 (define_insn "*addsi_3"
7056   [(set (reg FLAGS_REG)
7057         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7058                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
7059    (clobber (match_scratch:SI 0 "=r"))]
7060   "ix86_match_ccmode (insn, CCZmode)
7061    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7062    /* Current assemblers are broken and do not allow @GOTOFF in
7063       ought but a memory context.  */
7064    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7065 {
7066   switch (get_attr_type (insn))
7067     {
7068     case TYPE_INCDEC:
7069       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7070       if (operands[2] == const1_rtx)
7071         return "inc{l}\t%0";
7072       else
7073         {
7074           gcc_assert (operands[2] == constm1_rtx);
7075           return "dec{l}\t%0";
7076         }
7077
7078     default:
7079       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7080       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7081          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7082       if (CONST_INT_P (operands[2])
7083           && (INTVAL (operands[2]) == 128
7084               || (INTVAL (operands[2]) < 0
7085                   && INTVAL (operands[2]) != -128)))
7086         {
7087           operands[2] = GEN_INT (-INTVAL (operands[2]));
7088           return "sub{l}\t{%2, %0|%0, %2}";
7089         }
7090       return "add{l}\t{%2, %0|%0, %2}";
7091     }
7092 }
7093   [(set (attr "type")
7094      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7095         (const_string "incdec")
7096         (const_string "alu")))
7097    (set (attr "length_immediate")
7098       (if_then_else
7099         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7100         (const_string "1")
7101         (const_string "*")))
7102    (set_attr "mode" "SI")])
7103
7104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7105 (define_insn "*addsi_3_zext"
7106   [(set (reg FLAGS_REG)
7107         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7108                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
7109    (set (match_operand:DI 0 "register_operand" "=r")
7110         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7111   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7112    && ix86_binary_operator_ok (PLUS, SImode, operands)
7113    /* Current assemblers are broken and do not allow @GOTOFF in
7114       ought but a memory context.  */
7115    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7116 {
7117   switch (get_attr_type (insn))
7118     {
7119     case TYPE_INCDEC:
7120       if (operands[2] == const1_rtx)
7121         return "inc{l}\t%k0";
7122       else
7123         {
7124           gcc_assert (operands[2] == constm1_rtx);
7125           return "dec{l}\t%k0";
7126         }
7127
7128     default:
7129       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7130          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7131       if (CONST_INT_P (operands[2])
7132           && (INTVAL (operands[2]) == 128
7133               || (INTVAL (operands[2]) < 0
7134                   && INTVAL (operands[2]) != -128)))
7135         {
7136           operands[2] = GEN_INT (-INTVAL (operands[2]));
7137           return "sub{l}\t{%2, %k0|%k0, %2}";
7138         }
7139       return "add{l}\t{%2, %k0|%k0, %2}";
7140     }
7141 }
7142   [(set (attr "type")
7143      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7144         (const_string "incdec")
7145         (const_string "alu")))
7146    (set (attr "length_immediate")
7147       (if_then_else
7148         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7149         (const_string "1")
7150         (const_string "*")))
7151    (set_attr "mode" "SI")])
7152
7153 ; For comparisons against 1, -1 and 128, we may generate better code
7154 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7155 ; is matched then.  We can't accept general immediate, because for
7156 ; case of overflows,  the result is messed up.
7157 ; This pattern also don't hold of 0x80000000, since the value overflows
7158 ; when negated.
7159 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7160 ; only for comparisons not depending on it.
7161 (define_insn "*addsi_4"
7162   [(set (reg FLAGS_REG)
7163         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7164                  (match_operand:SI 2 "const_int_operand" "n")))
7165    (clobber (match_scratch:SI 0 "=rm"))]
7166   "ix86_match_ccmode (insn, CCGCmode)
7167    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7168 {
7169   switch (get_attr_type (insn))
7170     {
7171     case TYPE_INCDEC:
7172       if (operands[2] == constm1_rtx)
7173         return "inc{l}\t%0";
7174       else
7175         {
7176           gcc_assert (operands[2] == const1_rtx);
7177           return "dec{l}\t%0";
7178         }
7179
7180     default:
7181       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7182       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7183          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7184       if ((INTVAL (operands[2]) == -128
7185            || (INTVAL (operands[2]) > 0
7186                && INTVAL (operands[2]) != 128)))
7187         return "sub{l}\t{%2, %0|%0, %2}";
7188       operands[2] = GEN_INT (-INTVAL (operands[2]));
7189       return "add{l}\t{%2, %0|%0, %2}";
7190     }
7191 }
7192   [(set (attr "type")
7193      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7194         (const_string "incdec")
7195         (const_string "alu")))
7196    (set (attr "length_immediate")
7197       (if_then_else
7198         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7199         (const_string "1")
7200         (const_string "*")))
7201    (set_attr "mode" "SI")])
7202
7203 (define_insn "*addsi_5"
7204   [(set (reg FLAGS_REG)
7205         (compare
7206           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7207                    (match_operand:SI 2 "general_operand" "g"))
7208           (const_int 0)))
7209    (clobber (match_scratch:SI 0 "=r"))]
7210   "ix86_match_ccmode (insn, CCGOCmode)
7211    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7212    /* Current assemblers are broken and do not allow @GOTOFF in
7213       ought but a memory context.  */
7214    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7215 {
7216   switch (get_attr_type (insn))
7217     {
7218     case TYPE_INCDEC:
7219       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7220       if (operands[2] == const1_rtx)
7221         return "inc{l}\t%0";
7222       else
7223         {
7224           gcc_assert (operands[2] == constm1_rtx);
7225           return "dec{l}\t%0";
7226         }
7227
7228     default:
7229       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7230       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7232       if (CONST_INT_P (operands[2])
7233           && (INTVAL (operands[2]) == 128
7234               || (INTVAL (operands[2]) < 0
7235                   && INTVAL (operands[2]) != -128)))
7236         {
7237           operands[2] = GEN_INT (-INTVAL (operands[2]));
7238           return "sub{l}\t{%2, %0|%0, %2}";
7239         }
7240       return "add{l}\t{%2, %0|%0, %2}";
7241     }
7242 }
7243   [(set (attr "type")
7244      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7245         (const_string "incdec")
7246         (const_string "alu")))
7247    (set (attr "length_immediate")
7248       (if_then_else
7249         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7250         (const_string "1")
7251         (const_string "*")))
7252    (set_attr "mode" "SI")])
7253
7254 (define_expand "addhi3"
7255   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7256         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7257                  (match_operand:HI 2 "general_operand" "")))]
7258   "TARGET_HIMODE_MATH"
7259   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7260
7261 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7262 ;; type optimizations enabled by define-splits.  This is not important
7263 ;; for PII, and in fact harmful because of partial register stalls.
7264
7265 (define_insn "*addhi_1_lea"
7266   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7267         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
7268                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
7269    (clobber (reg:CC FLAGS_REG))]
7270   "!TARGET_PARTIAL_REG_STALL
7271    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7272 {
7273   switch (get_attr_type (insn))
7274     {
7275     case TYPE_LEA:
7276       return "#";
7277     case TYPE_INCDEC:
7278       if (operands[2] == const1_rtx)
7279         return "inc{w}\t%0";
7280       else
7281         {
7282           gcc_assert (operands[2] == constm1_rtx);
7283           return "dec{w}\t%0";
7284         }
7285
7286     default:
7287       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7288          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7289       if (CONST_INT_P (operands[2])
7290           && (INTVAL (operands[2]) == 128
7291               || (INTVAL (operands[2]) < 0
7292                   && INTVAL (operands[2]) != -128)))
7293         {
7294           operands[2] = GEN_INT (-INTVAL (operands[2]));
7295           return "sub{w}\t{%2, %0|%0, %2}";
7296         }
7297       return "add{w}\t{%2, %0|%0, %2}";
7298     }
7299 }
7300   [(set (attr "type")
7301      (if_then_else (eq_attr "alternative" "2")
7302         (const_string "lea")
7303         (if_then_else (match_operand:HI 2 "incdec_operand" "")
7304            (const_string "incdec")
7305            (const_string "alu"))))
7306    (set (attr "length_immediate")
7307       (if_then_else
7308         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7309         (const_string "1")
7310         (const_string "*")))
7311    (set_attr "mode" "HI,HI,SI")])
7312
7313 (define_insn "*addhi_1"
7314   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7315         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7316                  (match_operand:HI 2 "general_operand" "rn,rm")))
7317    (clobber (reg:CC FLAGS_REG))]
7318   "TARGET_PARTIAL_REG_STALL
7319    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7320 {
7321   switch (get_attr_type (insn))
7322     {
7323     case TYPE_INCDEC:
7324       if (operands[2] == const1_rtx)
7325         return "inc{w}\t%0";
7326       else
7327         {
7328           gcc_assert (operands[2] == constm1_rtx);
7329           return "dec{w}\t%0";
7330         }
7331
7332     default:
7333       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7334          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7335       if (CONST_INT_P (operands[2])
7336           && (INTVAL (operands[2]) == 128
7337               || (INTVAL (operands[2]) < 0
7338                   && INTVAL (operands[2]) != -128)))
7339         {
7340           operands[2] = GEN_INT (-INTVAL (operands[2]));
7341           return "sub{w}\t{%2, %0|%0, %2}";
7342         }
7343       return "add{w}\t{%2, %0|%0, %2}";
7344     }
7345 }
7346   [(set (attr "type")
7347      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7348         (const_string "incdec")
7349         (const_string "alu")))
7350    (set (attr "length_immediate")
7351       (if_then_else
7352         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7353         (const_string "1")
7354         (const_string "*")))
7355    (set_attr "mode" "HI")])
7356
7357 (define_insn "*addhi_2"
7358   [(set (reg FLAGS_REG)
7359         (compare
7360           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7361                    (match_operand:HI 2 "general_operand" "rmn,rn"))
7362           (const_int 0)))
7363    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7364         (plus:HI (match_dup 1) (match_dup 2)))]
7365   "ix86_match_ccmode (insn, CCGOCmode)
7366    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7367 {
7368   switch (get_attr_type (insn))
7369     {
7370     case TYPE_INCDEC:
7371       if (operands[2] == const1_rtx)
7372         return "inc{w}\t%0";
7373       else
7374         {
7375           gcc_assert (operands[2] == constm1_rtx);
7376           return "dec{w}\t%0";
7377         }
7378
7379     default:
7380       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7381          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7382       if (CONST_INT_P (operands[2])
7383           && (INTVAL (operands[2]) == 128
7384               || (INTVAL (operands[2]) < 0
7385                   && INTVAL (operands[2]) != -128)))
7386         {
7387           operands[2] = GEN_INT (-INTVAL (operands[2]));
7388           return "sub{w}\t{%2, %0|%0, %2}";
7389         }
7390       return "add{w}\t{%2, %0|%0, %2}";
7391     }
7392 }
7393   [(set (attr "type")
7394      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7395         (const_string "incdec")
7396         (const_string "alu")))
7397    (set (attr "length_immediate")
7398       (if_then_else
7399         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7400         (const_string "1")
7401         (const_string "*")))
7402    (set_attr "mode" "HI")])
7403
7404 (define_insn "*addhi_3"
7405   [(set (reg FLAGS_REG)
7406         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7407                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
7408    (clobber (match_scratch:HI 0 "=r"))]
7409   "ix86_match_ccmode (insn, CCZmode)
7410    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7411 {
7412   switch (get_attr_type (insn))
7413     {
7414     case TYPE_INCDEC:
7415       if (operands[2] == const1_rtx)
7416         return "inc{w}\t%0";
7417       else
7418         {
7419           gcc_assert (operands[2] == constm1_rtx);
7420           return "dec{w}\t%0";
7421         }
7422
7423     default:
7424       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7425          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7426       if (CONST_INT_P (operands[2])
7427           && (INTVAL (operands[2]) == 128
7428               || (INTVAL (operands[2]) < 0
7429                   && INTVAL (operands[2]) != -128)))
7430         {
7431           operands[2] = GEN_INT (-INTVAL (operands[2]));
7432           return "sub{w}\t{%2, %0|%0, %2}";
7433         }
7434       return "add{w}\t{%2, %0|%0, %2}";
7435     }
7436 }
7437   [(set (attr "type")
7438      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7439         (const_string "incdec")
7440         (const_string "alu")))
7441    (set (attr "length_immediate")
7442       (if_then_else
7443         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7444         (const_string "1")
7445         (const_string "*")))
7446    (set_attr "mode" "HI")])
7447
7448 ; See comments above addsi_4 for details.
7449 (define_insn "*addhi_4"
7450   [(set (reg FLAGS_REG)
7451         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7452                  (match_operand:HI 2 "const_int_operand" "n")))
7453    (clobber (match_scratch:HI 0 "=rm"))]
7454   "ix86_match_ccmode (insn, CCGCmode)
7455    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7456 {
7457   switch (get_attr_type (insn))
7458     {
7459     case TYPE_INCDEC:
7460       if (operands[2] == constm1_rtx)
7461         return "inc{w}\t%0";
7462       else
7463         {
7464           gcc_assert (operands[2] == const1_rtx);
7465           return "dec{w}\t%0";
7466         }
7467
7468     default:
7469       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7472       if ((INTVAL (operands[2]) == -128
7473            || (INTVAL (operands[2]) > 0
7474                && INTVAL (operands[2]) != 128)))
7475         return "sub{w}\t{%2, %0|%0, %2}";
7476       operands[2] = GEN_INT (-INTVAL (operands[2]));
7477       return "add{w}\t{%2, %0|%0, %2}";
7478     }
7479 }
7480   [(set (attr "type")
7481      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7482         (const_string "incdec")
7483         (const_string "alu")))
7484    (set (attr "length_immediate")
7485       (if_then_else
7486         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7487         (const_string "1")
7488         (const_string "*")))
7489    (set_attr "mode" "HI")])
7490
7491
7492 (define_insn "*addhi_5"
7493   [(set (reg FLAGS_REG)
7494         (compare
7495           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7496                    (match_operand:HI 2 "general_operand" "rmn"))
7497           (const_int 0)))
7498    (clobber (match_scratch:HI 0 "=r"))]
7499   "ix86_match_ccmode (insn, CCGOCmode)
7500    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7501 {
7502   switch (get_attr_type (insn))
7503     {
7504     case TYPE_INCDEC:
7505       if (operands[2] == const1_rtx)
7506         return "inc{w}\t%0";
7507       else
7508         {
7509           gcc_assert (operands[2] == constm1_rtx);
7510           return "dec{w}\t%0";
7511         }
7512
7513     default:
7514       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7515          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7516       if (CONST_INT_P (operands[2])
7517           && (INTVAL (operands[2]) == 128
7518               || (INTVAL (operands[2]) < 0
7519                   && INTVAL (operands[2]) != -128)))
7520         {
7521           operands[2] = GEN_INT (-INTVAL (operands[2]));
7522           return "sub{w}\t{%2, %0|%0, %2}";
7523         }
7524       return "add{w}\t{%2, %0|%0, %2}";
7525     }
7526 }
7527   [(set (attr "type")
7528      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7529         (const_string "incdec")
7530         (const_string "alu")))
7531    (set (attr "length_immediate")
7532       (if_then_else
7533         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7534         (const_string "1")
7535         (const_string "*")))
7536    (set_attr "mode" "HI")])
7537
7538 (define_expand "addqi3"
7539   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7540         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7541                  (match_operand:QI 2 "general_operand" "")))]
7542   "TARGET_QIMODE_MATH"
7543   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7544
7545 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7546 (define_insn "*addqi_1_lea"
7547   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7548         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7549                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "!TARGET_PARTIAL_REG_STALL
7552    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7553 {
7554   int widen = (which_alternative == 2);
7555   switch (get_attr_type (insn))
7556     {
7557     case TYPE_LEA:
7558       return "#";
7559     case TYPE_INCDEC:
7560       if (operands[2] == const1_rtx)
7561         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7562       else
7563         {
7564           gcc_assert (operands[2] == constm1_rtx);
7565           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7566         }
7567
7568     default:
7569       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7570          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7571       if (CONST_INT_P (operands[2])
7572           && (INTVAL (operands[2]) == 128
7573               || (INTVAL (operands[2]) < 0
7574                   && INTVAL (operands[2]) != -128)))
7575         {
7576           operands[2] = GEN_INT (-INTVAL (operands[2]));
7577           if (widen)
7578             return "sub{l}\t{%2, %k0|%k0, %2}";
7579           else
7580             return "sub{b}\t{%2, %0|%0, %2}";
7581         }
7582       if (widen)
7583         return "add{l}\t{%k2, %k0|%k0, %k2}";
7584       else
7585         return "add{b}\t{%2, %0|%0, %2}";
7586     }
7587 }
7588   [(set (attr "type")
7589      (if_then_else (eq_attr "alternative" "3")
7590         (const_string "lea")
7591         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7592            (const_string "incdec")
7593            (const_string "alu"))))
7594    (set (attr "length_immediate")
7595       (if_then_else
7596         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7597         (const_string "1")
7598         (const_string "*")))
7599    (set_attr "mode" "QI,QI,SI,SI")])
7600
7601 (define_insn "*addqi_1"
7602   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7603         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7604                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7605    (clobber (reg:CC FLAGS_REG))]
7606   "TARGET_PARTIAL_REG_STALL
7607    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7608 {
7609   int widen = (which_alternative == 2);
7610   switch (get_attr_type (insn))
7611     {
7612     case TYPE_INCDEC:
7613       if (operands[2] == const1_rtx)
7614         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7615       else
7616         {
7617           gcc_assert (operands[2] == constm1_rtx);
7618           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7619         }
7620
7621     default:
7622       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7623          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7624       if (CONST_INT_P (operands[2])
7625           && (INTVAL (operands[2]) == 128
7626               || (INTVAL (operands[2]) < 0
7627                   && INTVAL (operands[2]) != -128)))
7628         {
7629           operands[2] = GEN_INT (-INTVAL (operands[2]));
7630           if (widen)
7631             return "sub{l}\t{%2, %k0|%k0, %2}";
7632           else
7633             return "sub{b}\t{%2, %0|%0, %2}";
7634         }
7635       if (widen)
7636         return "add{l}\t{%k2, %k0|%k0, %k2}";
7637       else
7638         return "add{b}\t{%2, %0|%0, %2}";
7639     }
7640 }
7641   [(set (attr "type")
7642      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7643         (const_string "incdec")
7644         (const_string "alu")))
7645    (set (attr "length_immediate")
7646       (if_then_else
7647         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7648         (const_string "1")
7649         (const_string "*")))
7650    (set_attr "mode" "QI,QI,SI")])
7651
7652 (define_insn "*addqi_1_slp"
7653   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7654         (plus:QI (match_dup 0)
7655                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7656    (clobber (reg:CC FLAGS_REG))]
7657   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7658    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7659 {
7660   switch (get_attr_type (insn))
7661     {
7662     case TYPE_INCDEC:
7663       if (operands[1] == const1_rtx)
7664         return "inc{b}\t%0";
7665       else
7666         {
7667           gcc_assert (operands[1] == constm1_rtx);
7668           return "dec{b}\t%0";
7669         }
7670
7671     default:
7672       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7673       if (CONST_INT_P (operands[1])
7674           && INTVAL (operands[1]) < 0)
7675         {
7676           operands[1] = GEN_INT (-INTVAL (operands[1]));
7677           return "sub{b}\t{%1, %0|%0, %1}";
7678         }
7679       return "add{b}\t{%1, %0|%0, %1}";
7680     }
7681 }
7682   [(set (attr "type")
7683      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7684         (const_string "incdec")
7685         (const_string "alu1")))
7686    (set (attr "memory")
7687      (if_then_else (match_operand 1 "memory_operand" "")
7688         (const_string "load")
7689         (const_string "none")))
7690    (set_attr "mode" "QI")])
7691
7692 (define_insn "*addqi_2"
7693   [(set (reg FLAGS_REG)
7694         (compare
7695           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7696                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7697           (const_int 0)))
7698    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7699         (plus:QI (match_dup 1) (match_dup 2)))]
7700   "ix86_match_ccmode (insn, CCGOCmode)
7701    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7702 {
7703   switch (get_attr_type (insn))
7704     {
7705     case TYPE_INCDEC:
7706       if (operands[2] == const1_rtx)
7707         return "inc{b}\t%0";
7708       else
7709         {
7710           gcc_assert (operands[2] == constm1_rtx
7711                       || (CONST_INT_P (operands[2])
7712                           && INTVAL (operands[2]) == 255));
7713           return "dec{b}\t%0";
7714         }
7715
7716     default:
7717       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7718       if (CONST_INT_P (operands[2])
7719           && INTVAL (operands[2]) < 0)
7720         {
7721           operands[2] = GEN_INT (-INTVAL (operands[2]));
7722           return "sub{b}\t{%2, %0|%0, %2}";
7723         }
7724       return "add{b}\t{%2, %0|%0, %2}";
7725     }
7726 }
7727   [(set (attr "type")
7728      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7729         (const_string "incdec")
7730         (const_string "alu")))
7731    (set_attr "mode" "QI")])
7732
7733 (define_insn "*addqi_3"
7734   [(set (reg FLAGS_REG)
7735         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7736                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7737    (clobber (match_scratch:QI 0 "=q"))]
7738   "ix86_match_ccmode (insn, CCZmode)
7739    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7740 {
7741   switch (get_attr_type (insn))
7742     {
7743     case TYPE_INCDEC:
7744       if (operands[2] == const1_rtx)
7745         return "inc{b}\t%0";
7746       else
7747         {
7748           gcc_assert (operands[2] == constm1_rtx
7749                       || (CONST_INT_P (operands[2])
7750                           && INTVAL (operands[2]) == 255));
7751           return "dec{b}\t%0";
7752         }
7753
7754     default:
7755       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7756       if (CONST_INT_P (operands[2])
7757           && INTVAL (operands[2]) < 0)
7758         {
7759           operands[2] = GEN_INT (-INTVAL (operands[2]));
7760           return "sub{b}\t{%2, %0|%0, %2}";
7761         }
7762       return "add{b}\t{%2, %0|%0, %2}";
7763     }
7764 }
7765   [(set (attr "type")
7766      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7767         (const_string "incdec")
7768         (const_string "alu")))
7769    (set_attr "mode" "QI")])
7770
7771 ; See comments above addsi_4 for details.
7772 (define_insn "*addqi_4"
7773   [(set (reg FLAGS_REG)
7774         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7775                  (match_operand:QI 2 "const_int_operand" "n")))
7776    (clobber (match_scratch:QI 0 "=qm"))]
7777   "ix86_match_ccmode (insn, CCGCmode)
7778    && (INTVAL (operands[2]) & 0xff) != 0x80"
7779 {
7780   switch (get_attr_type (insn))
7781     {
7782     case TYPE_INCDEC:
7783       if (operands[2] == constm1_rtx
7784           || (CONST_INT_P (operands[2])
7785               && INTVAL (operands[2]) == 255))
7786         return "inc{b}\t%0";
7787       else
7788         {
7789           gcc_assert (operands[2] == const1_rtx);
7790           return "dec{b}\t%0";
7791         }
7792
7793     default:
7794       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7795       if (INTVAL (operands[2]) < 0)
7796         {
7797           operands[2] = GEN_INT (-INTVAL (operands[2]));
7798           return "add{b}\t{%2, %0|%0, %2}";
7799         }
7800       return "sub{b}\t{%2, %0|%0, %2}";
7801     }
7802 }
7803   [(set (attr "type")
7804      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7805         (const_string "incdec")
7806         (const_string "alu")))
7807    (set_attr "mode" "QI")])
7808
7809
7810 (define_insn "*addqi_5"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7814                    (match_operand:QI 2 "general_operand" "qmn"))
7815           (const_int 0)))
7816    (clobber (match_scratch:QI 0 "=q"))]
7817   "ix86_match_ccmode (insn, CCGOCmode)
7818    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7819 {
7820   switch (get_attr_type (insn))
7821     {
7822     case TYPE_INCDEC:
7823       if (operands[2] == const1_rtx)
7824         return "inc{b}\t%0";
7825       else
7826         {
7827           gcc_assert (operands[2] == constm1_rtx
7828                       || (CONST_INT_P (operands[2])
7829                           && INTVAL (operands[2]) == 255));
7830           return "dec{b}\t%0";
7831         }
7832
7833     default:
7834       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7835       if (CONST_INT_P (operands[2])
7836           && INTVAL (operands[2]) < 0)
7837         {
7838           operands[2] = GEN_INT (-INTVAL (operands[2]));
7839           return "sub{b}\t{%2, %0|%0, %2}";
7840         }
7841       return "add{b}\t{%2, %0|%0, %2}";
7842     }
7843 }
7844   [(set (attr "type")
7845      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7846         (const_string "incdec")
7847         (const_string "alu")))
7848    (set_attr "mode" "QI")])
7849
7850
7851 (define_insn "addqi_ext_1"
7852   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7853                          (const_int 8)
7854                          (const_int 8))
7855         (plus:SI
7856           (zero_extract:SI
7857             (match_operand 1 "ext_register_operand" "0")
7858             (const_int 8)
7859             (const_int 8))
7860           (match_operand:QI 2 "general_operand" "Qmn")))
7861    (clobber (reg:CC FLAGS_REG))]
7862   "!TARGET_64BIT"
7863 {
7864   switch (get_attr_type (insn))
7865     {
7866     case TYPE_INCDEC:
7867       if (operands[2] == const1_rtx)
7868         return "inc{b}\t%h0";
7869       else
7870         {
7871           gcc_assert (operands[2] == constm1_rtx
7872                       || (CONST_INT_P (operands[2])
7873                           && INTVAL (operands[2]) == 255));
7874           return "dec{b}\t%h0";
7875         }
7876
7877     default:
7878       return "add{b}\t{%2, %h0|%h0, %2}";
7879     }
7880 }
7881   [(set (attr "type")
7882      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7883         (const_string "incdec")
7884         (const_string "alu")))
7885    (set_attr "modrm" "1")
7886    (set_attr "mode" "QI")])
7887
7888 (define_insn "*addqi_ext_1_rex64"
7889   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7890                          (const_int 8)
7891                          (const_int 8))
7892         (plus:SI
7893           (zero_extract:SI
7894             (match_operand 1 "ext_register_operand" "0")
7895             (const_int 8)
7896             (const_int 8))
7897           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7898    (clobber (reg:CC FLAGS_REG))]
7899   "TARGET_64BIT"
7900 {
7901   switch (get_attr_type (insn))
7902     {
7903     case TYPE_INCDEC:
7904       if (operands[2] == const1_rtx)
7905         return "inc{b}\t%h0";
7906       else
7907         {
7908           gcc_assert (operands[2] == constm1_rtx
7909                       || (CONST_INT_P (operands[2])
7910                           && INTVAL (operands[2]) == 255));
7911           return "dec{b}\t%h0";
7912         }
7913
7914     default:
7915       return "add{b}\t{%2, %h0|%h0, %2}";
7916     }
7917 }
7918   [(set (attr "type")
7919      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7920         (const_string "incdec")
7921         (const_string "alu")))
7922    (set_attr "modrm" "1")
7923    (set_attr "mode" "QI")])
7924
7925 (define_insn "*addqi_ext_2"
7926   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7927                          (const_int 8)
7928                          (const_int 8))
7929         (plus:SI
7930           (zero_extract:SI
7931             (match_operand 1 "ext_register_operand" "%0")
7932             (const_int 8)
7933             (const_int 8))
7934           (zero_extract:SI
7935             (match_operand 2 "ext_register_operand" "Q")
7936             (const_int 8)
7937             (const_int 8))))
7938    (clobber (reg:CC FLAGS_REG))]
7939   ""
7940   "add{b}\t{%h2, %h0|%h0, %h2}"
7941   [(set_attr "type" "alu")
7942    (set_attr "mode" "QI")])
7943
7944 ;; The patterns that match these are at the end of this file.
7945
7946 (define_expand "addxf3"
7947   [(set (match_operand:XF 0 "register_operand" "")
7948         (plus:XF (match_operand:XF 1 "register_operand" "")
7949                  (match_operand:XF 2 "register_operand" "")))]
7950   "TARGET_80387"
7951   "")
7952
7953 (define_expand "add<mode>3"
7954   [(set (match_operand:MODEF 0 "register_operand" "")
7955         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7956                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7957   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7958     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7959   "")
7960 \f
7961 ;; Subtract instructions
7962
7963 ;; %%% splits for subditi3
7964
7965 (define_expand "subti3"
7966   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7967         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7968                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7969   "TARGET_64BIT"
7970   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7971
7972 (define_insn "*subti3_1"
7973   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7974         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7975                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7976    (clobber (reg:CC FLAGS_REG))]
7977   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7978   "#")
7979
7980 (define_split
7981   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7982         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7983                   (match_operand:TI 2 "x86_64_general_operand" "")))
7984    (clobber (reg:CC FLAGS_REG))]
7985   "TARGET_64BIT && reload_completed"
7986   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7987               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7988    (parallel [(set (match_dup 3)
7989                    (minus:DI (match_dup 4)
7990                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7991                                       (match_dup 5))))
7992               (clobber (reg:CC FLAGS_REG))])]
7993   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7994
7995 ;; %%% splits for subsidi3
7996
7997 (define_expand "subdi3"
7998   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7999         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8000                   (match_operand:DI 2 "x86_64_general_operand" "")))]
8001   ""
8002   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
8003
8004 (define_insn "*subdi3_1"
8005   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
8006         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8007                   (match_operand:DI 2 "general_operand" "roiF,riF")))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8010   "#")
8011
8012 (define_split
8013   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8014         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8015                   (match_operand:DI 2 "general_operand" "")))
8016    (clobber (reg:CC FLAGS_REG))]
8017   "!TARGET_64BIT && reload_completed"
8018   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
8019               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8020    (parallel [(set (match_dup 3)
8021                    (minus:SI (match_dup 4)
8022                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
8023                                       (match_dup 5))))
8024               (clobber (reg:CC FLAGS_REG))])]
8025   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
8026
8027 (define_insn "subdi3_carry_rex64"
8028   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8029           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8030             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
8031                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8034   "sbb{q}\t{%2, %0|%0, %2}"
8035   [(set_attr "type" "alu")
8036    (set_attr "use_carry" "1")
8037    (set_attr "pent_pair" "pu")
8038    (set_attr "mode" "DI")])
8039
8040 (define_insn "*subdi_1_rex64"
8041   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8042         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8043                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8044    (clobber (reg:CC FLAGS_REG))]
8045   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8046   "sub{q}\t{%2, %0|%0, %2}"
8047   [(set_attr "type" "alu")
8048    (set_attr "mode" "DI")])
8049
8050 (define_insn "*subdi_2_rex64"
8051   [(set (reg FLAGS_REG)
8052         (compare
8053           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8054                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
8055           (const_int 0)))
8056    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8057         (minus:DI (match_dup 1) (match_dup 2)))]
8058   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8059    && ix86_binary_operator_ok (MINUS, DImode, operands)"
8060   "sub{q}\t{%2, %0|%0, %2}"
8061   [(set_attr "type" "alu")
8062    (set_attr "mode" "DI")])
8063
8064 (define_insn "*subdi_3_rex63"
8065   [(set (reg FLAGS_REG)
8066         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
8067                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8068    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8069         (minus:DI (match_dup 1) (match_dup 2)))]
8070   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8071    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8072   "sub{q}\t{%2, %0|%0, %2}"
8073   [(set_attr "type" "alu")
8074    (set_attr "mode" "DI")])
8075
8076 (define_insn "subqi3_carry"
8077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8078           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8079             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
8080                (match_operand:QI 2 "general_operand" "qn,qm"))))
8081    (clobber (reg:CC FLAGS_REG))]
8082   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8083   "sbb{b}\t{%2, %0|%0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "use_carry" "1")
8086    (set_attr "pent_pair" "pu")
8087    (set_attr "mode" "QI")])
8088
8089 (define_insn "subhi3_carry"
8090   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8091           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8092             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
8093                (match_operand:HI 2 "general_operand" "rn,rm"))))
8094    (clobber (reg:CC FLAGS_REG))]
8095   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8096   "sbb{w}\t{%2, %0|%0, %2}"
8097   [(set_attr "type" "alu")
8098    (set_attr "use_carry" "1")
8099    (set_attr "pent_pair" "pu")
8100    (set_attr "mode" "HI")])
8101
8102 (define_insn "subsi3_carry"
8103   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8104           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8105             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8106                (match_operand:SI 2 "general_operand" "ri,rm"))))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "ix86_binary_operator_ok (MINUS, SImode, operands)"
8109   "sbb{l}\t{%2, %0|%0, %2}"
8110   [(set_attr "type" "alu")
8111    (set_attr "use_carry" "1")
8112    (set_attr "pent_pair" "pu")
8113    (set_attr "mode" "SI")])
8114
8115 (define_insn "subsi3_carry_zext"
8116   [(set (match_operand:DI 0 "register_operand" "=r")
8117           (zero_extend:DI
8118             (minus:SI (match_operand:SI 1 "register_operand" "0")
8119               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8120                  (match_operand:SI 2 "general_operand" "g")))))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8123   "sbb{l}\t{%2, %k0|%k0, %2}"
8124   [(set_attr "type" "alu")
8125    (set_attr "pent_pair" "pu")
8126    (set_attr "mode" "SI")])
8127
8128 (define_expand "subsi3"
8129   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8130         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
8131                   (match_operand:SI 2 "general_operand" "")))]
8132   ""
8133   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
8134
8135 (define_insn "*subsi_1"
8136   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8137         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8138                   (match_operand:SI 2 "general_operand" "ri,rm")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "ix86_binary_operator_ok (MINUS, SImode, operands)"
8141   "sub{l}\t{%2, %0|%0, %2}"
8142   [(set_attr "type" "alu")
8143    (set_attr "mode" "SI")])
8144
8145 (define_insn "*subsi_1_zext"
8146   [(set (match_operand:DI 0 "register_operand" "=r")
8147         (zero_extend:DI
8148           (minus:SI (match_operand:SI 1 "register_operand" "0")
8149                     (match_operand:SI 2 "general_operand" "g"))))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8152   "sub{l}\t{%2, %k0|%k0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "mode" "SI")])
8155
8156 (define_insn "*subsi_2"
8157   [(set (reg FLAGS_REG)
8158         (compare
8159           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8160                     (match_operand:SI 2 "general_operand" "ri,rm"))
8161           (const_int 0)))
8162    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8163         (minus:SI (match_dup 1) (match_dup 2)))]
8164   "ix86_match_ccmode (insn, CCGOCmode)
8165    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8166   "sub{l}\t{%2, %0|%0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8169
8170 (define_insn "*subsi_2_zext"
8171   [(set (reg FLAGS_REG)
8172         (compare
8173           (minus:SI (match_operand:SI 1 "register_operand" "0")
8174                     (match_operand:SI 2 "general_operand" "g"))
8175           (const_int 0)))
8176    (set (match_operand:DI 0 "register_operand" "=r")
8177         (zero_extend:DI
8178           (minus:SI (match_dup 1)
8179                     (match_dup 2))))]
8180   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8181    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8182   "sub{l}\t{%2, %k0|%k0, %2}"
8183   [(set_attr "type" "alu")
8184    (set_attr "mode" "SI")])
8185
8186 (define_insn "*subsi_3"
8187   [(set (reg FLAGS_REG)
8188         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
8189                  (match_operand:SI 2 "general_operand" "ri,rm")))
8190    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8191         (minus:SI (match_dup 1) (match_dup 2)))]
8192   "ix86_match_ccmode (insn, CCmode)
8193    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8194   "sub{l}\t{%2, %0|%0, %2}"
8195   [(set_attr "type" "alu")
8196    (set_attr "mode" "SI")])
8197
8198 (define_insn "*subsi_3_zext"
8199   [(set (reg FLAGS_REG)
8200         (compare (match_operand:SI 1 "register_operand" "0")
8201                  (match_operand:SI 2 "general_operand" "g")))
8202    (set (match_operand:DI 0 "register_operand" "=r")
8203         (zero_extend:DI
8204           (minus:SI (match_dup 1)
8205                     (match_dup 2))))]
8206   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8207    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8208   "sub{l}\t{%2, %1|%1, %2}"
8209   [(set_attr "type" "alu")
8210    (set_attr "mode" "DI")])
8211
8212 (define_expand "subhi3"
8213   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8214         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
8215                   (match_operand:HI 2 "general_operand" "")))]
8216   "TARGET_HIMODE_MATH"
8217   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
8218
8219 (define_insn "*subhi_1"
8220   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8221         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8222                   (match_operand:HI 2 "general_operand" "rn,rm")))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8225   "sub{w}\t{%2, %0|%0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "HI")])
8228
8229 (define_insn "*subhi_2"
8230   [(set (reg FLAGS_REG)
8231         (compare
8232           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8233                     (match_operand:HI 2 "general_operand" "rn,rm"))
8234           (const_int 0)))
8235    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8236         (minus:HI (match_dup 1) (match_dup 2)))]
8237   "ix86_match_ccmode (insn, CCGOCmode)
8238    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8239   "sub{w}\t{%2, %0|%0, %2}"
8240   [(set_attr "type" "alu")
8241    (set_attr "mode" "HI")])
8242
8243 (define_insn "*subhi_3"
8244   [(set (reg FLAGS_REG)
8245         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
8246                  (match_operand:HI 2 "general_operand" "rn,rm")))
8247    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8248         (minus:HI (match_dup 1) (match_dup 2)))]
8249   "ix86_match_ccmode (insn, CCmode)
8250    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8251   "sub{w}\t{%2, %0|%0, %2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "mode" "HI")])
8254
8255 (define_expand "subqi3"
8256   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8257         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8258                   (match_operand:QI 2 "general_operand" "")))]
8259   "TARGET_QIMODE_MATH"
8260   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
8261
8262 (define_insn "*subqi_1"
8263   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8264         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8265                   (match_operand:QI 2 "general_operand" "qn,qm")))
8266    (clobber (reg:CC FLAGS_REG))]
8267   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8268   "sub{b}\t{%2, %0|%0, %2}"
8269   [(set_attr "type" "alu")
8270    (set_attr "mode" "QI")])
8271
8272 (define_insn "*subqi_1_slp"
8273   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8274         (minus:QI (match_dup 0)
8275                   (match_operand:QI 1 "general_operand" "qn,qm")))
8276    (clobber (reg:CC FLAGS_REG))]
8277   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8278    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8279   "sub{b}\t{%1, %0|%0, %1}"
8280   [(set_attr "type" "alu1")
8281    (set_attr "mode" "QI")])
8282
8283 (define_insn "*subqi_2"
8284   [(set (reg FLAGS_REG)
8285         (compare
8286           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8287                     (match_operand:QI 2 "general_operand" "qn,qm"))
8288           (const_int 0)))
8289    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8290         (minus:QI (match_dup 1) (match_dup 2)))]
8291   "ix86_match_ccmode (insn, CCGOCmode)
8292    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8293   "sub{b}\t{%2, %0|%0, %2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "mode" "QI")])
8296
8297 (define_insn "*subqi_3"
8298   [(set (reg FLAGS_REG)
8299         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
8300                  (match_operand:QI 2 "general_operand" "qn,qm")))
8301    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8302         (minus:QI (match_dup 1) (match_dup 2)))]
8303   "ix86_match_ccmode (insn, CCmode)
8304    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8305   "sub{b}\t{%2, %0|%0, %2}"
8306   [(set_attr "type" "alu")
8307    (set_attr "mode" "QI")])
8308
8309 ;; The patterns that match these are at the end of this file.
8310
8311 (define_expand "subxf3"
8312   [(set (match_operand:XF 0 "register_operand" "")
8313         (minus:XF (match_operand:XF 1 "register_operand" "")
8314                   (match_operand:XF 2 "register_operand" "")))]
8315   "TARGET_80387"
8316   "")
8317
8318 (define_expand "sub<mode>3"
8319   [(set (match_operand:MODEF 0 "register_operand" "")
8320         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8321                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8322   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8323     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8324   "")
8325 \f
8326 ;; Multiply instructions
8327
8328 (define_expand "muldi3"
8329   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8330                    (mult:DI (match_operand:DI 1 "register_operand" "")
8331                             (match_operand:DI 2 "x86_64_general_operand" "")))
8332               (clobber (reg:CC FLAGS_REG))])]
8333   "TARGET_64BIT"
8334   "")
8335
8336 ;; On AMDFAM10
8337 ;; IMUL reg64, reg64, imm8      Direct
8338 ;; IMUL reg64, mem64, imm8      VectorPath
8339 ;; IMUL reg64, reg64, imm32     Direct
8340 ;; IMUL reg64, mem64, imm32     VectorPath
8341 ;; IMUL reg64, reg64            Direct
8342 ;; IMUL reg64, mem64            Direct
8343
8344 (define_insn "*muldi3_1_rex64"
8345   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8346         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
8347                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8348    (clobber (reg:CC FLAGS_REG))]
8349   "TARGET_64BIT
8350    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8351   "@
8352    imul{q}\t{%2, %1, %0|%0, %1, %2}
8353    imul{q}\t{%2, %1, %0|%0, %1, %2}
8354    imul{q}\t{%2, %0|%0, %2}"
8355   [(set_attr "type" "imul")
8356    (set_attr "prefix_0f" "0,0,1")
8357    (set (attr "athlon_decode")
8358         (cond [(eq_attr "cpu" "athlon")
8359                   (const_string "vector")
8360                (eq_attr "alternative" "1")
8361                   (const_string "vector")
8362                (and (eq_attr "alternative" "2")
8363                     (match_operand 1 "memory_operand" ""))
8364                   (const_string "vector")]
8365               (const_string "direct")))
8366    (set (attr "amdfam10_decode")
8367         (cond [(and (eq_attr "alternative" "0,1")
8368                     (match_operand 1 "memory_operand" ""))
8369                   (const_string "vector")]
8370               (const_string "direct")))
8371    (set_attr "mode" "DI")])
8372
8373 (define_expand "mulsi3"
8374   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8375                    (mult:SI (match_operand:SI 1 "register_operand" "")
8376                             (match_operand:SI 2 "general_operand" "")))
8377               (clobber (reg:CC FLAGS_REG))])]
8378   ""
8379   "")
8380
8381 ;; On AMDFAM10
8382 ;; IMUL reg32, reg32, imm8      Direct
8383 ;; IMUL reg32, mem32, imm8      VectorPath
8384 ;; IMUL reg32, reg32, imm32     Direct
8385 ;; IMUL reg32, mem32, imm32     VectorPath
8386 ;; IMUL reg32, reg32            Direct
8387 ;; IMUL reg32, mem32            Direct
8388
8389 (define_insn "*mulsi3_1"
8390   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
8391         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8392                  (match_operand:SI 2 "general_operand" "K,i,mr")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8395   "@
8396    imul{l}\t{%2, %1, %0|%0, %1, %2}
8397    imul{l}\t{%2, %1, %0|%0, %1, %2}
8398    imul{l}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "imul")
8400    (set_attr "prefix_0f" "0,0,1")
8401    (set (attr "athlon_decode")
8402         (cond [(eq_attr "cpu" "athlon")
8403                   (const_string "vector")
8404                (eq_attr "alternative" "1")
8405                   (const_string "vector")
8406                (and (eq_attr "alternative" "2")
8407                     (match_operand 1 "memory_operand" ""))
8408                   (const_string "vector")]
8409               (const_string "direct")))
8410    (set (attr "amdfam10_decode")
8411         (cond [(and (eq_attr "alternative" "0,1")
8412                     (match_operand 1 "memory_operand" ""))
8413                   (const_string "vector")]
8414               (const_string "direct")))
8415    (set_attr "mode" "SI")])
8416
8417 (define_insn "*mulsi3_1_zext"
8418   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8419         (zero_extend:DI
8420           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8421                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "TARGET_64BIT
8424    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8425   "@
8426    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8427    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8428    imul{l}\t{%2, %k0|%k0, %2}"
8429   [(set_attr "type" "imul")
8430    (set_attr "prefix_0f" "0,0,1")
8431    (set (attr "athlon_decode")
8432         (cond [(eq_attr "cpu" "athlon")
8433                   (const_string "vector")
8434                (eq_attr "alternative" "1")
8435                   (const_string "vector")
8436                (and (eq_attr "alternative" "2")
8437                     (match_operand 1 "memory_operand" ""))
8438                   (const_string "vector")]
8439               (const_string "direct")))
8440    (set (attr "amdfam10_decode")
8441         (cond [(and (eq_attr "alternative" "0,1")
8442                     (match_operand 1 "memory_operand" ""))
8443                   (const_string "vector")]
8444               (const_string "direct")))
8445    (set_attr "mode" "SI")])
8446
8447 (define_expand "mulhi3"
8448   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8449                    (mult:HI (match_operand:HI 1 "register_operand" "")
8450                             (match_operand:HI 2 "general_operand" "")))
8451               (clobber (reg:CC FLAGS_REG))])]
8452   "TARGET_HIMODE_MATH"
8453   "")
8454
8455 ;; On AMDFAM10
8456 ;; IMUL reg16, reg16, imm8      VectorPath
8457 ;; IMUL reg16, mem16, imm8      VectorPath
8458 ;; IMUL reg16, reg16, imm16     VectorPath
8459 ;; IMUL reg16, mem16, imm16     VectorPath
8460 ;; IMUL reg16, reg16            Direct
8461 ;; IMUL reg16, mem16            Direct
8462 (define_insn "*mulhi3_1"
8463   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8464         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8465                  (match_operand:HI 2 "general_operand" "K,n,mr")))
8466    (clobber (reg:CC FLAGS_REG))]
8467   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8468   "@
8469    imul{w}\t{%2, %1, %0|%0, %1, %2}
8470    imul{w}\t{%2, %1, %0|%0, %1, %2}
8471    imul{w}\t{%2, %0|%0, %2}"
8472   [(set_attr "type" "imul")
8473    (set_attr "prefix_0f" "0,0,1")
8474    (set (attr "athlon_decode")
8475         (cond [(eq_attr "cpu" "athlon")
8476                   (const_string "vector")
8477                (eq_attr "alternative" "1,2")
8478                   (const_string "vector")]
8479               (const_string "direct")))
8480    (set (attr "amdfam10_decode")
8481         (cond [(eq_attr "alternative" "0,1")
8482                   (const_string "vector")]
8483               (const_string "direct")))
8484    (set_attr "mode" "HI")])
8485
8486 (define_expand "mulqi3"
8487   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8488                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8489                             (match_operand:QI 2 "register_operand" "")))
8490               (clobber (reg:CC FLAGS_REG))])]
8491   "TARGET_QIMODE_MATH"
8492   "")
8493
8494 ;;On AMDFAM10
8495 ;; MUL reg8     Direct
8496 ;; MUL mem8     Direct
8497
8498 (define_insn "*mulqi3_1"
8499   [(set (match_operand:QI 0 "register_operand" "=a")
8500         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8501                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "TARGET_QIMODE_MATH
8504    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8505   "mul{b}\t%2"
8506   [(set_attr "type" "imul")
8507    (set_attr "length_immediate" "0")
8508    (set (attr "athlon_decode")
8509      (if_then_else (eq_attr "cpu" "athlon")
8510         (const_string "vector")
8511         (const_string "direct")))
8512    (set_attr "amdfam10_decode" "direct")
8513    (set_attr "mode" "QI")])
8514
8515 (define_expand "umulqihi3"
8516   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8517                    (mult:HI (zero_extend:HI
8518                               (match_operand:QI 1 "nonimmediate_operand" ""))
8519                             (zero_extend:HI
8520                               (match_operand:QI 2 "register_operand" ""))))
8521               (clobber (reg:CC FLAGS_REG))])]
8522   "TARGET_QIMODE_MATH"
8523   "")
8524
8525 (define_insn "*umulqihi3_1"
8526   [(set (match_operand:HI 0 "register_operand" "=a")
8527         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8528                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8529    (clobber (reg:CC FLAGS_REG))]
8530   "TARGET_QIMODE_MATH
8531    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8532   "mul{b}\t%2"
8533   [(set_attr "type" "imul")
8534    (set_attr "length_immediate" "0")
8535    (set (attr "athlon_decode")
8536      (if_then_else (eq_attr "cpu" "athlon")
8537         (const_string "vector")
8538         (const_string "direct")))
8539    (set_attr "amdfam10_decode" "direct")
8540    (set_attr "mode" "QI")])
8541
8542 (define_expand "mulqihi3"
8543   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8544                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8545                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8546               (clobber (reg:CC FLAGS_REG))])]
8547   "TARGET_QIMODE_MATH"
8548   "")
8549
8550 (define_insn "*mulqihi3_insn"
8551   [(set (match_operand:HI 0 "register_operand" "=a")
8552         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8553                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_QIMODE_MATH
8556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8557   "imul{b}\t%2"
8558   [(set_attr "type" "imul")
8559    (set_attr "length_immediate" "0")
8560    (set (attr "athlon_decode")
8561      (if_then_else (eq_attr "cpu" "athlon")
8562         (const_string "vector")
8563         (const_string "direct")))
8564    (set_attr "amdfam10_decode" "direct")
8565    (set_attr "mode" "QI")])
8566
8567 (define_expand "umulditi3"
8568   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8569                    (mult:TI (zero_extend:TI
8570                               (match_operand:DI 1 "nonimmediate_operand" ""))
8571                             (zero_extend:TI
8572                               (match_operand:DI 2 "register_operand" ""))))
8573               (clobber (reg:CC FLAGS_REG))])]
8574   "TARGET_64BIT"
8575   "")
8576
8577 (define_insn "*umulditi3_insn"
8578   [(set (match_operand:TI 0 "register_operand" "=A")
8579         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8580                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "TARGET_64BIT
8583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8584   "mul{q}\t%2"
8585   [(set_attr "type" "imul")
8586    (set_attr "length_immediate" "0")
8587    (set (attr "athlon_decode")
8588      (if_then_else (eq_attr "cpu" "athlon")
8589         (const_string "vector")
8590         (const_string "double")))
8591    (set_attr "amdfam10_decode" "double")
8592    (set_attr "mode" "DI")])
8593
8594 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8595 (define_expand "umulsidi3"
8596   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8597                    (mult:DI (zero_extend:DI
8598                               (match_operand:SI 1 "nonimmediate_operand" ""))
8599                             (zero_extend:DI
8600                               (match_operand:SI 2 "register_operand" ""))))
8601               (clobber (reg:CC FLAGS_REG))])]
8602   "!TARGET_64BIT"
8603   "")
8604
8605 (define_insn "*umulsidi3_insn"
8606   [(set (match_operand:DI 0 "register_operand" "=A")
8607         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8608                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8609    (clobber (reg:CC FLAGS_REG))]
8610   "!TARGET_64BIT
8611    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8612   "mul{l}\t%2"
8613   [(set_attr "type" "imul")
8614    (set_attr "length_immediate" "0")
8615    (set (attr "athlon_decode")
8616      (if_then_else (eq_attr "cpu" "athlon")
8617         (const_string "vector")
8618         (const_string "double")))
8619    (set_attr "amdfam10_decode" "double")
8620    (set_attr "mode" "SI")])
8621
8622 (define_expand "mulditi3"
8623   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8624                    (mult:TI (sign_extend:TI
8625                               (match_operand:DI 1 "nonimmediate_operand" ""))
8626                             (sign_extend:TI
8627                               (match_operand:DI 2 "register_operand" ""))))
8628               (clobber (reg:CC FLAGS_REG))])]
8629   "TARGET_64BIT"
8630   "")
8631
8632 (define_insn "*mulditi3_insn"
8633   [(set (match_operand:TI 0 "register_operand" "=A")
8634         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8635                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8636    (clobber (reg:CC FLAGS_REG))]
8637   "TARGET_64BIT
8638    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8639   "imul{q}\t%2"
8640   [(set_attr "type" "imul")
8641    (set_attr "length_immediate" "0")
8642    (set (attr "athlon_decode")
8643      (if_then_else (eq_attr "cpu" "athlon")
8644         (const_string "vector")
8645         (const_string "double")))
8646    (set_attr "amdfam10_decode" "double")
8647    (set_attr "mode" "DI")])
8648
8649 (define_expand "mulsidi3"
8650   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8651                    (mult:DI (sign_extend:DI
8652                               (match_operand:SI 1 "nonimmediate_operand" ""))
8653                             (sign_extend:DI
8654                               (match_operand:SI 2 "register_operand" ""))))
8655               (clobber (reg:CC FLAGS_REG))])]
8656   "!TARGET_64BIT"
8657   "")
8658
8659 (define_insn "*mulsidi3_insn"
8660   [(set (match_operand:DI 0 "register_operand" "=A")
8661         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8662                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "!TARGET_64BIT
8665    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8666   "imul{l}\t%2"
8667   [(set_attr "type" "imul")
8668    (set_attr "length_immediate" "0")
8669    (set (attr "athlon_decode")
8670      (if_then_else (eq_attr "cpu" "athlon")
8671         (const_string "vector")
8672         (const_string "double")))
8673    (set_attr "amdfam10_decode" "double")
8674    (set_attr "mode" "SI")])
8675
8676 (define_expand "umuldi3_highpart"
8677   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8678                    (truncate:DI
8679                      (lshiftrt:TI
8680                        (mult:TI (zero_extend:TI
8681                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8682                                 (zero_extend:TI
8683                                   (match_operand:DI 2 "register_operand" "")))
8684                        (const_int 64))))
8685               (clobber (match_scratch:DI 3 ""))
8686               (clobber (reg:CC FLAGS_REG))])]
8687   "TARGET_64BIT"
8688   "")
8689
8690 (define_insn "*umuldi3_highpart_rex64"
8691   [(set (match_operand:DI 0 "register_operand" "=d")
8692         (truncate:DI
8693           (lshiftrt:TI
8694             (mult:TI (zero_extend:TI
8695                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8696                      (zero_extend:TI
8697                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8698             (const_int 64))))
8699    (clobber (match_scratch:DI 3 "=1"))
8700    (clobber (reg:CC FLAGS_REG))]
8701   "TARGET_64BIT
8702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8703   "mul{q}\t%2"
8704   [(set_attr "type" "imul")
8705    (set_attr "length_immediate" "0")
8706    (set (attr "athlon_decode")
8707      (if_then_else (eq_attr "cpu" "athlon")
8708         (const_string "vector")
8709         (const_string "double")))
8710    (set_attr "amdfam10_decode" "double")
8711    (set_attr "mode" "DI")])
8712
8713 (define_expand "umulsi3_highpart"
8714   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8715                    (truncate:SI
8716                      (lshiftrt:DI
8717                        (mult:DI (zero_extend:DI
8718                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8719                                 (zero_extend:DI
8720                                   (match_operand:SI 2 "register_operand" "")))
8721                        (const_int 32))))
8722               (clobber (match_scratch:SI 3 ""))
8723               (clobber (reg:CC FLAGS_REG))])]
8724   ""
8725   "")
8726
8727 (define_insn "*umulsi3_highpart_insn"
8728   [(set (match_operand:SI 0 "register_operand" "=d")
8729         (truncate:SI
8730           (lshiftrt:DI
8731             (mult:DI (zero_extend:DI
8732                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8733                      (zero_extend:DI
8734                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8735             (const_int 32))))
8736    (clobber (match_scratch:SI 3 "=1"))
8737    (clobber (reg:CC FLAGS_REG))]
8738   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8739   "mul{l}\t%2"
8740   [(set_attr "type" "imul")
8741    (set_attr "length_immediate" "0")
8742    (set (attr "athlon_decode")
8743      (if_then_else (eq_attr "cpu" "athlon")
8744         (const_string "vector")
8745         (const_string "double")))
8746    (set_attr "amdfam10_decode" "double")
8747    (set_attr "mode" "SI")])
8748
8749 (define_insn "*umulsi3_highpart_zext"
8750   [(set (match_operand:DI 0 "register_operand" "=d")
8751         (zero_extend:DI (truncate:SI
8752           (lshiftrt:DI
8753             (mult:DI (zero_extend:DI
8754                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8755                      (zero_extend:DI
8756                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8757             (const_int 32)))))
8758    (clobber (match_scratch:SI 3 "=1"))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "TARGET_64BIT
8761    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8762   "mul{l}\t%2"
8763   [(set_attr "type" "imul")
8764    (set_attr "length_immediate" "0")
8765    (set (attr "athlon_decode")
8766      (if_then_else (eq_attr "cpu" "athlon")
8767         (const_string "vector")
8768         (const_string "double")))
8769    (set_attr "amdfam10_decode" "double")
8770    (set_attr "mode" "SI")])
8771
8772 (define_expand "smuldi3_highpart"
8773   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8774                    (truncate:DI
8775                      (lshiftrt:TI
8776                        (mult:TI (sign_extend:TI
8777                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8778                                 (sign_extend:TI
8779                                   (match_operand:DI 2 "register_operand" "")))
8780                        (const_int 64))))
8781               (clobber (match_scratch:DI 3 ""))
8782               (clobber (reg:CC FLAGS_REG))])]
8783   "TARGET_64BIT"
8784   "")
8785
8786 (define_insn "*smuldi3_highpart_rex64"
8787   [(set (match_operand:DI 0 "register_operand" "=d")
8788         (truncate:DI
8789           (lshiftrt:TI
8790             (mult:TI (sign_extend:TI
8791                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8792                      (sign_extend:TI
8793                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8794             (const_int 64))))
8795    (clobber (match_scratch:DI 3 "=1"))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "TARGET_64BIT
8798    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8799   "imul{q}\t%2"
8800   [(set_attr "type" "imul")
8801    (set (attr "athlon_decode")
8802      (if_then_else (eq_attr "cpu" "athlon")
8803         (const_string "vector")
8804         (const_string "double")))
8805    (set_attr "amdfam10_decode" "double")
8806    (set_attr "mode" "DI")])
8807
8808 (define_expand "smulsi3_highpart"
8809   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8810                    (truncate:SI
8811                      (lshiftrt:DI
8812                        (mult:DI (sign_extend:DI
8813                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8814                                 (sign_extend:DI
8815                                   (match_operand:SI 2 "register_operand" "")))
8816                        (const_int 32))))
8817               (clobber (match_scratch:SI 3 ""))
8818               (clobber (reg:CC FLAGS_REG))])]
8819   ""
8820   "")
8821
8822 (define_insn "*smulsi3_highpart_insn"
8823   [(set (match_operand:SI 0 "register_operand" "=d")
8824         (truncate:SI
8825           (lshiftrt:DI
8826             (mult:DI (sign_extend:DI
8827                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8828                      (sign_extend:DI
8829                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8830             (const_int 32))))
8831    (clobber (match_scratch:SI 3 "=1"))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8834   "imul{l}\t%2"
8835   [(set_attr "type" "imul")
8836    (set (attr "athlon_decode")
8837      (if_then_else (eq_attr "cpu" "athlon")
8838         (const_string "vector")
8839         (const_string "double")))
8840    (set_attr "amdfam10_decode" "double")
8841    (set_attr "mode" "SI")])
8842
8843 (define_insn "*smulsi3_highpart_zext"
8844   [(set (match_operand:DI 0 "register_operand" "=d")
8845         (zero_extend:DI (truncate:SI
8846           (lshiftrt:DI
8847             (mult:DI (sign_extend:DI
8848                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8849                      (sign_extend:DI
8850                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8851             (const_int 32)))))
8852    (clobber (match_scratch:SI 3 "=1"))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT
8855    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8856   "imul{l}\t%2"
8857   [(set_attr "type" "imul")
8858    (set (attr "athlon_decode")
8859      (if_then_else (eq_attr "cpu" "athlon")
8860         (const_string "vector")
8861         (const_string "double")))
8862    (set_attr "amdfam10_decode" "double")
8863    (set_attr "mode" "SI")])
8864
8865 ;; The patterns that match these are at the end of this file.
8866
8867 (define_expand "mulxf3"
8868   [(set (match_operand:XF 0 "register_operand" "")
8869         (mult:XF (match_operand:XF 1 "register_operand" "")
8870                  (match_operand:XF 2 "register_operand" "")))]
8871   "TARGET_80387"
8872   "")
8873
8874 (define_expand "mul<mode>3"
8875   [(set (match_operand:MODEF 0 "register_operand" "")
8876         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8877                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8878   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8879     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8880   "")
8881
8882 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8883
8884 \f
8885 ;; Divide instructions
8886
8887 (define_insn "divqi3"
8888   [(set (match_operand:QI 0 "register_operand" "=a")
8889         (div:QI (match_operand:HI 1 "register_operand" "0")
8890                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "TARGET_QIMODE_MATH"
8893   "idiv{b}\t%2"
8894   [(set_attr "type" "idiv")
8895    (set_attr "mode" "QI")])
8896
8897 (define_insn "udivqi3"
8898   [(set (match_operand:QI 0 "register_operand" "=a")
8899         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8900                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_QIMODE_MATH"
8903   "div{b}\t%2"
8904   [(set_attr "type" "idiv")
8905    (set_attr "mode" "QI")])
8906
8907 ;; The patterns that match these are at the end of this file.
8908
8909 (define_expand "divxf3"
8910   [(set (match_operand:XF 0 "register_operand" "")
8911         (div:XF (match_operand:XF 1 "register_operand" "")
8912                 (match_operand:XF 2 "register_operand" "")))]
8913   "TARGET_80387"
8914   "")
8915
8916 (define_expand "divdf3"
8917   [(set (match_operand:DF 0 "register_operand" "")
8918         (div:DF (match_operand:DF 1 "register_operand" "")
8919                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8920    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8921     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8922    "")
8923
8924 (define_expand "divsf3"
8925   [(set (match_operand:SF 0 "register_operand" "")
8926         (div:SF (match_operand:SF 1 "register_operand" "")
8927                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8928   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8929     || TARGET_SSE_MATH"
8930 {
8931   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8932       && flag_finite_math_only && !flag_trapping_math
8933       && flag_unsafe_math_optimizations)
8934     {
8935       ix86_emit_swdivsf (operands[0], operands[1],
8936                          operands[2], SFmode);
8937       DONE;
8938     }
8939 })
8940 \f
8941 ;; Remainder instructions.
8942
8943 (define_expand "divmoddi4"
8944   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8945                    (div:DI (match_operand:DI 1 "register_operand" "")
8946                            (match_operand:DI 2 "nonimmediate_operand" "")))
8947               (set (match_operand:DI 3 "register_operand" "")
8948                    (mod:DI (match_dup 1) (match_dup 2)))
8949               (clobber (reg:CC FLAGS_REG))])]
8950   "TARGET_64BIT"
8951   "")
8952
8953 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8954 ;; Penalize eax case slightly because it results in worse scheduling
8955 ;; of code.
8956 (define_insn "*divmoddi4_nocltd_rex64"
8957   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8958         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8959                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8960    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8961         (mod:DI (match_dup 2) (match_dup 3)))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8964   "#"
8965   [(set_attr "type" "multi")])
8966
8967 (define_insn "*divmoddi4_cltd_rex64"
8968   [(set (match_operand:DI 0 "register_operand" "=a")
8969         (div:DI (match_operand:DI 2 "register_operand" "a")
8970                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8971    (set (match_operand:DI 1 "register_operand" "=&d")
8972         (mod:DI (match_dup 2) (match_dup 3)))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8975   "#"
8976   [(set_attr "type" "multi")])
8977
8978 (define_insn "*divmoddi_noext_rex64"
8979   [(set (match_operand:DI 0 "register_operand" "=a")
8980         (div:DI (match_operand:DI 1 "register_operand" "0")
8981                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8982    (set (match_operand:DI 3 "register_operand" "=d")
8983         (mod:DI (match_dup 1) (match_dup 2)))
8984    (use (match_operand:DI 4 "register_operand" "3"))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_64BIT"
8987   "idiv{q}\t%2"
8988   [(set_attr "type" "idiv")
8989    (set_attr "mode" "DI")])
8990
8991 (define_split
8992   [(set (match_operand:DI 0 "register_operand" "")
8993         (div:DI (match_operand:DI 1 "register_operand" "")
8994                 (match_operand:DI 2 "nonimmediate_operand" "")))
8995    (set (match_operand:DI 3 "register_operand" "")
8996         (mod:DI (match_dup 1) (match_dup 2)))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "TARGET_64BIT && reload_completed"
8999   [(parallel [(set (match_dup 3)
9000                    (ashiftrt:DI (match_dup 4) (const_int 63)))
9001               (clobber (reg:CC FLAGS_REG))])
9002    (parallel [(set (match_dup 0)
9003                    (div:DI (reg:DI 0) (match_dup 2)))
9004               (set (match_dup 3)
9005                    (mod:DI (reg:DI 0) (match_dup 2)))
9006               (use (match_dup 3))
9007               (clobber (reg:CC FLAGS_REG))])]
9008 {
9009   /* Avoid use of cltd in favor of a mov+shift.  */
9010   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9011     {
9012       if (true_regnum (operands[1]))
9013         emit_move_insn (operands[0], operands[1]);
9014       else
9015         emit_move_insn (operands[3], operands[1]);
9016       operands[4] = operands[3];
9017     }
9018   else
9019     {
9020       gcc_assert (!true_regnum (operands[1]));
9021       operands[4] = operands[1];
9022     }
9023 })
9024
9025
9026 (define_expand "divmodsi4"
9027   [(parallel [(set (match_operand:SI 0 "register_operand" "")
9028                    (div:SI (match_operand:SI 1 "register_operand" "")
9029                            (match_operand:SI 2 "nonimmediate_operand" "")))
9030               (set (match_operand:SI 3 "register_operand" "")
9031                    (mod:SI (match_dup 1) (match_dup 2)))
9032               (clobber (reg:CC FLAGS_REG))])]
9033   ""
9034   "")
9035
9036 ;; Allow to come the parameter in eax or edx to avoid extra moves.
9037 ;; Penalize eax case slightly because it results in worse scheduling
9038 ;; of code.
9039 (define_insn "*divmodsi4_nocltd"
9040   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
9041         (div:SI (match_operand:SI 2 "register_operand" "1,0")
9042                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
9043    (set (match_operand:SI 1 "register_operand" "=&d,&d")
9044         (mod:SI (match_dup 2) (match_dup 3)))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
9047   "#"
9048   [(set_attr "type" "multi")])
9049
9050 (define_insn "*divmodsi4_cltd"
9051   [(set (match_operand:SI 0 "register_operand" "=a")
9052         (div:SI (match_operand:SI 2 "register_operand" "a")
9053                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
9054    (set (match_operand:SI 1 "register_operand" "=&d")
9055         (mod:SI (match_dup 2) (match_dup 3)))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
9058   "#"
9059   [(set_attr "type" "multi")])
9060
9061 (define_insn "*divmodsi_noext"
9062   [(set (match_operand:SI 0 "register_operand" "=a")
9063         (div:SI (match_operand:SI 1 "register_operand" "0")
9064                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9065    (set (match_operand:SI 3 "register_operand" "=d")
9066         (mod:SI (match_dup 1) (match_dup 2)))
9067    (use (match_operand:SI 4 "register_operand" "3"))
9068    (clobber (reg:CC FLAGS_REG))]
9069   ""
9070   "idiv{l}\t%2"
9071   [(set_attr "type" "idiv")
9072    (set_attr "mode" "SI")])
9073
9074 (define_split
9075   [(set (match_operand:SI 0 "register_operand" "")
9076         (div:SI (match_operand:SI 1 "register_operand" "")
9077                 (match_operand:SI 2 "nonimmediate_operand" "")))
9078    (set (match_operand:SI 3 "register_operand" "")
9079         (mod:SI (match_dup 1) (match_dup 2)))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "reload_completed"
9082   [(parallel [(set (match_dup 3)
9083                    (ashiftrt:SI (match_dup 4) (const_int 31)))
9084               (clobber (reg:CC FLAGS_REG))])
9085    (parallel [(set (match_dup 0)
9086                    (div:SI (reg:SI 0) (match_dup 2)))
9087               (set (match_dup 3)
9088                    (mod:SI (reg:SI 0) (match_dup 2)))
9089               (use (match_dup 3))
9090               (clobber (reg:CC FLAGS_REG))])]
9091 {
9092   /* Avoid use of cltd in favor of a mov+shift.  */
9093   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9094     {
9095       if (true_regnum (operands[1]))
9096         emit_move_insn (operands[0], operands[1]);
9097       else
9098         emit_move_insn (operands[3], operands[1]);
9099       operands[4] = operands[3];
9100     }
9101   else
9102     {
9103       gcc_assert (!true_regnum (operands[1]));
9104       operands[4] = operands[1];
9105     }
9106 })
9107 ;; %%% Split me.
9108 (define_insn "divmodhi4"
9109   [(set (match_operand:HI 0 "register_operand" "=a")
9110         (div:HI (match_operand:HI 1 "register_operand" "0")
9111                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9112    (set (match_operand:HI 3 "register_operand" "=&d")
9113         (mod:HI (match_dup 1) (match_dup 2)))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "TARGET_HIMODE_MATH"
9116   "cwtd\;idiv{w}\t%2"
9117   [(set_attr "type" "multi")
9118    (set_attr "length_immediate" "0")
9119    (set_attr "mode" "SI")])
9120
9121 (define_insn "udivmoddi4"
9122   [(set (match_operand:DI 0 "register_operand" "=a")
9123         (udiv:DI (match_operand:DI 1 "register_operand" "0")
9124                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
9125    (set (match_operand:DI 3 "register_operand" "=&d")
9126         (umod:DI (match_dup 1) (match_dup 2)))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "TARGET_64BIT"
9129   "xor{q}\t%3, %3\;div{q}\t%2"
9130   [(set_attr "type" "multi")
9131    (set_attr "length_immediate" "0")
9132    (set_attr "mode" "DI")])
9133
9134 (define_insn "*udivmoddi4_noext"
9135   [(set (match_operand:DI 0 "register_operand" "=a")
9136         (udiv:DI (match_operand:DI 1 "register_operand" "0")
9137                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
9138    (set (match_operand:DI 3 "register_operand" "=d")
9139         (umod:DI (match_dup 1) (match_dup 2)))
9140    (use (match_dup 3))
9141    (clobber (reg:CC FLAGS_REG))]
9142   "TARGET_64BIT"
9143   "div{q}\t%2"
9144   [(set_attr "type" "idiv")
9145    (set_attr "mode" "DI")])
9146
9147 (define_split
9148   [(set (match_operand:DI 0 "register_operand" "")
9149         (udiv:DI (match_operand:DI 1 "register_operand" "")
9150                  (match_operand:DI 2 "nonimmediate_operand" "")))
9151    (set (match_operand:DI 3 "register_operand" "")
9152         (umod:DI (match_dup 1) (match_dup 2)))
9153    (clobber (reg:CC FLAGS_REG))]
9154   "TARGET_64BIT && reload_completed"
9155   [(set (match_dup 3) (const_int 0))
9156    (parallel [(set (match_dup 0)
9157                    (udiv:DI (match_dup 1) (match_dup 2)))
9158               (set (match_dup 3)
9159                    (umod:DI (match_dup 1) (match_dup 2)))
9160               (use (match_dup 3))
9161               (clobber (reg:CC FLAGS_REG))])]
9162   "")
9163
9164 (define_insn "udivmodsi4"
9165   [(set (match_operand:SI 0 "register_operand" "=a")
9166         (udiv:SI (match_operand:SI 1 "register_operand" "0")
9167                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
9168    (set (match_operand:SI 3 "register_operand" "=&d")
9169         (umod:SI (match_dup 1) (match_dup 2)))
9170    (clobber (reg:CC FLAGS_REG))]
9171   ""
9172   "xor{l}\t%3, %3\;div{l}\t%2"
9173   [(set_attr "type" "multi")
9174    (set_attr "length_immediate" "0")
9175    (set_attr "mode" "SI")])
9176
9177 (define_insn "*udivmodsi4_noext"
9178   [(set (match_operand:SI 0 "register_operand" "=a")
9179         (udiv:SI (match_operand:SI 1 "register_operand" "0")
9180                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
9181    (set (match_operand:SI 3 "register_operand" "=d")
9182         (umod:SI (match_dup 1) (match_dup 2)))
9183    (use (match_dup 3))
9184    (clobber (reg:CC FLAGS_REG))]
9185   ""
9186   "div{l}\t%2"
9187   [(set_attr "type" "idiv")
9188    (set_attr "mode" "SI")])
9189
9190 (define_split
9191   [(set (match_operand:SI 0 "register_operand" "")
9192         (udiv:SI (match_operand:SI 1 "register_operand" "")
9193                  (match_operand:SI 2 "nonimmediate_operand" "")))
9194    (set (match_operand:SI 3 "register_operand" "")
9195         (umod:SI (match_dup 1) (match_dup 2)))
9196    (clobber (reg:CC FLAGS_REG))]
9197   "reload_completed"
9198   [(set (match_dup 3) (const_int 0))
9199    (parallel [(set (match_dup 0)
9200                    (udiv:SI (match_dup 1) (match_dup 2)))
9201               (set (match_dup 3)
9202                    (umod:SI (match_dup 1) (match_dup 2)))
9203               (use (match_dup 3))
9204               (clobber (reg:CC FLAGS_REG))])]
9205   "")
9206
9207 (define_expand "udivmodhi4"
9208   [(set (match_dup 4) (const_int 0))
9209    (parallel [(set (match_operand:HI 0 "register_operand" "")
9210                    (udiv:HI (match_operand:HI 1 "register_operand" "")
9211                             (match_operand:HI 2 "nonimmediate_operand" "")))
9212               (set (match_operand:HI 3 "register_operand" "")
9213                    (umod:HI (match_dup 1) (match_dup 2)))
9214               (use (match_dup 4))
9215               (clobber (reg:CC FLAGS_REG))])]
9216   "TARGET_HIMODE_MATH"
9217   "operands[4] = gen_reg_rtx (HImode);")
9218
9219 (define_insn "*udivmodhi_noext"
9220   [(set (match_operand:HI 0 "register_operand" "=a")
9221         (udiv:HI (match_operand:HI 1 "register_operand" "0")
9222                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
9223    (set (match_operand:HI 3 "register_operand" "=d")
9224         (umod:HI (match_dup 1) (match_dup 2)))
9225    (use (match_operand:HI 4 "register_operand" "3"))
9226    (clobber (reg:CC FLAGS_REG))]
9227   ""
9228   "div{w}\t%2"
9229   [(set_attr "type" "idiv")
9230    (set_attr "mode" "HI")])
9231
9232 ;; We cannot use div/idiv for double division, because it causes
9233 ;; "division by zero" on the overflow and that's not what we expect
9234 ;; from truncate.  Because true (non truncating) double division is
9235 ;; never generated, we can't create this insn anyway.
9236 ;
9237 ;(define_insn ""
9238 ;  [(set (match_operand:SI 0 "register_operand" "=a")
9239 ;       (truncate:SI
9240 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
9241 ;                  (zero_extend:DI
9242 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9243 ;   (set (match_operand:SI 3 "register_operand" "=d")
9244 ;       (truncate:SI
9245 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
9246 ;   (clobber (reg:CC FLAGS_REG))]
9247 ;  ""
9248 ;  "div{l}\t{%2, %0|%0, %2}"
9249 ;  [(set_attr "type" "idiv")])
9250 \f
9251 ;;- Logical AND instructions
9252
9253 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9254 ;; Note that this excludes ah.
9255
9256 (define_insn "*testdi_1_rex64"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
9260                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9261           (const_int 0)))]
9262   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9263    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9264   "@
9265    test{l}\t{%k1, %k0|%k0, %k1}
9266    test{l}\t{%k1, %k0|%k0, %k1}
9267    test{q}\t{%1, %0|%0, %1}
9268    test{q}\t{%1, %0|%0, %1}
9269    test{q}\t{%1, %0|%0, %1}"
9270   [(set_attr "type" "test")
9271    (set_attr "modrm" "0,1,0,1,1")
9272    (set_attr "mode" "SI,SI,DI,DI,DI")
9273    (set_attr "pent_pair" "uv,np,uv,np,uv")])
9274
9275 (define_insn "testsi_1"
9276   [(set (reg FLAGS_REG)
9277         (compare
9278           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
9279                   (match_operand:SI 1 "general_operand" "i,i,ri"))
9280           (const_int 0)))]
9281   "ix86_match_ccmode (insn, CCNOmode)
9282    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9283   "test{l}\t{%1, %0|%0, %1}"
9284   [(set_attr "type" "test")
9285    (set_attr "modrm" "0,1,1")
9286    (set_attr "mode" "SI")
9287    (set_attr "pent_pair" "uv,np,uv")])
9288
9289 (define_expand "testsi_ccno_1"
9290   [(set (reg:CCNO FLAGS_REG)
9291         (compare:CCNO
9292           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9293                   (match_operand:SI 1 "nonmemory_operand" ""))
9294           (const_int 0)))]
9295   ""
9296   "")
9297
9298 (define_insn "*testhi_1"
9299   [(set (reg FLAGS_REG)
9300         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
9301                          (match_operand:HI 1 "general_operand" "n,n,rn"))
9302                  (const_int 0)))]
9303   "ix86_match_ccmode (insn, CCNOmode)
9304    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9305   "test{w}\t{%1, %0|%0, %1}"
9306   [(set_attr "type" "test")
9307    (set_attr "modrm" "0,1,1")
9308    (set_attr "mode" "HI")
9309    (set_attr "pent_pair" "uv,np,uv")])
9310
9311 (define_expand "testqi_ccz_1"
9312   [(set (reg:CCZ FLAGS_REG)
9313         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9314                              (match_operand:QI 1 "nonmemory_operand" ""))
9315                  (const_int 0)))]
9316   ""
9317   "")
9318
9319 (define_insn "*testqi_1_maybe_si"
9320   [(set (reg FLAGS_REG)
9321         (compare
9322           (and:QI
9323             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9324             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9325           (const_int 0)))]
9326    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9327     && ix86_match_ccmode (insn,
9328                          CONST_INT_P (operands[1])
9329                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
9330 {
9331   if (which_alternative == 3)
9332     {
9333       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
9334         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
9335       return "test{l}\t{%1, %k0|%k0, %1}";
9336     }
9337   return "test{b}\t{%1, %0|%0, %1}";
9338 }
9339   [(set_attr "type" "test")
9340    (set_attr "modrm" "0,1,1,1")
9341    (set_attr "mode" "QI,QI,QI,SI")
9342    (set_attr "pent_pair" "uv,np,uv,np")])
9343
9344 (define_insn "*testqi_1"
9345   [(set (reg FLAGS_REG)
9346         (compare
9347           (and:QI
9348             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9349             (match_operand:QI 1 "general_operand" "n,n,qn"))
9350           (const_int 0)))]
9351   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9352    && ix86_match_ccmode (insn, CCNOmode)"
9353   "test{b}\t{%1, %0|%0, %1}"
9354   [(set_attr "type" "test")
9355    (set_attr "modrm" "0,1,1")
9356    (set_attr "mode" "QI")
9357    (set_attr "pent_pair" "uv,np,uv")])
9358
9359 (define_expand "testqi_ext_ccno_0"
9360   [(set (reg:CCNO FLAGS_REG)
9361         (compare:CCNO
9362           (and:SI
9363             (zero_extract:SI
9364               (match_operand 0 "ext_register_operand" "")
9365               (const_int 8)
9366               (const_int 8))
9367             (match_operand 1 "const_int_operand" ""))
9368           (const_int 0)))]
9369   ""
9370   "")
9371
9372 (define_insn "*testqi_ext_0"
9373   [(set (reg FLAGS_REG)
9374         (compare
9375           (and:SI
9376             (zero_extract:SI
9377               (match_operand 0 "ext_register_operand" "Q")
9378               (const_int 8)
9379               (const_int 8))
9380             (match_operand 1 "const_int_operand" "n"))
9381           (const_int 0)))]
9382   "ix86_match_ccmode (insn, CCNOmode)"
9383   "test{b}\t{%1, %h0|%h0, %1}"
9384   [(set_attr "type" "test")
9385    (set_attr "mode" "QI")
9386    (set_attr "length_immediate" "1")
9387    (set_attr "modrm" "1")
9388    (set_attr "pent_pair" "np")])
9389
9390 (define_insn "*testqi_ext_1"
9391   [(set (reg FLAGS_REG)
9392         (compare
9393           (and:SI
9394             (zero_extract:SI
9395               (match_operand 0 "ext_register_operand" "Q")
9396               (const_int 8)
9397               (const_int 8))
9398             (zero_extend:SI
9399               (match_operand:QI 1 "general_operand" "Qm")))
9400           (const_int 0)))]
9401   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9402    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9403   "test{b}\t{%1, %h0|%h0, %1}"
9404   [(set_attr "type" "test")
9405    (set_attr "mode" "QI")])
9406
9407 (define_insn "*testqi_ext_1_rex64"
9408   [(set (reg FLAGS_REG)
9409         (compare
9410           (and:SI
9411             (zero_extract:SI
9412               (match_operand 0 "ext_register_operand" "Q")
9413               (const_int 8)
9414               (const_int 8))
9415             (zero_extend:SI
9416               (match_operand:QI 1 "register_operand" "Q")))
9417           (const_int 0)))]
9418   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9419   "test{b}\t{%1, %h0|%h0, %1}"
9420   [(set_attr "type" "test")
9421    (set_attr "mode" "QI")])
9422
9423 (define_insn "*testqi_ext_2"
9424   [(set (reg FLAGS_REG)
9425         (compare
9426           (and:SI
9427             (zero_extract:SI
9428               (match_operand 0 "ext_register_operand" "Q")
9429               (const_int 8)
9430               (const_int 8))
9431             (zero_extract:SI
9432               (match_operand 1 "ext_register_operand" "Q")
9433               (const_int 8)
9434               (const_int 8)))
9435           (const_int 0)))]
9436   "ix86_match_ccmode (insn, CCNOmode)"
9437   "test{b}\t{%h1, %h0|%h0, %h1}"
9438   [(set_attr "type" "test")
9439    (set_attr "mode" "QI")])
9440
9441 ;; Combine likes to form bit extractions for some tests.  Humor it.
9442 (define_insn "*testqi_ext_3"
9443   [(set (reg FLAGS_REG)
9444         (compare (zero_extract:SI
9445                    (match_operand 0 "nonimmediate_operand" "rm")
9446                    (match_operand:SI 1 "const_int_operand" "")
9447                    (match_operand:SI 2 "const_int_operand" ""))
9448                  (const_int 0)))]
9449   "ix86_match_ccmode (insn, CCNOmode)
9450    && INTVAL (operands[1]) > 0
9451    && INTVAL (operands[2]) >= 0
9452    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9453    && (GET_MODE (operands[0]) == SImode
9454        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9455        || GET_MODE (operands[0]) == HImode
9456        || GET_MODE (operands[0]) == QImode)"
9457   "#")
9458
9459 (define_insn "*testqi_ext_3_rex64"
9460   [(set (reg FLAGS_REG)
9461         (compare (zero_extract:DI
9462                    (match_operand 0 "nonimmediate_operand" "rm")
9463                    (match_operand:DI 1 "const_int_operand" "")
9464                    (match_operand:DI 2 "const_int_operand" ""))
9465                  (const_int 0)))]
9466   "TARGET_64BIT
9467    && ix86_match_ccmode (insn, CCNOmode)
9468    && INTVAL (operands[1]) > 0
9469    && INTVAL (operands[2]) >= 0
9470    /* Ensure that resulting mask is zero or sign extended operand.  */
9471    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9472        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9473            && INTVAL (operands[1]) > 32))
9474    && (GET_MODE (operands[0]) == SImode
9475        || GET_MODE (operands[0]) == DImode
9476        || GET_MODE (operands[0]) == HImode
9477        || GET_MODE (operands[0]) == QImode)"
9478   "#")
9479
9480 (define_split
9481   [(set (match_operand 0 "flags_reg_operand" "")
9482         (match_operator 1 "compare_operator"
9483           [(zero_extract
9484              (match_operand 2 "nonimmediate_operand" "")
9485              (match_operand 3 "const_int_operand" "")
9486              (match_operand 4 "const_int_operand" ""))
9487            (const_int 0)]))]
9488   "ix86_match_ccmode (insn, CCNOmode)"
9489   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9490 {
9491   rtx val = operands[2];
9492   HOST_WIDE_INT len = INTVAL (operands[3]);
9493   HOST_WIDE_INT pos = INTVAL (operands[4]);
9494   HOST_WIDE_INT mask;
9495   enum machine_mode mode, submode;
9496
9497   mode = GET_MODE (val);
9498   if (MEM_P (val))
9499     {
9500       /* ??? Combine likes to put non-volatile mem extractions in QImode
9501          no matter the size of the test.  So find a mode that works.  */
9502       if (! MEM_VOLATILE_P (val))
9503         {
9504           mode = smallest_mode_for_size (pos + len, MODE_INT);
9505           val = adjust_address (val, mode, 0);
9506         }
9507     }
9508   else if (GET_CODE (val) == SUBREG
9509            && (submode = GET_MODE (SUBREG_REG (val)),
9510                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9511            && pos + len <= GET_MODE_BITSIZE (submode))
9512     {
9513       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9514       mode = submode;
9515       val = SUBREG_REG (val);
9516     }
9517   else if (mode == HImode && pos + len <= 8)
9518     {
9519       /* Small HImode tests can be converted to QImode.  */
9520       mode = QImode;
9521       val = gen_lowpart (QImode, val);
9522     }
9523
9524   if (len == HOST_BITS_PER_WIDE_INT)
9525     mask = -1;
9526   else
9527     mask = ((HOST_WIDE_INT)1 << len) - 1;
9528   mask <<= pos;
9529
9530   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9531 })
9532
9533 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9534 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9535 ;; this is relatively important trick.
9536 ;; Do the conversion only post-reload to avoid limiting of the register class
9537 ;; to QI regs.
9538 (define_split
9539   [(set (match_operand 0 "flags_reg_operand" "")
9540         (match_operator 1 "compare_operator"
9541           [(and (match_operand 2 "register_operand" "")
9542                 (match_operand 3 "const_int_operand" ""))
9543            (const_int 0)]))]
9544    "reload_completed
9545     && QI_REG_P (operands[2])
9546     && GET_MODE (operands[2]) != QImode
9547     && ((ix86_match_ccmode (insn, CCZmode)
9548          && !(INTVAL (operands[3]) & ~(255 << 8)))
9549         || (ix86_match_ccmode (insn, CCNOmode)
9550             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9551   [(set (match_dup 0)
9552         (match_op_dup 1
9553           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9554                    (match_dup 3))
9555            (const_int 0)]))]
9556   "operands[2] = gen_lowpart (SImode, operands[2]);
9557    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9558
9559 (define_split
9560   [(set (match_operand 0 "flags_reg_operand" "")
9561         (match_operator 1 "compare_operator"
9562           [(and (match_operand 2 "nonimmediate_operand" "")
9563                 (match_operand 3 "const_int_operand" ""))
9564            (const_int 0)]))]
9565    "reload_completed
9566     && GET_MODE (operands[2]) != QImode
9567     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9568     && ((ix86_match_ccmode (insn, CCZmode)
9569          && !(INTVAL (operands[3]) & ~255))
9570         || (ix86_match_ccmode (insn, CCNOmode)
9571             && !(INTVAL (operands[3]) & ~127)))"
9572   [(set (match_dup 0)
9573         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9574                          (const_int 0)]))]
9575   "operands[2] = gen_lowpart (QImode, operands[2]);
9576    operands[3] = gen_lowpart (QImode, operands[3]);")
9577
9578
9579 ;; %%% This used to optimize known byte-wide and operations to memory,
9580 ;; and sometimes to QImode registers.  If this is considered useful,
9581 ;; it should be done with splitters.
9582
9583 (define_expand "anddi3"
9584   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9585         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9586                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9587   "TARGET_64BIT"
9588   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9589
9590 (define_insn "*anddi_1_rex64"
9591   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9592         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9593                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9596 {
9597   switch (get_attr_type (insn))
9598     {
9599     case TYPE_IMOVX:
9600       {
9601         enum machine_mode mode;
9602
9603         gcc_assert (CONST_INT_P (operands[2]));
9604         if (INTVAL (operands[2]) == 0xff)
9605           mode = QImode;
9606         else
9607           {
9608             gcc_assert (INTVAL (operands[2]) == 0xffff);
9609             mode = HImode;
9610           }
9611
9612         operands[1] = gen_lowpart (mode, operands[1]);
9613         if (mode == QImode)
9614           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9615         else
9616           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9617       }
9618
9619     default:
9620       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9621       if (get_attr_mode (insn) == MODE_SI)
9622         return "and{l}\t{%k2, %k0|%k0, %k2}";
9623       else
9624         return "and{q}\t{%2, %0|%0, %2}";
9625     }
9626 }
9627   [(set_attr "type" "alu,alu,alu,imovx")
9628    (set_attr "length_immediate" "*,*,*,0")
9629    (set (attr "prefix_rex")
9630      (if_then_else
9631        (and (eq_attr "type" "imovx")
9632             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9633                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9634        (const_string "1")
9635        (const_string "*")))
9636    (set_attr "mode" "SI,DI,DI,SI")])
9637
9638 (define_insn "*anddi_2"
9639   [(set (reg FLAGS_REG)
9640         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9641                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9642                  (const_int 0)))
9643    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9644         (and:DI (match_dup 1) (match_dup 2)))]
9645   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9646    && ix86_binary_operator_ok (AND, DImode, operands)"
9647   "@
9648    and{l}\t{%k2, %k0|%k0, %k2}
9649    and{q}\t{%2, %0|%0, %2}
9650    and{q}\t{%2, %0|%0, %2}"
9651   [(set_attr "type" "alu")
9652    (set_attr "mode" "SI,DI,DI")])
9653
9654 (define_expand "andsi3"
9655   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9656         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9657                 (match_operand:SI 2 "general_operand" "")))]
9658   ""
9659   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9660
9661 (define_insn "*andsi_1"
9662   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9663         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9664                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9665    (clobber (reg:CC FLAGS_REG))]
9666   "ix86_binary_operator_ok (AND, SImode, operands)"
9667 {
9668   switch (get_attr_type (insn))
9669     {
9670     case TYPE_IMOVX:
9671       {
9672         enum machine_mode mode;
9673
9674         gcc_assert (CONST_INT_P (operands[2]));
9675         if (INTVAL (operands[2]) == 0xff)
9676           mode = QImode;
9677         else
9678           {
9679             gcc_assert (INTVAL (operands[2]) == 0xffff);
9680             mode = HImode;
9681           }
9682
9683         operands[1] = gen_lowpart (mode, operands[1]);
9684         if (mode == QImode)
9685           return "movz{bl|x}\t{%1, %0|%0, %1}";
9686         else
9687           return "movz{wl|x}\t{%1, %0|%0, %1}";
9688       }
9689
9690     default:
9691       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9692       return "and{l}\t{%2, %0|%0, %2}";
9693     }
9694 }
9695   [(set_attr "type" "alu,alu,imovx")
9696    (set (attr "prefix_rex")
9697      (if_then_else
9698        (and (eq_attr "type" "imovx")
9699             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9700                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9701        (const_string "1")
9702        (const_string "*")))
9703    (set_attr "length_immediate" "*,*,0")
9704    (set_attr "mode" "SI")])
9705
9706 (define_split
9707   [(set (match_operand 0 "register_operand" "")
9708         (and (match_dup 0)
9709              (const_int -65536)))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9712   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9713   "operands[1] = gen_lowpart (HImode, operands[0]);")
9714
9715 (define_split
9716   [(set (match_operand 0 "ext_register_operand" "")
9717         (and (match_dup 0)
9718              (const_int -256)))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9721   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9722   "operands[1] = gen_lowpart (QImode, operands[0]);")
9723
9724 (define_split
9725   [(set (match_operand 0 "ext_register_operand" "")
9726         (and (match_dup 0)
9727              (const_int -65281)))
9728    (clobber (reg:CC FLAGS_REG))]
9729   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9730   [(parallel [(set (zero_extract:SI (match_dup 0)
9731                                     (const_int 8)
9732                                     (const_int 8))
9733                    (xor:SI
9734                      (zero_extract:SI (match_dup 0)
9735                                       (const_int 8)
9736                                       (const_int 8))
9737                      (zero_extract:SI (match_dup 0)
9738                                       (const_int 8)
9739                                       (const_int 8))))
9740               (clobber (reg:CC FLAGS_REG))])]
9741   "operands[0] = gen_lowpart (SImode, operands[0]);")
9742
9743 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9744 (define_insn "*andsi_1_zext"
9745   [(set (match_operand:DI 0 "register_operand" "=r")
9746         (zero_extend:DI
9747           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9748                   (match_operand:SI 2 "general_operand" "g"))))
9749    (clobber (reg:CC FLAGS_REG))]
9750   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9751   "and{l}\t{%2, %k0|%k0, %2}"
9752   [(set_attr "type" "alu")
9753    (set_attr "mode" "SI")])
9754
9755 (define_insn "*andsi_2"
9756   [(set (reg FLAGS_REG)
9757         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9758                          (match_operand:SI 2 "general_operand" "g,ri"))
9759                  (const_int 0)))
9760    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9761         (and:SI (match_dup 1) (match_dup 2)))]
9762   "ix86_match_ccmode (insn, CCNOmode)
9763    && ix86_binary_operator_ok (AND, SImode, operands)"
9764   "and{l}\t{%2, %0|%0, %2}"
9765   [(set_attr "type" "alu")
9766    (set_attr "mode" "SI")])
9767
9768 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9769 (define_insn "*andsi_2_zext"
9770   [(set (reg FLAGS_REG)
9771         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9772                          (match_operand:SI 2 "general_operand" "g"))
9773                  (const_int 0)))
9774    (set (match_operand:DI 0 "register_operand" "=r")
9775         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9776   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9777    && ix86_binary_operator_ok (AND, SImode, operands)"
9778   "and{l}\t{%2, %k0|%k0, %2}"
9779   [(set_attr "type" "alu")
9780    (set_attr "mode" "SI")])
9781
9782 (define_expand "andhi3"
9783   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9784         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9785                 (match_operand:HI 2 "general_operand" "")))]
9786   "TARGET_HIMODE_MATH"
9787   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9788
9789 (define_insn "*andhi_1"
9790   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9791         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9792                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9793    (clobber (reg:CC FLAGS_REG))]
9794   "ix86_binary_operator_ok (AND, HImode, operands)"
9795 {
9796   switch (get_attr_type (insn))
9797     {
9798     case TYPE_IMOVX:
9799       gcc_assert (CONST_INT_P (operands[2]));
9800       gcc_assert (INTVAL (operands[2]) == 0xff);
9801       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9802
9803     default:
9804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9805
9806       return "and{w}\t{%2, %0|%0, %2}";
9807     }
9808 }
9809   [(set_attr "type" "alu,alu,imovx")
9810    (set_attr "length_immediate" "*,*,0")
9811    (set (attr "prefix_rex")
9812      (if_then_else
9813        (and (eq_attr "type" "imovx")
9814             (match_operand 1 "ext_QIreg_nomode_operand" ""))
9815        (const_string "1")
9816        (const_string "*")))
9817    (set_attr "mode" "HI,HI,SI")])
9818
9819 (define_insn "*andhi_2"
9820   [(set (reg FLAGS_REG)
9821         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9822                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9823                  (const_int 0)))
9824    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9825         (and:HI (match_dup 1) (match_dup 2)))]
9826   "ix86_match_ccmode (insn, CCNOmode)
9827    && ix86_binary_operator_ok (AND, HImode, operands)"
9828   "and{w}\t{%2, %0|%0, %2}"
9829   [(set_attr "type" "alu")
9830    (set_attr "mode" "HI")])
9831
9832 (define_expand "andqi3"
9833   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9834         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9835                 (match_operand:QI 2 "general_operand" "")))]
9836   "TARGET_QIMODE_MATH"
9837   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9838
9839 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9840 (define_insn "*andqi_1"
9841   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9842         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9843                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "ix86_binary_operator_ok (AND, QImode, operands)"
9846   "@
9847    and{b}\t{%2, %0|%0, %2}
9848    and{b}\t{%2, %0|%0, %2}
9849    and{l}\t{%k2, %k0|%k0, %k2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "mode" "QI,QI,SI")])
9852
9853 (define_insn "*andqi_1_slp"
9854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9855         (and:QI (match_dup 0)
9856                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9857    (clobber (reg:CC FLAGS_REG))]
9858   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9859    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9860   "and{b}\t{%1, %0|%0, %1}"
9861   [(set_attr "type" "alu1")
9862    (set_attr "mode" "QI")])
9863
9864 (define_insn "*andqi_2_maybe_si"
9865   [(set (reg FLAGS_REG)
9866         (compare (and:QI
9867                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9868                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9869                  (const_int 0)))
9870    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9871         (and:QI (match_dup 1) (match_dup 2)))]
9872   "ix86_binary_operator_ok (AND, QImode, operands)
9873    && ix86_match_ccmode (insn,
9874                          CONST_INT_P (operands[2])
9875                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9876 {
9877   if (which_alternative == 2)
9878     {
9879       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9880         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9881       return "and{l}\t{%2, %k0|%k0, %2}";
9882     }
9883   return "and{b}\t{%2, %0|%0, %2}";
9884 }
9885   [(set_attr "type" "alu")
9886    (set_attr "mode" "QI,QI,SI")])
9887
9888 (define_insn "*andqi_2"
9889   [(set (reg FLAGS_REG)
9890         (compare (and:QI
9891                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9892                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9893                  (const_int 0)))
9894    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9895         (and:QI (match_dup 1) (match_dup 2)))]
9896   "ix86_match_ccmode (insn, CCNOmode)
9897    && ix86_binary_operator_ok (AND, QImode, operands)"
9898   "and{b}\t{%2, %0|%0, %2}"
9899   [(set_attr "type" "alu")
9900    (set_attr "mode" "QI")])
9901
9902 (define_insn "*andqi_2_slp"
9903   [(set (reg FLAGS_REG)
9904         (compare (and:QI
9905                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9906                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9907                  (const_int 0)))
9908    (set (strict_low_part (match_dup 0))
9909         (and:QI (match_dup 0) (match_dup 1)))]
9910   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9911    && ix86_match_ccmode (insn, CCNOmode)
9912    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9913   "and{b}\t{%1, %0|%0, %1}"
9914   [(set_attr "type" "alu1")
9915    (set_attr "mode" "QI")])
9916
9917 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9918 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9919 ;; for a QImode operand, which of course failed.
9920
9921 (define_insn "andqi_ext_0"
9922   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9923                          (const_int 8)
9924                          (const_int 8))
9925         (and:SI
9926           (zero_extract:SI
9927             (match_operand 1 "ext_register_operand" "0")
9928             (const_int 8)
9929             (const_int 8))
9930           (match_operand 2 "const_int_operand" "n")))
9931    (clobber (reg:CC FLAGS_REG))]
9932   ""
9933   "and{b}\t{%2, %h0|%h0, %2}"
9934   [(set_attr "type" "alu")
9935    (set_attr "length_immediate" "1")
9936    (set_attr "modrm" "1")
9937    (set_attr "mode" "QI")])
9938
9939 ;; Generated by peephole translating test to and.  This shows up
9940 ;; often in fp comparisons.
9941
9942 (define_insn "*andqi_ext_0_cc"
9943   [(set (reg FLAGS_REG)
9944         (compare
9945           (and:SI
9946             (zero_extract:SI
9947               (match_operand 1 "ext_register_operand" "0")
9948               (const_int 8)
9949               (const_int 8))
9950             (match_operand 2 "const_int_operand" "n"))
9951           (const_int 0)))
9952    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9953                          (const_int 8)
9954                          (const_int 8))
9955         (and:SI
9956           (zero_extract:SI
9957             (match_dup 1)
9958             (const_int 8)
9959             (const_int 8))
9960           (match_dup 2)))]
9961   "ix86_match_ccmode (insn, CCNOmode)"
9962   "and{b}\t{%2, %h0|%h0, %2}"
9963   [(set_attr "type" "alu")
9964    (set_attr "length_immediate" "1")
9965    (set_attr "modrm" "1")
9966    (set_attr "mode" "QI")])
9967
9968 (define_insn "*andqi_ext_1"
9969   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9970                          (const_int 8)
9971                          (const_int 8))
9972         (and:SI
9973           (zero_extract:SI
9974             (match_operand 1 "ext_register_operand" "0")
9975             (const_int 8)
9976             (const_int 8))
9977           (zero_extend:SI
9978             (match_operand:QI 2 "general_operand" "Qm"))))
9979    (clobber (reg:CC FLAGS_REG))]
9980   "!TARGET_64BIT"
9981   "and{b}\t{%2, %h0|%h0, %2}"
9982   [(set_attr "type" "alu")
9983    (set_attr "length_immediate" "0")
9984    (set_attr "mode" "QI")])
9985
9986 (define_insn "*andqi_ext_1_rex64"
9987   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9988                          (const_int 8)
9989                          (const_int 8))
9990         (and:SI
9991           (zero_extract:SI
9992             (match_operand 1 "ext_register_operand" "0")
9993             (const_int 8)
9994             (const_int 8))
9995           (zero_extend:SI
9996             (match_operand 2 "ext_register_operand" "Q"))))
9997    (clobber (reg:CC FLAGS_REG))]
9998   "TARGET_64BIT"
9999   "and{b}\t{%2, %h0|%h0, %2}"
10000   [(set_attr "type" "alu")
10001    (set_attr "length_immediate" "0")
10002    (set_attr "mode" "QI")])
10003
10004 (define_insn "*andqi_ext_2"
10005   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10006                          (const_int 8)
10007                          (const_int 8))
10008         (and:SI
10009           (zero_extract:SI
10010             (match_operand 1 "ext_register_operand" "%0")
10011             (const_int 8)
10012             (const_int 8))
10013           (zero_extract:SI
10014             (match_operand 2 "ext_register_operand" "Q")
10015             (const_int 8)
10016             (const_int 8))))
10017    (clobber (reg:CC FLAGS_REG))]
10018   ""
10019   "and{b}\t{%h2, %h0|%h0, %h2}"
10020   [(set_attr "type" "alu")
10021    (set_attr "length_immediate" "0")
10022    (set_attr "mode" "QI")])
10023
10024 ;; Convert wide AND instructions with immediate operand to shorter QImode
10025 ;; equivalents when possible.
10026 ;; Don't do the splitting with memory operands, since it introduces risk
10027 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
10028 ;; for size, but that can (should?) be handled by generic code instead.
10029 (define_split
10030   [(set (match_operand 0 "register_operand" "")
10031         (and (match_operand 1 "register_operand" "")
10032              (match_operand 2 "const_int_operand" "")))
10033    (clobber (reg:CC FLAGS_REG))]
10034    "reload_completed
10035     && QI_REG_P (operands[0])
10036     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10037     && !(~INTVAL (operands[2]) & ~(255 << 8))
10038     && GET_MODE (operands[0]) != QImode"
10039   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10040                    (and:SI (zero_extract:SI (match_dup 1)
10041                                             (const_int 8) (const_int 8))
10042                            (match_dup 2)))
10043               (clobber (reg:CC FLAGS_REG))])]
10044   "operands[0] = gen_lowpart (SImode, operands[0]);
10045    operands[1] = gen_lowpart (SImode, operands[1]);
10046    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10047
10048 ;; Since AND can be encoded with sign extended immediate, this is only
10049 ;; profitable when 7th bit is not set.
10050 (define_split
10051   [(set (match_operand 0 "register_operand" "")
10052         (and (match_operand 1 "general_operand" "")
10053              (match_operand 2 "const_int_operand" "")))
10054    (clobber (reg:CC FLAGS_REG))]
10055    "reload_completed
10056     && ANY_QI_REG_P (operands[0])
10057     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10058     && !(~INTVAL (operands[2]) & ~255)
10059     && !(INTVAL (operands[2]) & 128)
10060     && GET_MODE (operands[0]) != QImode"
10061   [(parallel [(set (strict_low_part (match_dup 0))
10062                    (and:QI (match_dup 1)
10063                            (match_dup 2)))
10064               (clobber (reg:CC FLAGS_REG))])]
10065   "operands[0] = gen_lowpart (QImode, operands[0]);
10066    operands[1] = gen_lowpart (QImode, operands[1]);
10067    operands[2] = gen_lowpart (QImode, operands[2]);")
10068 \f
10069 ;; Logical inclusive OR instructions
10070
10071 ;; %%% This used to optimize known byte-wide and operations to memory.
10072 ;; If this is considered useful, it should be done with splitters.
10073
10074 (define_expand "iordi3"
10075   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10076         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
10077                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10078   "TARGET_64BIT"
10079   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
10080
10081 (define_insn "*iordi_1_rex64"
10082   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10083         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10084                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
10085    (clobber (reg:CC FLAGS_REG))]
10086   "TARGET_64BIT
10087    && ix86_binary_operator_ok (IOR, DImode, operands)"
10088   "or{q}\t{%2, %0|%0, %2}"
10089   [(set_attr "type" "alu")
10090    (set_attr "mode" "DI")])
10091
10092 (define_insn "*iordi_2_rex64"
10093   [(set (reg FLAGS_REG)
10094         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10095                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10096                  (const_int 0)))
10097    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10098         (ior:DI (match_dup 1) (match_dup 2)))]
10099   "TARGET_64BIT
10100    && ix86_match_ccmode (insn, CCNOmode)
10101    && ix86_binary_operator_ok (IOR, DImode, operands)"
10102   "or{q}\t{%2, %0|%0, %2}"
10103   [(set_attr "type" "alu")
10104    (set_attr "mode" "DI")])
10105
10106 (define_insn "*iordi_3_rex64"
10107   [(set (reg FLAGS_REG)
10108         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10109                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10110                  (const_int 0)))
10111    (clobber (match_scratch:DI 0 "=r"))]
10112   "TARGET_64BIT
10113    && ix86_match_ccmode (insn, CCNOmode)
10114    && ix86_binary_operator_ok (IOR, DImode, operands)"
10115   "or{q}\t{%2, %0|%0, %2}"
10116   [(set_attr "type" "alu")
10117    (set_attr "mode" "DI")])
10118
10119
10120 (define_expand "iorsi3"
10121   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10122         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
10123                 (match_operand:SI 2 "general_operand" "")))]
10124   ""
10125   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
10126
10127 (define_insn "*iorsi_1"
10128   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10129         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10130                 (match_operand:SI 2 "general_operand" "ri,g")))
10131    (clobber (reg:CC FLAGS_REG))]
10132   "ix86_binary_operator_ok (IOR, SImode, operands)"
10133   "or{l}\t{%2, %0|%0, %2}"
10134   [(set_attr "type" "alu")
10135    (set_attr "mode" "SI")])
10136
10137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10138 (define_insn "*iorsi_1_zext"
10139   [(set (match_operand:DI 0 "register_operand" "=r")
10140         (zero_extend:DI
10141           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10142                   (match_operand:SI 2 "general_operand" "g"))))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
10145   "or{l}\t{%2, %k0|%k0, %2}"
10146   [(set_attr "type" "alu")
10147    (set_attr "mode" "SI")])
10148
10149 (define_insn "*iorsi_1_zext_imm"
10150   [(set (match_operand:DI 0 "register_operand" "=r")
10151         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10152                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10153    (clobber (reg:CC FLAGS_REG))]
10154   "TARGET_64BIT"
10155   "or{l}\t{%2, %k0|%k0, %2}"
10156   [(set_attr "type" "alu")
10157    (set_attr "mode" "SI")])
10158
10159 (define_insn "*iorsi_2"
10160   [(set (reg FLAGS_REG)
10161         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10162                          (match_operand:SI 2 "general_operand" "g,ri"))
10163                  (const_int 0)))
10164    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10165         (ior:SI (match_dup 1) (match_dup 2)))]
10166   "ix86_match_ccmode (insn, CCNOmode)
10167    && ix86_binary_operator_ok (IOR, SImode, operands)"
10168   "or{l}\t{%2, %0|%0, %2}"
10169   [(set_attr "type" "alu")
10170    (set_attr "mode" "SI")])
10171
10172 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10173 ;; ??? Special case for immediate operand is missing - it is tricky.
10174 (define_insn "*iorsi_2_zext"
10175   [(set (reg FLAGS_REG)
10176         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10177                          (match_operand:SI 2 "general_operand" "g"))
10178                  (const_int 0)))
10179    (set (match_operand:DI 0 "register_operand" "=r")
10180         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
10181   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10182    && ix86_binary_operator_ok (IOR, SImode, operands)"
10183   "or{l}\t{%2, %k0|%k0, %2}"
10184   [(set_attr "type" "alu")
10185    (set_attr "mode" "SI")])
10186
10187 (define_insn "*iorsi_2_zext_imm"
10188   [(set (reg FLAGS_REG)
10189         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10190                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10191                  (const_int 0)))
10192    (set (match_operand:DI 0 "register_operand" "=r")
10193         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10194   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10195    && ix86_binary_operator_ok (IOR, SImode, operands)"
10196   "or{l}\t{%2, %k0|%k0, %2}"
10197   [(set_attr "type" "alu")
10198    (set_attr "mode" "SI")])
10199
10200 (define_insn "*iorsi_3"
10201   [(set (reg FLAGS_REG)
10202         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10203                          (match_operand:SI 2 "general_operand" "g"))
10204                  (const_int 0)))
10205    (clobber (match_scratch:SI 0 "=r"))]
10206   "ix86_match_ccmode (insn, CCNOmode)
10207    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10208   "or{l}\t{%2, %0|%0, %2}"
10209   [(set_attr "type" "alu")
10210    (set_attr "mode" "SI")])
10211
10212 (define_expand "iorhi3"
10213   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10214         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
10215                 (match_operand:HI 2 "general_operand" "")))]
10216   "TARGET_HIMODE_MATH"
10217   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
10218
10219 (define_insn "*iorhi_1"
10220   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10221         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10222                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "ix86_binary_operator_ok (IOR, HImode, operands)"
10225   "or{w}\t{%2, %0|%0, %2}"
10226   [(set_attr "type" "alu")
10227    (set_attr "mode" "HI")])
10228
10229 (define_insn "*iorhi_2"
10230   [(set (reg FLAGS_REG)
10231         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10232                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10233                  (const_int 0)))
10234    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10235         (ior:HI (match_dup 1) (match_dup 2)))]
10236   "ix86_match_ccmode (insn, CCNOmode)
10237    && ix86_binary_operator_ok (IOR, HImode, operands)"
10238   "or{w}\t{%2, %0|%0, %2}"
10239   [(set_attr "type" "alu")
10240    (set_attr "mode" "HI")])
10241
10242 (define_insn "*iorhi_3"
10243   [(set (reg FLAGS_REG)
10244         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10245                          (match_operand:HI 2 "general_operand" "rmn"))
10246                  (const_int 0)))
10247    (clobber (match_scratch:HI 0 "=r"))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10250   "or{w}\t{%2, %0|%0, %2}"
10251   [(set_attr "type" "alu")
10252    (set_attr "mode" "HI")])
10253
10254 (define_expand "iorqi3"
10255   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10256         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
10257                 (match_operand:QI 2 "general_operand" "")))]
10258   "TARGET_QIMODE_MATH"
10259   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10260
10261 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10262 (define_insn "*iorqi_1"
10263   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10264         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10265                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "ix86_binary_operator_ok (IOR, QImode, operands)"
10268   "@
10269    or{b}\t{%2, %0|%0, %2}
10270    or{b}\t{%2, %0|%0, %2}
10271    or{l}\t{%k2, %k0|%k0, %k2}"
10272   [(set_attr "type" "alu")
10273    (set_attr "mode" "QI,QI,SI")])
10274
10275 (define_insn "*iorqi_1_slp"
10276   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10277         (ior:QI (match_dup 0)
10278                 (match_operand:QI 1 "general_operand" "qmn,qn")))
10279    (clobber (reg:CC FLAGS_REG))]
10280   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10281    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10282   "or{b}\t{%1, %0|%0, %1}"
10283   [(set_attr "type" "alu1")
10284    (set_attr "mode" "QI")])
10285
10286 (define_insn "*iorqi_2"
10287   [(set (reg FLAGS_REG)
10288         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10289                          (match_operand:QI 2 "general_operand" "qmn,qn"))
10290                  (const_int 0)))
10291    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10292         (ior:QI (match_dup 1) (match_dup 2)))]
10293   "ix86_match_ccmode (insn, CCNOmode)
10294    && ix86_binary_operator_ok (IOR, QImode, operands)"
10295   "or{b}\t{%2, %0|%0, %2}"
10296   [(set_attr "type" "alu")
10297    (set_attr "mode" "QI")])
10298
10299 (define_insn "*iorqi_2_slp"
10300   [(set (reg FLAGS_REG)
10301         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10302                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10303                  (const_int 0)))
10304    (set (strict_low_part (match_dup 0))
10305         (ior:QI (match_dup 0) (match_dup 1)))]
10306   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10307    && ix86_match_ccmode (insn, CCNOmode)
10308    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10309   "or{b}\t{%1, %0|%0, %1}"
10310   [(set_attr "type" "alu1")
10311    (set_attr "mode" "QI")])
10312
10313 (define_insn "*iorqi_3"
10314   [(set (reg FLAGS_REG)
10315         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10316                          (match_operand:QI 2 "general_operand" "qmn"))
10317                  (const_int 0)))
10318    (clobber (match_scratch:QI 0 "=q"))]
10319   "ix86_match_ccmode (insn, CCNOmode)
10320    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10321   "or{b}\t{%2, %0|%0, %2}"
10322   [(set_attr "type" "alu")
10323    (set_attr "mode" "QI")])
10324
10325 (define_insn "*iorqi_ext_0"
10326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10327                          (const_int 8)
10328                          (const_int 8))
10329         (ior:SI
10330           (zero_extract:SI
10331             (match_operand 1 "ext_register_operand" "0")
10332             (const_int 8)
10333             (const_int 8))
10334           (match_operand 2 "const_int_operand" "n")))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10337   "or{b}\t{%2, %h0|%h0, %2}"
10338   [(set_attr "type" "alu")
10339    (set_attr "length_immediate" "1")
10340    (set_attr "modrm" "1")
10341    (set_attr "mode" "QI")])
10342
10343 (define_insn "*iorqi_ext_1"
10344   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10345                          (const_int 8)
10346                          (const_int 8))
10347         (ior:SI
10348           (zero_extract:SI
10349             (match_operand 1 "ext_register_operand" "0")
10350             (const_int 8)
10351             (const_int 8))
10352           (zero_extend:SI
10353             (match_operand:QI 2 "general_operand" "Qm"))))
10354    (clobber (reg:CC FLAGS_REG))]
10355   "!TARGET_64BIT
10356    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10357   "or{b}\t{%2, %h0|%h0, %2}"
10358   [(set_attr "type" "alu")
10359    (set_attr "length_immediate" "0")
10360    (set_attr "mode" "QI")])
10361
10362 (define_insn "*iorqi_ext_1_rex64"
10363   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10364                          (const_int 8)
10365                          (const_int 8))
10366         (ior:SI
10367           (zero_extract:SI
10368             (match_operand 1 "ext_register_operand" "0")
10369             (const_int 8)
10370             (const_int 8))
10371           (zero_extend:SI
10372             (match_operand 2 "ext_register_operand" "Q"))))
10373    (clobber (reg:CC FLAGS_REG))]
10374   "TARGET_64BIT
10375    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10376   "or{b}\t{%2, %h0|%h0, %2}"
10377   [(set_attr "type" "alu")
10378    (set_attr "length_immediate" "0")
10379    (set_attr "mode" "QI")])
10380
10381 (define_insn "*iorqi_ext_2"
10382   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10383                          (const_int 8)
10384                          (const_int 8))
10385         (ior:SI
10386           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10387                            (const_int 8)
10388                            (const_int 8))
10389           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10390                            (const_int 8)
10391                            (const_int 8))))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10394   "ior{b}\t{%h2, %h0|%h0, %h2}"
10395   [(set_attr "type" "alu")
10396    (set_attr "length_immediate" "0")
10397    (set_attr "mode" "QI")])
10398
10399 (define_split
10400   [(set (match_operand 0 "register_operand" "")
10401         (ior (match_operand 1 "register_operand" "")
10402              (match_operand 2 "const_int_operand" "")))
10403    (clobber (reg:CC FLAGS_REG))]
10404    "reload_completed
10405     && QI_REG_P (operands[0])
10406     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10407     && !(INTVAL (operands[2]) & ~(255 << 8))
10408     && GET_MODE (operands[0]) != QImode"
10409   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10410                    (ior:SI (zero_extract:SI (match_dup 1)
10411                                             (const_int 8) (const_int 8))
10412                            (match_dup 2)))
10413               (clobber (reg:CC FLAGS_REG))])]
10414   "operands[0] = gen_lowpart (SImode, operands[0]);
10415    operands[1] = gen_lowpart (SImode, operands[1]);
10416    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10417
10418 ;; Since OR can be encoded with sign extended immediate, this is only
10419 ;; profitable when 7th bit is set.
10420 (define_split
10421   [(set (match_operand 0 "register_operand" "")
10422         (ior (match_operand 1 "general_operand" "")
10423              (match_operand 2 "const_int_operand" "")))
10424    (clobber (reg:CC FLAGS_REG))]
10425    "reload_completed
10426     && ANY_QI_REG_P (operands[0])
10427     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10428     && !(INTVAL (operands[2]) & ~255)
10429     && (INTVAL (operands[2]) & 128)
10430     && GET_MODE (operands[0]) != QImode"
10431   [(parallel [(set (strict_low_part (match_dup 0))
10432                    (ior:QI (match_dup 1)
10433                            (match_dup 2)))
10434               (clobber (reg:CC FLAGS_REG))])]
10435   "operands[0] = gen_lowpart (QImode, operands[0]);
10436    operands[1] = gen_lowpart (QImode, operands[1]);
10437    operands[2] = gen_lowpart (QImode, operands[2]);")
10438 \f
10439 ;; Logical XOR instructions
10440
10441 ;; %%% This used to optimize known byte-wide and operations to memory.
10442 ;; If this is considered useful, it should be done with splitters.
10443
10444 (define_expand "xordi3"
10445   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10446         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10447                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10448   "TARGET_64BIT"
10449   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10450
10451 (define_insn "*xordi_1_rex64"
10452   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10453         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10454                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10455    (clobber (reg:CC FLAGS_REG))]
10456   "TARGET_64BIT
10457    && ix86_binary_operator_ok (XOR, DImode, operands)"
10458   "xor{q}\t{%2, %0|%0, %2}"
10459   [(set_attr "type" "alu")
10460    (set_attr "mode" "DI")])
10461
10462 (define_insn "*xordi_2_rex64"
10463   [(set (reg FLAGS_REG)
10464         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10465                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10466                  (const_int 0)))
10467    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10468         (xor:DI (match_dup 1) (match_dup 2)))]
10469   "TARGET_64BIT
10470    && ix86_match_ccmode (insn, CCNOmode)
10471    && ix86_binary_operator_ok (XOR, DImode, operands)"
10472   "xor{q}\t{%2, %0|%0, %2}"
10473   [(set_attr "type" "alu")
10474    (set_attr "mode" "DI")])
10475
10476 (define_insn "*xordi_3_rex64"
10477   [(set (reg FLAGS_REG)
10478         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10479                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10480                  (const_int 0)))
10481    (clobber (match_scratch:DI 0 "=r"))]
10482   "TARGET_64BIT
10483    && ix86_match_ccmode (insn, CCNOmode)
10484    && ix86_binary_operator_ok (XOR, DImode, operands)"
10485   "xor{q}\t{%2, %0|%0, %2}"
10486   [(set_attr "type" "alu")
10487    (set_attr "mode" "DI")])
10488
10489 (define_expand "xorsi3"
10490   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10491         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10492                 (match_operand:SI 2 "general_operand" "")))]
10493   ""
10494   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10495
10496 (define_insn "*xorsi_1"
10497   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10498         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10499                 (match_operand:SI 2 "general_operand" "ri,rm")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "ix86_binary_operator_ok (XOR, SImode, operands)"
10502   "xor{l}\t{%2, %0|%0, %2}"
10503   [(set_attr "type" "alu")
10504    (set_attr "mode" "SI")])
10505
10506 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10507 ;; Add speccase for immediates
10508 (define_insn "*xorsi_1_zext"
10509   [(set (match_operand:DI 0 "register_operand" "=r")
10510         (zero_extend:DI
10511           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10512                   (match_operand:SI 2 "general_operand" "g"))))
10513    (clobber (reg:CC FLAGS_REG))]
10514   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10515   "xor{l}\t{%2, %k0|%k0, %2}"
10516   [(set_attr "type" "alu")
10517    (set_attr "mode" "SI")])
10518
10519 (define_insn "*xorsi_1_zext_imm"
10520   [(set (match_operand:DI 0 "register_operand" "=r")
10521         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10522                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10523    (clobber (reg:CC FLAGS_REG))]
10524   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10525   "xor{l}\t{%2, %k0|%k0, %2}"
10526   [(set_attr "type" "alu")
10527    (set_attr "mode" "SI")])
10528
10529 (define_insn "*xorsi_2"
10530   [(set (reg FLAGS_REG)
10531         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10532                          (match_operand:SI 2 "general_operand" "g,ri"))
10533                  (const_int 0)))
10534    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10535         (xor:SI (match_dup 1) (match_dup 2)))]
10536   "ix86_match_ccmode (insn, CCNOmode)
10537    && ix86_binary_operator_ok (XOR, SImode, operands)"
10538   "xor{l}\t{%2, %0|%0, %2}"
10539   [(set_attr "type" "alu")
10540    (set_attr "mode" "SI")])
10541
10542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10543 ;; ??? Special case for immediate operand is missing - it is tricky.
10544 (define_insn "*xorsi_2_zext"
10545   [(set (reg FLAGS_REG)
10546         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10547                          (match_operand:SI 2 "general_operand" "g"))
10548                  (const_int 0)))
10549    (set (match_operand:DI 0 "register_operand" "=r")
10550         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10551   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10552    && ix86_binary_operator_ok (XOR, SImode, operands)"
10553   "xor{l}\t{%2, %k0|%k0, %2}"
10554   [(set_attr "type" "alu")
10555    (set_attr "mode" "SI")])
10556
10557 (define_insn "*xorsi_2_zext_imm"
10558   [(set (reg FLAGS_REG)
10559         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10560                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10561                  (const_int 0)))
10562    (set (match_operand:DI 0 "register_operand" "=r")
10563         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10564   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10565    && ix86_binary_operator_ok (XOR, SImode, operands)"
10566   "xor{l}\t{%2, %k0|%k0, %2}"
10567   [(set_attr "type" "alu")
10568    (set_attr "mode" "SI")])
10569
10570 (define_insn "*xorsi_3"
10571   [(set (reg FLAGS_REG)
10572         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10573                          (match_operand:SI 2 "general_operand" "g"))
10574                  (const_int 0)))
10575    (clobber (match_scratch:SI 0 "=r"))]
10576   "ix86_match_ccmode (insn, CCNOmode)
10577    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10578   "xor{l}\t{%2, %0|%0, %2}"
10579   [(set_attr "type" "alu")
10580    (set_attr "mode" "SI")])
10581
10582 (define_expand "xorhi3"
10583   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10584         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10585                 (match_operand:HI 2 "general_operand" "")))]
10586   "TARGET_HIMODE_MATH"
10587   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10588
10589 (define_insn "*xorhi_1"
10590   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10591         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10592                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10593    (clobber (reg:CC FLAGS_REG))]
10594   "ix86_binary_operator_ok (XOR, HImode, operands)"
10595   "xor{w}\t{%2, %0|%0, %2}"
10596   [(set_attr "type" "alu")
10597    (set_attr "mode" "HI")])
10598
10599 (define_insn "*xorhi_2"
10600   [(set (reg FLAGS_REG)
10601         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10602                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10603                  (const_int 0)))
10604    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10605         (xor:HI (match_dup 1) (match_dup 2)))]
10606   "ix86_match_ccmode (insn, CCNOmode)
10607    && ix86_binary_operator_ok (XOR, HImode, operands)"
10608   "xor{w}\t{%2, %0|%0, %2}"
10609   [(set_attr "type" "alu")
10610    (set_attr "mode" "HI")])
10611
10612 (define_insn "*xorhi_3"
10613   [(set (reg FLAGS_REG)
10614         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10615                          (match_operand:HI 2 "general_operand" "rmn"))
10616                  (const_int 0)))
10617    (clobber (match_scratch:HI 0 "=r"))]
10618   "ix86_match_ccmode (insn, CCNOmode)
10619    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10620   "xor{w}\t{%2, %0|%0, %2}"
10621   [(set_attr "type" "alu")
10622    (set_attr "mode" "HI")])
10623
10624 (define_expand "xorqi3"
10625   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10626         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10627                 (match_operand:QI 2 "general_operand" "")))]
10628   "TARGET_QIMODE_MATH"
10629   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10630
10631 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10632 (define_insn "*xorqi_1"
10633   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10634         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10635                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "ix86_binary_operator_ok (XOR, QImode, operands)"
10638   "@
10639    xor{b}\t{%2, %0|%0, %2}
10640    xor{b}\t{%2, %0|%0, %2}
10641    xor{l}\t{%k2, %k0|%k0, %k2}"
10642   [(set_attr "type" "alu")
10643    (set_attr "mode" "QI,QI,SI")])
10644
10645 (define_insn "*xorqi_1_slp"
10646   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10647         (xor:QI (match_dup 0)
10648                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10649    (clobber (reg:CC FLAGS_REG))]
10650   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10651    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10652   "xor{b}\t{%1, %0|%0, %1}"
10653   [(set_attr "type" "alu1")
10654    (set_attr "mode" "QI")])
10655
10656 (define_insn "*xorqi_ext_0"
10657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10658                          (const_int 8)
10659                          (const_int 8))
10660         (xor:SI
10661           (zero_extract:SI
10662             (match_operand 1 "ext_register_operand" "0")
10663             (const_int 8)
10664             (const_int 8))
10665           (match_operand 2 "const_int_operand" "n")))
10666    (clobber (reg:CC FLAGS_REG))]
10667   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10668   "xor{b}\t{%2, %h0|%h0, %2}"
10669   [(set_attr "type" "alu")
10670    (set_attr "length_immediate" "1")
10671    (set_attr "modrm" "1")
10672    (set_attr "mode" "QI")])
10673
10674 (define_insn "*xorqi_ext_1"
10675   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10676                          (const_int 8)
10677                          (const_int 8))
10678         (xor:SI
10679           (zero_extract:SI
10680             (match_operand 1 "ext_register_operand" "0")
10681             (const_int 8)
10682             (const_int 8))
10683           (zero_extend:SI
10684             (match_operand:QI 2 "general_operand" "Qm"))))
10685    (clobber (reg:CC FLAGS_REG))]
10686   "!TARGET_64BIT
10687    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10688   "xor{b}\t{%2, %h0|%h0, %2}"
10689   [(set_attr "type" "alu")
10690    (set_attr "length_immediate" "0")
10691    (set_attr "mode" "QI")])
10692
10693 (define_insn "*xorqi_ext_1_rex64"
10694   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10695                          (const_int 8)
10696                          (const_int 8))
10697         (xor:SI
10698           (zero_extract:SI
10699             (match_operand 1 "ext_register_operand" "0")
10700             (const_int 8)
10701             (const_int 8))
10702           (zero_extend:SI
10703             (match_operand 2 "ext_register_operand" "Q"))))
10704    (clobber (reg:CC FLAGS_REG))]
10705   "TARGET_64BIT
10706    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10707   "xor{b}\t{%2, %h0|%h0, %2}"
10708   [(set_attr "type" "alu")
10709    (set_attr "length_immediate" "0")
10710    (set_attr "mode" "QI")])
10711
10712 (define_insn "*xorqi_ext_2"
10713   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10714                          (const_int 8)
10715                          (const_int 8))
10716         (xor:SI
10717           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10718                            (const_int 8)
10719                            (const_int 8))
10720           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10721                            (const_int 8)
10722                            (const_int 8))))
10723    (clobber (reg:CC FLAGS_REG))]
10724   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10725   "xor{b}\t{%h2, %h0|%h0, %h2}"
10726   [(set_attr "type" "alu")
10727    (set_attr "length_immediate" "0")
10728    (set_attr "mode" "QI")])
10729
10730 (define_insn "*xorqi_cc_1"
10731   [(set (reg FLAGS_REG)
10732         (compare
10733           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10734                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10735           (const_int 0)))
10736    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10737         (xor:QI (match_dup 1) (match_dup 2)))]
10738   "ix86_match_ccmode (insn, CCNOmode)
10739    && ix86_binary_operator_ok (XOR, QImode, operands)"
10740   "xor{b}\t{%2, %0|%0, %2}"
10741   [(set_attr "type" "alu")
10742    (set_attr "mode" "QI")])
10743
10744 (define_insn "*xorqi_2_slp"
10745   [(set (reg FLAGS_REG)
10746         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10747                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10748                  (const_int 0)))
10749    (set (strict_low_part (match_dup 0))
10750         (xor:QI (match_dup 0) (match_dup 1)))]
10751   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10752    && ix86_match_ccmode (insn, CCNOmode)
10753    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10754   "xor{b}\t{%1, %0|%0, %1}"
10755   [(set_attr "type" "alu1")
10756    (set_attr "mode" "QI")])
10757
10758 (define_insn "*xorqi_cc_2"
10759   [(set (reg FLAGS_REG)
10760         (compare
10761           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10762                   (match_operand:QI 2 "general_operand" "qmn"))
10763           (const_int 0)))
10764    (clobber (match_scratch:QI 0 "=q"))]
10765   "ix86_match_ccmode (insn, CCNOmode)
10766    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10767   "xor{b}\t{%2, %0|%0, %2}"
10768   [(set_attr "type" "alu")
10769    (set_attr "mode" "QI")])
10770
10771 (define_insn "*xorqi_cc_ext_1"
10772   [(set (reg FLAGS_REG)
10773         (compare
10774           (xor:SI
10775             (zero_extract:SI
10776               (match_operand 1 "ext_register_operand" "0")
10777               (const_int 8)
10778               (const_int 8))
10779             (match_operand:QI 2 "general_operand" "qmn"))
10780           (const_int 0)))
10781    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10782                          (const_int 8)
10783                          (const_int 8))
10784         (xor:SI
10785           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10786           (match_dup 2)))]
10787   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10788   "xor{b}\t{%2, %h0|%h0, %2}"
10789   [(set_attr "type" "alu")
10790    (set_attr "modrm" "1")
10791    (set_attr "mode" "QI")])
10792
10793 (define_insn "*xorqi_cc_ext_1_rex64"
10794   [(set (reg FLAGS_REG)
10795         (compare
10796           (xor:SI
10797             (zero_extract:SI
10798               (match_operand 1 "ext_register_operand" "0")
10799               (const_int 8)
10800               (const_int 8))
10801             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10802           (const_int 0)))
10803    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10804                          (const_int 8)
10805                          (const_int 8))
10806         (xor:SI
10807           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10808           (match_dup 2)))]
10809   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10810   "xor{b}\t{%2, %h0|%h0, %2}"
10811   [(set_attr "type" "alu")
10812    (set_attr "modrm" "1")
10813    (set_attr "mode" "QI")])
10814
10815 (define_expand "xorqi_cc_ext_1"
10816   [(parallel [
10817      (set (reg:CCNO FLAGS_REG)
10818           (compare:CCNO
10819             (xor:SI
10820               (zero_extract:SI
10821                 (match_operand 1 "ext_register_operand" "")
10822                 (const_int 8)
10823                 (const_int 8))
10824               (match_operand:QI 2 "general_operand" ""))
10825             (const_int 0)))
10826      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10827                            (const_int 8)
10828                            (const_int 8))
10829           (xor:SI
10830             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10831             (match_dup 2)))])]
10832   ""
10833   "")
10834
10835 (define_split
10836   [(set (match_operand 0 "register_operand" "")
10837         (xor (match_operand 1 "register_operand" "")
10838              (match_operand 2 "const_int_operand" "")))
10839    (clobber (reg:CC FLAGS_REG))]
10840    "reload_completed
10841     && QI_REG_P (operands[0])
10842     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10843     && !(INTVAL (operands[2]) & ~(255 << 8))
10844     && GET_MODE (operands[0]) != QImode"
10845   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10846                    (xor:SI (zero_extract:SI (match_dup 1)
10847                                             (const_int 8) (const_int 8))
10848                            (match_dup 2)))
10849               (clobber (reg:CC FLAGS_REG))])]
10850   "operands[0] = gen_lowpart (SImode, operands[0]);
10851    operands[1] = gen_lowpart (SImode, operands[1]);
10852    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10853
10854 ;; Since XOR can be encoded with sign extended immediate, this is only
10855 ;; profitable when 7th bit is set.
10856 (define_split
10857   [(set (match_operand 0 "register_operand" "")
10858         (xor (match_operand 1 "general_operand" "")
10859              (match_operand 2 "const_int_operand" "")))
10860    (clobber (reg:CC FLAGS_REG))]
10861    "reload_completed
10862     && ANY_QI_REG_P (operands[0])
10863     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10864     && !(INTVAL (operands[2]) & ~255)
10865     && (INTVAL (operands[2]) & 128)
10866     && GET_MODE (operands[0]) != QImode"
10867   [(parallel [(set (strict_low_part (match_dup 0))
10868                    (xor:QI (match_dup 1)
10869                            (match_dup 2)))
10870               (clobber (reg:CC FLAGS_REG))])]
10871   "operands[0] = gen_lowpart (QImode, operands[0]);
10872    operands[1] = gen_lowpart (QImode, operands[1]);
10873    operands[2] = gen_lowpart (QImode, operands[2]);")
10874 \f
10875 ;; Negation instructions
10876
10877 (define_expand "negti2"
10878   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10879         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10880   "TARGET_64BIT"
10881   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10882
10883 (define_insn "*negti2_1"
10884   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10885         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10886    (clobber (reg:CC FLAGS_REG))]
10887   "TARGET_64BIT
10888    && ix86_unary_operator_ok (NEG, TImode, operands)"
10889   "#")
10890
10891 (define_split
10892   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10893         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_64BIT && reload_completed"
10896   [(parallel
10897     [(set (reg:CCZ FLAGS_REG)
10898           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10899      (set (match_dup 0) (neg:DI (match_dup 1)))])
10900    (parallel
10901     [(set (match_dup 2)
10902           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10903                             (match_dup 3))
10904                    (const_int 0)))
10905      (clobber (reg:CC FLAGS_REG))])
10906    (parallel
10907     [(set (match_dup 2)
10908           (neg:DI (match_dup 2)))
10909      (clobber (reg:CC FLAGS_REG))])]
10910   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10911
10912 (define_expand "negdi2"
10913   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10914         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10915   ""
10916   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10917
10918 (define_insn "*negdi2_1"
10919   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10920         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10921    (clobber (reg:CC FLAGS_REG))]
10922   "!TARGET_64BIT
10923    && ix86_unary_operator_ok (NEG, DImode, operands)"
10924   "#")
10925
10926 (define_split
10927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10928         (neg:DI (match_operand:DI 1 "general_operand" "")))
10929    (clobber (reg:CC FLAGS_REG))]
10930   "!TARGET_64BIT && reload_completed"
10931   [(parallel
10932     [(set (reg:CCZ FLAGS_REG)
10933           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10934      (set (match_dup 0) (neg:SI (match_dup 1)))])
10935    (parallel
10936     [(set (match_dup 2)
10937           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10938                             (match_dup 3))
10939                    (const_int 0)))
10940      (clobber (reg:CC FLAGS_REG))])
10941    (parallel
10942     [(set (match_dup 2)
10943           (neg:SI (match_dup 2)))
10944      (clobber (reg:CC FLAGS_REG))])]
10945   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10946
10947 (define_insn "*negdi2_1_rex64"
10948   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10949         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10952   "neg{q}\t%0"
10953   [(set_attr "type" "negnot")
10954    (set_attr "mode" "DI")])
10955
10956 ;; The problem with neg is that it does not perform (compare x 0),
10957 ;; it really performs (compare 0 x), which leaves us with the zero
10958 ;; flag being the only useful item.
10959
10960 (define_insn "*negdi2_cmpz_rex64"
10961   [(set (reg:CCZ FLAGS_REG)
10962         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10963                      (const_int 0)))
10964    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10965         (neg:DI (match_dup 1)))]
10966   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10967   "neg{q}\t%0"
10968   [(set_attr "type" "negnot")
10969    (set_attr "mode" "DI")])
10970
10971
10972 (define_expand "negsi2"
10973   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10974         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10975   ""
10976   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10977
10978 (define_insn "*negsi2_1"
10979   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10980         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10981    (clobber (reg:CC FLAGS_REG))]
10982   "ix86_unary_operator_ok (NEG, SImode, operands)"
10983   "neg{l}\t%0"
10984   [(set_attr "type" "negnot")
10985    (set_attr "mode" "SI")])
10986
10987 ;; Combine is quite creative about this pattern.
10988 (define_insn "*negsi2_1_zext"
10989   [(set (match_operand:DI 0 "register_operand" "=r")
10990         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10991                                         (const_int 32)))
10992                      (const_int 32)))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10995   "neg{l}\t%k0"
10996   [(set_attr "type" "negnot")
10997    (set_attr "mode" "SI")])
10998
10999 ;; The problem with neg is that it does not perform (compare x 0),
11000 ;; it really performs (compare 0 x), which leaves us with the zero
11001 ;; flag being the only useful item.
11002
11003 (define_insn "*negsi2_cmpz"
11004   [(set (reg:CCZ FLAGS_REG)
11005         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11006                      (const_int 0)))
11007    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11008         (neg:SI (match_dup 1)))]
11009   "ix86_unary_operator_ok (NEG, SImode, operands)"
11010   "neg{l}\t%0"
11011   [(set_attr "type" "negnot")
11012    (set_attr "mode" "SI")])
11013
11014 (define_insn "*negsi2_cmpz_zext"
11015   [(set (reg:CCZ FLAGS_REG)
11016         (compare:CCZ (lshiftrt:DI
11017                        (neg:DI (ashift:DI
11018                                  (match_operand:DI 1 "register_operand" "0")
11019                                  (const_int 32)))
11020                        (const_int 32))
11021                      (const_int 0)))
11022    (set (match_operand:DI 0 "register_operand" "=r")
11023         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
11024                                         (const_int 32)))
11025                      (const_int 32)))]
11026   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
11027   "neg{l}\t%k0"
11028   [(set_attr "type" "negnot")
11029    (set_attr "mode" "SI")])
11030
11031 (define_expand "neghi2"
11032   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11033         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11034   "TARGET_HIMODE_MATH"
11035   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
11036
11037 (define_insn "*neghi2_1"
11038   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11039         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
11040    (clobber (reg:CC FLAGS_REG))]
11041   "ix86_unary_operator_ok (NEG, HImode, operands)"
11042   "neg{w}\t%0"
11043   [(set_attr "type" "negnot")
11044    (set_attr "mode" "HI")])
11045
11046 (define_insn "*neghi2_cmpz"
11047   [(set (reg:CCZ FLAGS_REG)
11048         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11049                      (const_int 0)))
11050    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11051         (neg:HI (match_dup 1)))]
11052   "ix86_unary_operator_ok (NEG, HImode, operands)"
11053   "neg{w}\t%0"
11054   [(set_attr "type" "negnot")
11055    (set_attr "mode" "HI")])
11056
11057 (define_expand "negqi2"
11058   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11059         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11060   "TARGET_QIMODE_MATH"
11061   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
11062
11063 (define_insn "*negqi2_1"
11064   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11065         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "ix86_unary_operator_ok (NEG, QImode, operands)"
11068   "neg{b}\t%0"
11069   [(set_attr "type" "negnot")
11070    (set_attr "mode" "QI")])
11071
11072 (define_insn "*negqi2_cmpz"
11073   [(set (reg:CCZ FLAGS_REG)
11074         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11075                      (const_int 0)))
11076    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11077         (neg:QI (match_dup 1)))]
11078   "ix86_unary_operator_ok (NEG, QImode, operands)"
11079   "neg{b}\t%0"
11080   [(set_attr "type" "negnot")
11081    (set_attr "mode" "QI")])
11082
11083 ;; Changing of sign for FP values is doable using integer unit too.
11084
11085 (define_expand "<code><mode>2"
11086   [(set (match_operand:X87MODEF 0 "register_operand" "")
11087         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
11088   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11089   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
11090
11091 (define_insn "*absneg<mode>2_mixed"
11092   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
11093         (match_operator:MODEF 3 "absneg_operator"
11094           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
11095    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
11098   "#")
11099
11100 (define_insn "*absneg<mode>2_sse"
11101   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
11102         (match_operator:MODEF 3 "absneg_operator"
11103           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
11104    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
11107   "#")
11108
11109 (define_insn "*absneg<mode>2_i387"
11110   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
11111         (match_operator:X87MODEF 3 "absneg_operator"
11112           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
11113    (use (match_operand 2 "" ""))
11114    (clobber (reg:CC FLAGS_REG))]
11115   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11116   "#")
11117
11118 (define_expand "<code>tf2"
11119   [(set (match_operand:TF 0 "register_operand" "")
11120         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
11121   "TARGET_SSE2"
11122   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
11123
11124 (define_insn "*absnegtf2_sse"
11125   [(set (match_operand:TF 0 "register_operand" "=x,x")
11126         (match_operator:TF 3 "absneg_operator"
11127           [(match_operand:TF 1 "register_operand" "0,x")]))
11128    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "TARGET_SSE2"
11131   "#")
11132
11133 ;; Splitters for fp abs and neg.
11134
11135 (define_split
11136   [(set (match_operand 0 "fp_register_operand" "")
11137         (match_operator 1 "absneg_operator" [(match_dup 0)]))
11138    (use (match_operand 2 "" ""))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "reload_completed"
11141   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
11142
11143 (define_split
11144   [(set (match_operand 0 "register_operand" "")
11145         (match_operator 3 "absneg_operator"
11146           [(match_operand 1 "register_operand" "")]))
11147    (use (match_operand 2 "nonimmediate_operand" ""))
11148    (clobber (reg:CC FLAGS_REG))]
11149   "reload_completed && SSE_REG_P (operands[0])"
11150   [(set (match_dup 0) (match_dup 3))]
11151 {
11152   enum machine_mode mode = GET_MODE (operands[0]);
11153   enum machine_mode vmode = GET_MODE (operands[2]);
11154   rtx tmp;
11155
11156   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
11157   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
11158   if (operands_match_p (operands[0], operands[2]))
11159     {
11160       tmp = operands[1];
11161       operands[1] = operands[2];
11162       operands[2] = tmp;
11163     }
11164   if (GET_CODE (operands[3]) == ABS)
11165     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
11166   else
11167     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
11168   operands[3] = tmp;
11169 })
11170
11171 (define_split
11172   [(set (match_operand:SF 0 "register_operand" "")
11173         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
11174    (use (match_operand:V4SF 2 "" ""))
11175    (clobber (reg:CC FLAGS_REG))]
11176   "reload_completed"
11177   [(parallel [(set (match_dup 0) (match_dup 1))
11178               (clobber (reg:CC FLAGS_REG))])]
11179 {
11180   rtx tmp;
11181   operands[0] = gen_lowpart (SImode, operands[0]);
11182   if (GET_CODE (operands[1]) == ABS)
11183     {
11184       tmp = gen_int_mode (0x7fffffff, SImode);
11185       tmp = gen_rtx_AND (SImode, operands[0], tmp);
11186     }
11187   else
11188     {
11189       tmp = gen_int_mode (0x80000000, SImode);
11190       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11191     }
11192   operands[1] = tmp;
11193 })
11194
11195 (define_split
11196   [(set (match_operand:DF 0 "register_operand" "")
11197         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
11198    (use (match_operand 2 "" ""))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "reload_completed"
11201   [(parallel [(set (match_dup 0) (match_dup 1))
11202               (clobber (reg:CC FLAGS_REG))])]
11203 {
11204   rtx tmp;
11205   if (TARGET_64BIT)
11206     {
11207       tmp = gen_lowpart (DImode, operands[0]);
11208       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
11209       operands[0] = tmp;
11210
11211       if (GET_CODE (operands[1]) == ABS)
11212         tmp = const0_rtx;
11213       else
11214         tmp = gen_rtx_NOT (DImode, tmp);
11215     }
11216   else
11217     {
11218       operands[0] = gen_highpart (SImode, operands[0]);
11219       if (GET_CODE (operands[1]) == ABS)
11220         {
11221           tmp = gen_int_mode (0x7fffffff, SImode);
11222           tmp = gen_rtx_AND (SImode, operands[0], tmp);
11223         }
11224       else
11225         {
11226           tmp = gen_int_mode (0x80000000, SImode);
11227           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11228         }
11229     }
11230   operands[1] = tmp;
11231 })
11232
11233 (define_split
11234   [(set (match_operand:XF 0 "register_operand" "")
11235         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
11236    (use (match_operand 2 "" ""))
11237    (clobber (reg:CC FLAGS_REG))]
11238   "reload_completed"
11239   [(parallel [(set (match_dup 0) (match_dup 1))
11240               (clobber (reg:CC FLAGS_REG))])]
11241 {
11242   rtx tmp;
11243   operands[0] = gen_rtx_REG (SImode,
11244                              true_regnum (operands[0])
11245                              + (TARGET_64BIT ? 1 : 2));
11246   if (GET_CODE (operands[1]) == ABS)
11247     {
11248       tmp = GEN_INT (0x7fff);
11249       tmp = gen_rtx_AND (SImode, operands[0], tmp);
11250     }
11251   else
11252     {
11253       tmp = GEN_INT (0x8000);
11254       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11255     }
11256   operands[1] = tmp;
11257 })
11258
11259 ;; Conditionalize these after reload. If they match before reload, we
11260 ;; lose the clobber and ability to use integer instructions.
11261
11262 (define_insn "*<code><mode>2_1"
11263   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
11264         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
11265   "TARGET_80387
11266    && (reload_completed
11267        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11268   "f<absnegprefix>"
11269   [(set_attr "type" "fsgn")
11270    (set_attr "mode" "<MODE>")])
11271
11272 (define_insn "*<code>extendsfdf2"
11273   [(set (match_operand:DF 0 "register_operand" "=f")
11274         (absneg:DF (float_extend:DF
11275                      (match_operand:SF 1 "register_operand" "0"))))]
11276   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
11277   "f<absnegprefix>"
11278   [(set_attr "type" "fsgn")
11279    (set_attr "mode" "DF")])
11280
11281 (define_insn "*<code>extendsfxf2"
11282   [(set (match_operand:XF 0 "register_operand" "=f")
11283         (absneg:XF (float_extend:XF
11284                      (match_operand:SF 1 "register_operand" "0"))))]
11285   "TARGET_80387"
11286   "f<absnegprefix>"
11287   [(set_attr "type" "fsgn")
11288    (set_attr "mode" "XF")])
11289
11290 (define_insn "*<code>extenddfxf2"
11291   [(set (match_operand:XF 0 "register_operand" "=f")
11292         (absneg:XF (float_extend:XF
11293                       (match_operand:DF 1 "register_operand" "0"))))]
11294   "TARGET_80387"
11295   "f<absnegprefix>"
11296   [(set_attr "type" "fsgn")
11297    (set_attr "mode" "XF")])
11298
11299 ;; Copysign instructions
11300
11301 (define_mode_iterator CSGNMODE [SF DF TF])
11302 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11303
11304 (define_expand "copysign<mode>3"
11305   [(match_operand:CSGNMODE 0 "register_operand" "")
11306    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11307    (match_operand:CSGNMODE 2 "register_operand" "")]
11308   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11309    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11310 {
11311   ix86_expand_copysign (operands);
11312   DONE;
11313 })
11314
11315 (define_insn_and_split "copysign<mode>3_const"
11316   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11317         (unspec:CSGNMODE
11318           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11319            (match_operand:CSGNMODE 2 "register_operand" "0")
11320            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11321           UNSPEC_COPYSIGN))]
11322   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11323    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11324   "#"
11325   "&& reload_completed"
11326   [(const_int 0)]
11327 {
11328   ix86_split_copysign_const (operands);
11329   DONE;
11330 })
11331
11332 (define_insn "copysign<mode>3_var"
11333   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11334         (unspec:CSGNMODE
11335           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11336            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11337            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11338            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11339           UNSPEC_COPYSIGN))
11340    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11341   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11342    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11343   "#")
11344
11345 (define_split
11346   [(set (match_operand:CSGNMODE 0 "register_operand" "")
11347         (unspec:CSGNMODE
11348           [(match_operand:CSGNMODE 2 "register_operand" "")
11349            (match_operand:CSGNMODE 3 "register_operand" "")
11350            (match_operand:<CSGNVMODE> 4 "" "")
11351            (match_operand:<CSGNVMODE> 5 "" "")]
11352           UNSPEC_COPYSIGN))
11353    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11354   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11355     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
11356    && reload_completed"
11357   [(const_int 0)]
11358 {
11359   ix86_split_copysign_var (operands);
11360   DONE;
11361 })
11362 \f
11363 ;; One complement instructions
11364
11365 (define_expand "one_cmpldi2"
11366   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11367         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11368   "TARGET_64BIT"
11369   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11370
11371 (define_insn "*one_cmpldi2_1_rex64"
11372   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11373         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11374   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
11375   "not{q}\t%0"
11376   [(set_attr "type" "negnot")
11377    (set_attr "mode" "DI")])
11378
11379 (define_insn "*one_cmpldi2_2_rex64"
11380   [(set (reg FLAGS_REG)
11381         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11382                  (const_int 0)))
11383    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384         (not:DI (match_dup 1)))]
11385   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11386    && ix86_unary_operator_ok (NOT, DImode, operands)"
11387   "#"
11388   [(set_attr "type" "alu1")
11389    (set_attr "mode" "DI")])
11390
11391 (define_split
11392   [(set (match_operand 0 "flags_reg_operand" "")
11393         (match_operator 2 "compare_operator"
11394           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11395            (const_int 0)]))
11396    (set (match_operand:DI 1 "nonimmediate_operand" "")
11397         (not:DI (match_dup 3)))]
11398   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
11399   [(parallel [(set (match_dup 0)
11400                    (match_op_dup 2
11401                      [(xor:DI (match_dup 3) (const_int -1))
11402                       (const_int 0)]))
11403               (set (match_dup 1)
11404                    (xor:DI (match_dup 3) (const_int -1)))])]
11405   "")
11406
11407 (define_expand "one_cmplsi2"
11408   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11409         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
11410   ""
11411   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11412
11413 (define_insn "*one_cmplsi2_1"
11414   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11415         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
11416   "ix86_unary_operator_ok (NOT, SImode, operands)"
11417   "not{l}\t%0"
11418   [(set_attr "type" "negnot")
11419    (set_attr "mode" "SI")])
11420
11421 ;; ??? Currently never generated - xor is used instead.
11422 (define_insn "*one_cmplsi2_1_zext"
11423   [(set (match_operand:DI 0 "register_operand" "=r")
11424         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11425   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11426   "not{l}\t%k0"
11427   [(set_attr "type" "negnot")
11428    (set_attr "mode" "SI")])
11429
11430 (define_insn "*one_cmplsi2_2"
11431   [(set (reg FLAGS_REG)
11432         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11433                  (const_int 0)))
11434    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11435         (not:SI (match_dup 1)))]
11436   "ix86_match_ccmode (insn, CCNOmode)
11437    && ix86_unary_operator_ok (NOT, SImode, operands)"
11438   "#"
11439   [(set_attr "type" "alu1")
11440    (set_attr "mode" "SI")])
11441
11442 (define_split
11443   [(set (match_operand 0 "flags_reg_operand" "")
11444         (match_operator 2 "compare_operator"
11445           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11446            (const_int 0)]))
11447    (set (match_operand:SI 1 "nonimmediate_operand" "")
11448         (not:SI (match_dup 3)))]
11449   "ix86_match_ccmode (insn, CCNOmode)"
11450   [(parallel [(set (match_dup 0)
11451                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11452                                     (const_int 0)]))
11453               (set (match_dup 1)
11454                    (xor:SI (match_dup 3) (const_int -1)))])]
11455   "")
11456
11457 ;; ??? Currently never generated - xor is used instead.
11458 (define_insn "*one_cmplsi2_2_zext"
11459   [(set (reg FLAGS_REG)
11460         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11461                  (const_int 0)))
11462    (set (match_operand:DI 0 "register_operand" "=r")
11463         (zero_extend:DI (not:SI (match_dup 1))))]
11464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11465    && ix86_unary_operator_ok (NOT, SImode, operands)"
11466   "#"
11467   [(set_attr "type" "alu1")
11468    (set_attr "mode" "SI")])
11469
11470 (define_split
11471   [(set (match_operand 0 "flags_reg_operand" "")
11472         (match_operator 2 "compare_operator"
11473           [(not:SI (match_operand:SI 3 "register_operand" ""))
11474            (const_int 0)]))
11475    (set (match_operand:DI 1 "register_operand" "")
11476         (zero_extend:DI (not:SI (match_dup 3))))]
11477   "ix86_match_ccmode (insn, CCNOmode)"
11478   [(parallel [(set (match_dup 0)
11479                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11480                                     (const_int 0)]))
11481               (set (match_dup 1)
11482                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11483   "")
11484
11485 (define_expand "one_cmplhi2"
11486   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11487         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11488   "TARGET_HIMODE_MATH"
11489   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11490
11491 (define_insn "*one_cmplhi2_1"
11492   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11493         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11494   "ix86_unary_operator_ok (NOT, HImode, operands)"
11495   "not{w}\t%0"
11496   [(set_attr "type" "negnot")
11497    (set_attr "mode" "HI")])
11498
11499 (define_insn "*one_cmplhi2_2"
11500   [(set (reg FLAGS_REG)
11501         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11502                  (const_int 0)))
11503    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11504         (not:HI (match_dup 1)))]
11505   "ix86_match_ccmode (insn, CCNOmode)
11506    && ix86_unary_operator_ok (NEG, HImode, operands)"
11507   "#"
11508   [(set_attr "type" "alu1")
11509    (set_attr "mode" "HI")])
11510
11511 (define_split
11512   [(set (match_operand 0 "flags_reg_operand" "")
11513         (match_operator 2 "compare_operator"
11514           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11515            (const_int 0)]))
11516    (set (match_operand:HI 1 "nonimmediate_operand" "")
11517         (not:HI (match_dup 3)))]
11518   "ix86_match_ccmode (insn, CCNOmode)"
11519   [(parallel [(set (match_dup 0)
11520                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11521                                     (const_int 0)]))
11522               (set (match_dup 1)
11523                    (xor:HI (match_dup 3) (const_int -1)))])]
11524   "")
11525
11526 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11527 (define_expand "one_cmplqi2"
11528   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11529         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11530   "TARGET_QIMODE_MATH"
11531   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11532
11533 (define_insn "*one_cmplqi2_1"
11534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11535         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11536   "ix86_unary_operator_ok (NOT, QImode, operands)"
11537   "@
11538    not{b}\t%0
11539    not{l}\t%k0"
11540   [(set_attr "type" "negnot")
11541    (set_attr "mode" "QI,SI")])
11542
11543 (define_insn "*one_cmplqi2_2"
11544   [(set (reg FLAGS_REG)
11545         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11546                  (const_int 0)))
11547    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11548         (not:QI (match_dup 1)))]
11549   "ix86_match_ccmode (insn, CCNOmode)
11550    && ix86_unary_operator_ok (NOT, QImode, operands)"
11551   "#"
11552   [(set_attr "type" "alu1")
11553    (set_attr "mode" "QI")])
11554
11555 (define_split
11556   [(set (match_operand 0 "flags_reg_operand" "")
11557         (match_operator 2 "compare_operator"
11558           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11559            (const_int 0)]))
11560    (set (match_operand:QI 1 "nonimmediate_operand" "")
11561         (not:QI (match_dup 3)))]
11562   "ix86_match_ccmode (insn, CCNOmode)"
11563   [(parallel [(set (match_dup 0)
11564                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11565                                     (const_int 0)]))
11566               (set (match_dup 1)
11567                    (xor:QI (match_dup 3) (const_int -1)))])]
11568   "")
11569 \f
11570 ;; Arithmetic shift instructions
11571
11572 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11573 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11574 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11575 ;; from the assembler input.
11576 ;;
11577 ;; This instruction shifts the target reg/mem as usual, but instead of
11578 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11579 ;; is a left shift double, bits are taken from the high order bits of
11580 ;; reg, else if the insn is a shift right double, bits are taken from the
11581 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11582 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11583 ;;
11584 ;; Since sh[lr]d does not change the `reg' operand, that is done
11585 ;; separately, making all shifts emit pairs of shift double and normal
11586 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11587 ;; support a 63 bit shift, each shift where the count is in a reg expands
11588 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11589 ;;
11590 ;; If the shift count is a constant, we need never emit more than one
11591 ;; shift pair, instead using moves and sign extension for counts greater
11592 ;; than 31.
11593
11594 (define_expand "ashlti3"
11595   [(set (match_operand:TI 0 "register_operand" "")
11596         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11597                    (match_operand:QI 2 "nonmemory_operand" "")))]
11598   "TARGET_64BIT"
11599   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11600
11601 ;; This pattern must be defined before *ashlti3_1 to prevent
11602 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11603
11604 (define_insn "*avx_ashlti3"
11605   [(set (match_operand:TI 0 "register_operand" "=x")
11606         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11607                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11608   "TARGET_AVX"
11609 {
11610   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11611   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11612 }
11613   [(set_attr "type" "sseishft")
11614    (set_attr "prefix" "vex")
11615    (set_attr "length_immediate" "1")
11616    (set_attr "mode" "TI")])
11617
11618 (define_insn "sse2_ashlti3"
11619   [(set (match_operand:TI 0 "register_operand" "=x")
11620         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11621                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11622   "TARGET_SSE2"
11623 {
11624   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11625   return "pslldq\t{%2, %0|%0, %2}";
11626 }
11627   [(set_attr "type" "sseishft")
11628    (set_attr "prefix_data16" "1")
11629    (set_attr "length_immediate" "1")
11630    (set_attr "mode" "TI")])
11631
11632 (define_insn "*ashlti3_1"
11633   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11634         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11635                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT"
11638   "#"
11639   [(set_attr "type" "multi")])
11640
11641 (define_peephole2
11642   [(match_scratch:DI 3 "r")
11643    (parallel [(set (match_operand:TI 0 "register_operand" "")
11644                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11645                               (match_operand:QI 2 "nonmemory_operand" "")))
11646               (clobber (reg:CC FLAGS_REG))])
11647    (match_dup 3)]
11648   "TARGET_64BIT"
11649   [(const_int 0)]
11650   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11651
11652 (define_split
11653   [(set (match_operand:TI 0 "register_operand" "")
11654         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11655                    (match_operand:QI 2 "nonmemory_operand" "")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11658                     ? epilogue_completed : reload_completed)"
11659   [(const_int 0)]
11660   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11661
11662 (define_insn "x86_64_shld"
11663   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11664         (ior:DI (ashift:DI (match_dup 0)
11665                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11666                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11667                   (minus:QI (const_int 64) (match_dup 2)))))
11668    (clobber (reg:CC FLAGS_REG))]
11669   "TARGET_64BIT"
11670   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11671   [(set_attr "type" "ishift")
11672    (set_attr "prefix_0f" "1")
11673    (set_attr "mode" "DI")
11674    (set_attr "athlon_decode" "vector")
11675    (set_attr "amdfam10_decode" "vector")])
11676
11677 (define_expand "x86_64_shift_adj_1"
11678   [(set (reg:CCZ FLAGS_REG)
11679         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11680                              (const_int 64))
11681                      (const_int 0)))
11682    (set (match_operand:DI 0 "register_operand" "")
11683         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11684                          (match_operand:DI 1 "register_operand" "")
11685                          (match_dup 0)))
11686    (set (match_dup 1)
11687         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11688                          (match_operand:DI 3 "register_operand" "r")
11689                          (match_dup 1)))]
11690   "TARGET_64BIT"
11691   "")
11692
11693 (define_expand "x86_64_shift_adj_2"
11694   [(use (match_operand:DI 0 "register_operand" ""))
11695    (use (match_operand:DI 1 "register_operand" ""))
11696    (use (match_operand:QI 2 "register_operand" ""))]
11697   "TARGET_64BIT"
11698 {
11699   rtx label = gen_label_rtx ();
11700   rtx tmp;
11701
11702   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11703
11704   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11705   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11706   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11707                               gen_rtx_LABEL_REF (VOIDmode, label),
11708                               pc_rtx);
11709   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11710   JUMP_LABEL (tmp) = label;
11711
11712   emit_move_insn (operands[0], operands[1]);
11713   ix86_expand_clear (operands[1]);
11714
11715   emit_label (label);
11716   LABEL_NUSES (label) = 1;
11717
11718   DONE;
11719 })
11720
11721 (define_expand "ashldi3"
11722   [(set (match_operand:DI 0 "shiftdi_operand" "")
11723         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11724                    (match_operand:QI 2 "nonmemory_operand" "")))]
11725   ""
11726   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11727
11728 (define_insn "*ashldi3_1_rex64"
11729   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11730         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11731                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11734 {
11735   switch (get_attr_type (insn))
11736     {
11737     case TYPE_ALU:
11738       gcc_assert (operands[2] == const1_rtx);
11739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11740       return "add{q}\t%0, %0";
11741
11742     case TYPE_LEA:
11743       gcc_assert (CONST_INT_P (operands[2]));
11744       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11745       operands[1] = gen_rtx_MULT (DImode, operands[1],
11746                                   GEN_INT (1 << INTVAL (operands[2])));
11747       return "lea{q}\t{%a1, %0|%0, %a1}";
11748
11749     default:
11750       if (REG_P (operands[2]))
11751         return "sal{q}\t{%b2, %0|%0, %b2}";
11752       else if (operands[2] == const1_rtx
11753                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11754         return "sal{q}\t%0";
11755       else
11756         return "sal{q}\t{%2, %0|%0, %2}";
11757     }
11758 }
11759   [(set (attr "type")
11760      (cond [(eq_attr "alternative" "1")
11761               (const_string "lea")
11762             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11763                           (const_int 0))
11764                       (match_operand 0 "register_operand" ""))
11765                  (match_operand 2 "const1_operand" ""))
11766               (const_string "alu")
11767            ]
11768            (const_string "ishift")))
11769    (set (attr "length_immediate")
11770      (if_then_else
11771        (ior (eq_attr "type" "alu")
11772             (and (eq_attr "type" "ishift")
11773                  (and (match_operand 2 "const1_operand" "")
11774                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11775                           (const_int 0)))))
11776        (const_string "0")
11777        (const_string "*")))
11778    (set_attr "mode" "DI")])
11779
11780 ;; Convert lea to the lea pattern to avoid flags dependency.
11781 (define_split
11782   [(set (match_operand:DI 0 "register_operand" "")
11783         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11784                    (match_operand:QI 2 "immediate_operand" "")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "TARGET_64BIT && reload_completed
11787    && true_regnum (operands[0]) != true_regnum (operands[1])"
11788   [(set (match_dup 0)
11789         (mult:DI (match_dup 1)
11790                  (match_dup 2)))]
11791   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11792
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashldi3_cmp_rex64"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11800                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11801           (const_int 0)))
11802    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11803         (ashift:DI (match_dup 1) (match_dup 2)))]
11804   "TARGET_64BIT
11805    && (optimize_function_for_size_p (cfun)
11806        || !TARGET_PARTIAL_FLAG_REG_STALL
11807        || (operands[2] == const1_rtx
11808            && (TARGET_SHIFT1
11809                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11810    && ix86_match_ccmode (insn, CCGOCmode)
11811    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11812 {
11813   switch (get_attr_type (insn))
11814     {
11815     case TYPE_ALU:
11816       gcc_assert (operands[2] == const1_rtx);
11817       return "add{q}\t%0, %0";
11818
11819     default:
11820       if (REG_P (operands[2]))
11821         return "sal{q}\t{%b2, %0|%0, %b2}";
11822       else if (operands[2] == const1_rtx
11823                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11824         return "sal{q}\t%0";
11825       else
11826         return "sal{q}\t{%2, %0|%0, %2}";
11827     }
11828 }
11829   [(set (attr "type")
11830      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11831                           (const_int 0))
11832                       (match_operand 0 "register_operand" ""))
11833                  (match_operand 2 "const1_operand" ""))
11834               (const_string "alu")
11835            ]
11836            (const_string "ishift")))
11837    (set (attr "length_immediate")
11838      (if_then_else
11839        (ior (eq_attr "type" "alu")
11840             (and (eq_attr "type" "ishift")
11841                  (and (match_operand 2 "const1_operand" "")
11842                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11843                           (const_int 0)))))
11844        (const_string "0")
11845        (const_string "*")))
11846    (set_attr "mode" "DI")])
11847
11848 (define_insn "*ashldi3_cconly_rex64"
11849   [(set (reg FLAGS_REG)
11850         (compare
11851           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11852                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11853           (const_int 0)))
11854    (clobber (match_scratch:DI 0 "=r"))]
11855   "TARGET_64BIT
11856    && (optimize_function_for_size_p (cfun)
11857        || !TARGET_PARTIAL_FLAG_REG_STALL
11858        || (operands[2] == const1_rtx
11859            && (TARGET_SHIFT1
11860                || TARGET_DOUBLE_WITH_ADD)))
11861    && ix86_match_ccmode (insn, CCGOCmode)
11862    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11863 {
11864   switch (get_attr_type (insn))
11865     {
11866     case TYPE_ALU:
11867       gcc_assert (operands[2] == const1_rtx);
11868       return "add{q}\t%0, %0";
11869
11870     default:
11871       if (REG_P (operands[2]))
11872         return "sal{q}\t{%b2, %0|%0, %b2}";
11873       else if (operands[2] == const1_rtx
11874                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11875         return "sal{q}\t%0";
11876       else
11877         return "sal{q}\t{%2, %0|%0, %2}";
11878     }
11879 }
11880   [(set (attr "type")
11881      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11882                           (const_int 0))
11883                       (match_operand 0 "register_operand" ""))
11884                  (match_operand 2 "const1_operand" ""))
11885               (const_string "alu")
11886            ]
11887            (const_string "ishift")))
11888    (set (attr "length_immediate")
11889      (if_then_else
11890        (ior (eq_attr "type" "alu")
11891             (and (eq_attr "type" "ishift")
11892                  (and (match_operand 2 "const1_operand" "")
11893                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11894                           (const_int 0)))))
11895        (const_string "0")
11896        (const_string "*")))
11897    (set_attr "mode" "DI")])
11898
11899 (define_insn "*ashldi3_1"
11900   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11901         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11902                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11903    (clobber (reg:CC FLAGS_REG))]
11904   "!TARGET_64BIT"
11905   "#"
11906   [(set_attr "type" "multi")])
11907
11908 ;; By default we don't ask for a scratch register, because when DImode
11909 ;; values are manipulated, registers are already at a premium.  But if
11910 ;; we have one handy, we won't turn it away.
11911 (define_peephole2
11912   [(match_scratch:SI 3 "r")
11913    (parallel [(set (match_operand:DI 0 "register_operand" "")
11914                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11915                               (match_operand:QI 2 "nonmemory_operand" "")))
11916               (clobber (reg:CC FLAGS_REG))])
11917    (match_dup 3)]
11918   "!TARGET_64BIT && TARGET_CMOVE"
11919   [(const_int 0)]
11920   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11921
11922 (define_split
11923   [(set (match_operand:DI 0 "register_operand" "")
11924         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11925                    (match_operand:QI 2 "nonmemory_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11928                      ? epilogue_completed : reload_completed)"
11929   [(const_int 0)]
11930   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11931
11932 (define_insn "x86_shld"
11933   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11934         (ior:SI (ashift:SI (match_dup 0)
11935                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11936                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11937                   (minus:QI (const_int 32) (match_dup 2)))))
11938    (clobber (reg:CC FLAGS_REG))]
11939   ""
11940   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11941   [(set_attr "type" "ishift")
11942    (set_attr "prefix_0f" "1")
11943    (set_attr "mode" "SI")
11944    (set_attr "pent_pair" "np")
11945    (set_attr "athlon_decode" "vector")
11946    (set_attr "amdfam10_decode" "vector")])
11947
11948 (define_expand "x86_shift_adj_1"
11949   [(set (reg:CCZ FLAGS_REG)
11950         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11951                              (const_int 32))
11952                      (const_int 0)))
11953    (set (match_operand:SI 0 "register_operand" "")
11954         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11955                          (match_operand:SI 1 "register_operand" "")
11956                          (match_dup 0)))
11957    (set (match_dup 1)
11958         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11959                          (match_operand:SI 3 "register_operand" "r")
11960                          (match_dup 1)))]
11961   "TARGET_CMOVE"
11962   "")
11963
11964 (define_expand "x86_shift_adj_2"
11965   [(use (match_operand:SI 0 "register_operand" ""))
11966    (use (match_operand:SI 1 "register_operand" ""))
11967    (use (match_operand:QI 2 "register_operand" ""))]
11968   ""
11969 {
11970   rtx label = gen_label_rtx ();
11971   rtx tmp;
11972
11973   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11974
11975   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11976   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11977   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11978                               gen_rtx_LABEL_REF (VOIDmode, label),
11979                               pc_rtx);
11980   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11981   JUMP_LABEL (tmp) = label;
11982
11983   emit_move_insn (operands[0], operands[1]);
11984   ix86_expand_clear (operands[1]);
11985
11986   emit_label (label);
11987   LABEL_NUSES (label) = 1;
11988
11989   DONE;
11990 })
11991
11992 (define_expand "ashlsi3"
11993   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11994         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11995                    (match_operand:QI 2 "nonmemory_operand" "")))]
11996   ""
11997   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11998
11999 (define_insn "*ashlsi3_1"
12000   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
12001         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
12002                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12005 {
12006   switch (get_attr_type (insn))
12007     {
12008     case TYPE_ALU:
12009       gcc_assert (operands[2] == const1_rtx);
12010       gcc_assert (rtx_equal_p (operands[0], operands[1]));
12011       return "add{l}\t%0, %0";
12012
12013     case TYPE_LEA:
12014       return "#";
12015
12016     default:
12017       if (REG_P (operands[2]))
12018         return "sal{l}\t{%b2, %0|%0, %b2}";
12019       else if (operands[2] == const1_rtx
12020                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12021         return "sal{l}\t%0";
12022       else
12023         return "sal{l}\t{%2, %0|%0, %2}";
12024     }
12025 }
12026   [(set (attr "type")
12027      (cond [(eq_attr "alternative" "1")
12028               (const_string "lea")
12029             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12030                           (const_int 0))
12031                       (match_operand 0 "register_operand" ""))
12032                  (match_operand 2 "const1_operand" ""))
12033               (const_string "alu")
12034            ]
12035            (const_string "ishift")))
12036    (set (attr "length_immediate")
12037      (if_then_else
12038        (ior (eq_attr "type" "alu")
12039             (and (eq_attr "type" "ishift")
12040                  (and (match_operand 2 "const1_operand" "")
12041                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12042                           (const_int 0)))))
12043        (const_string "0")
12044        (const_string "*")))
12045    (set_attr "mode" "SI")])
12046
12047 ;; Convert lea to the lea pattern to avoid flags dependency.
12048 (define_split
12049   [(set (match_operand 0 "register_operand" "")
12050         (ashift (match_operand 1 "index_register_operand" "")
12051                 (match_operand:QI 2 "const_int_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053   "reload_completed
12054    && true_regnum (operands[0]) != true_regnum (operands[1])
12055    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
12056   [(const_int 0)]
12057 {
12058   rtx pat;
12059   enum machine_mode mode = GET_MODE (operands[0]);
12060
12061   if (GET_MODE_SIZE (mode) < 4)
12062     operands[0] = gen_lowpart (SImode, operands[0]);
12063   if (mode != Pmode)
12064     operands[1] = gen_lowpart (Pmode, operands[1]);
12065   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12066
12067   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
12068   if (Pmode != SImode)
12069     pat = gen_rtx_SUBREG (SImode, pat, 0);
12070   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
12071   DONE;
12072 })
12073
12074 ;; Rare case of shifting RSP is handled by generating move and shift
12075 (define_split
12076   [(set (match_operand 0 "register_operand" "")
12077         (ashift (match_operand 1 "register_operand" "")
12078                 (match_operand:QI 2 "const_int_operand" "")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "reload_completed
12081    && true_regnum (operands[0]) != true_regnum (operands[1])"
12082   [(const_int 0)]
12083 {
12084   rtx pat, clob;
12085   emit_move_insn (operands[0], operands[1]);
12086   pat = gen_rtx_SET (VOIDmode, operands[0],
12087                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
12088                                      operands[0], operands[2]));
12089   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
12090   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
12091   DONE;
12092 })
12093
12094 (define_insn "*ashlsi3_1_zext"
12095   [(set (match_operand:DI 0 "register_operand" "=r,r")
12096         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
12097                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12100 {
12101   switch (get_attr_type (insn))
12102     {
12103     case TYPE_ALU:
12104       gcc_assert (operands[2] == const1_rtx);
12105       return "add{l}\t%k0, %k0";
12106
12107     case TYPE_LEA:
12108       return "#";
12109
12110     default:
12111       if (REG_P (operands[2]))
12112         return "sal{l}\t{%b2, %k0|%k0, %b2}";
12113       else if (operands[2] == const1_rtx
12114                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12115         return "sal{l}\t%k0";
12116       else
12117         return "sal{l}\t{%2, %k0|%k0, %2}";
12118     }
12119 }
12120   [(set (attr "type")
12121      (cond [(eq_attr "alternative" "1")
12122               (const_string "lea")
12123             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12124                      (const_int 0))
12125                  (match_operand 2 "const1_operand" ""))
12126               (const_string "alu")
12127            ]
12128            (const_string "ishift")))
12129    (set (attr "length_immediate")
12130      (if_then_else
12131        (ior (eq_attr "type" "alu")
12132             (and (eq_attr "type" "ishift")
12133                  (and (match_operand 2 "const1_operand" "")
12134                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12135                           (const_int 0)))))
12136        (const_string "0")
12137        (const_string "*")))
12138    (set_attr "mode" "SI")])
12139
12140 ;; Convert lea to the lea pattern to avoid flags dependency.
12141 (define_split
12142   [(set (match_operand:DI 0 "register_operand" "")
12143         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
12144                                 (match_operand:QI 2 "const_int_operand" ""))))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "TARGET_64BIT && reload_completed
12147    && true_regnum (operands[0]) != true_regnum (operands[1])"
12148   [(set (match_dup 0) (zero_extend:DI
12149                         (subreg:SI (mult:SI (match_dup 1)
12150                                             (match_dup 2)) 0)))]
12151 {
12152   operands[1] = gen_lowpart (Pmode, operands[1]);
12153   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12154 })
12155
12156 ;; This pattern can't accept a variable shift count, since shifts by
12157 ;; zero don't affect the flags.  We assume that shifts by constant
12158 ;; zero are optimized away.
12159 (define_insn "*ashlsi3_cmp"
12160   [(set (reg FLAGS_REG)
12161         (compare
12162           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12164           (const_int 0)))
12165    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12166         (ashift:SI (match_dup 1) (match_dup 2)))]
12167    "(optimize_function_for_size_p (cfun)
12168      || !TARGET_PARTIAL_FLAG_REG_STALL
12169      || (operands[2] == const1_rtx
12170          && (TARGET_SHIFT1
12171              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12172    && ix86_match_ccmode (insn, CCGOCmode)
12173    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12174 {
12175   switch (get_attr_type (insn))
12176     {
12177     case TYPE_ALU:
12178       gcc_assert (operands[2] == const1_rtx);
12179       return "add{l}\t%0, %0";
12180
12181     default:
12182       if (REG_P (operands[2]))
12183         return "sal{l}\t{%b2, %0|%0, %b2}";
12184       else if (operands[2] == const1_rtx
12185                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12186         return "sal{l}\t%0";
12187       else
12188         return "sal{l}\t{%2, %0|%0, %2}";
12189     }
12190 }
12191   [(set (attr "type")
12192      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12193                           (const_int 0))
12194                       (match_operand 0 "register_operand" ""))
12195                  (match_operand 2 "const1_operand" ""))
12196               (const_string "alu")
12197            ]
12198            (const_string "ishift")))
12199    (set (attr "length_immediate")
12200      (if_then_else
12201        (ior (eq_attr "type" "alu")
12202             (and (eq_attr "type" "ishift")
12203                  (and (match_operand 2 "const1_operand" "")
12204                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12205                           (const_int 0)))))
12206        (const_string "0")
12207        (const_string "*")))
12208    (set_attr "mode" "SI")])
12209
12210 (define_insn "*ashlsi3_cconly"
12211   [(set (reg FLAGS_REG)
12212         (compare
12213           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12214                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12215           (const_int 0)))
12216    (clobber (match_scratch:SI 0 "=r"))]
12217   "(optimize_function_for_size_p (cfun)
12218     || !TARGET_PARTIAL_FLAG_REG_STALL
12219     || (operands[2] == const1_rtx
12220         && (TARGET_SHIFT1
12221             || TARGET_DOUBLE_WITH_ADD)))
12222    && ix86_match_ccmode (insn, CCGOCmode)
12223    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12224 {
12225   switch (get_attr_type (insn))
12226     {
12227     case TYPE_ALU:
12228       gcc_assert (operands[2] == const1_rtx);
12229       return "add{l}\t%0, %0";
12230
12231     default:
12232       if (REG_P (operands[2]))
12233         return "sal{l}\t{%b2, %0|%0, %b2}";
12234       else if (operands[2] == const1_rtx
12235                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12236         return "sal{l}\t%0";
12237       else
12238         return "sal{l}\t{%2, %0|%0, %2}";
12239     }
12240 }
12241   [(set (attr "type")
12242      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12243                           (const_int 0))
12244                       (match_operand 0 "register_operand" ""))
12245                  (match_operand 2 "const1_operand" ""))
12246               (const_string "alu")
12247            ]
12248            (const_string "ishift")))
12249    (set (attr "length_immediate")
12250      (if_then_else
12251        (ior (eq_attr "type" "alu")
12252             (and (eq_attr "type" "ishift")
12253                  (and (match_operand 2 "const1_operand" "")
12254                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12255                           (const_int 0)))))
12256        (const_string "0")
12257        (const_string "*")))
12258    (set_attr "mode" "SI")])
12259
12260 (define_insn "*ashlsi3_cmp_zext"
12261   [(set (reg FLAGS_REG)
12262         (compare
12263           (ashift:SI (match_operand:SI 1 "register_operand" "0")
12264                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12265           (const_int 0)))
12266    (set (match_operand:DI 0 "register_operand" "=r")
12267         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
12268   "TARGET_64BIT
12269    && (optimize_function_for_size_p (cfun)
12270        || !TARGET_PARTIAL_FLAG_REG_STALL
12271        || (operands[2] == const1_rtx
12272            && (TARGET_SHIFT1
12273                || TARGET_DOUBLE_WITH_ADD)))
12274    && ix86_match_ccmode (insn, CCGOCmode)
12275    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12276 {
12277   switch (get_attr_type (insn))
12278     {
12279     case TYPE_ALU:
12280       gcc_assert (operands[2] == const1_rtx);
12281       return "add{l}\t%k0, %k0";
12282
12283     default:
12284       if (REG_P (operands[2]))
12285         return "sal{l}\t{%b2, %k0|%k0, %b2}";
12286       else if (operands[2] == const1_rtx
12287                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12288         return "sal{l}\t%k0";
12289       else
12290         return "sal{l}\t{%2, %k0|%k0, %2}";
12291     }
12292 }
12293   [(set (attr "type")
12294      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12295                      (const_int 0))
12296                  (match_operand 2 "const1_operand" ""))
12297               (const_string "alu")
12298            ]
12299            (const_string "ishift")))
12300    (set (attr "length_immediate")
12301      (if_then_else
12302        (ior (eq_attr "type" "alu")
12303             (and (eq_attr "type" "ishift")
12304                  (and (match_operand 2 "const1_operand" "")
12305                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12306                           (const_int 0)))))
12307        (const_string "0")
12308        (const_string "*")))
12309    (set_attr "mode" "SI")])
12310
12311 (define_expand "ashlhi3"
12312   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12313         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
12314                    (match_operand:QI 2 "nonmemory_operand" "")))]
12315   "TARGET_HIMODE_MATH"
12316   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
12317
12318 (define_insn "*ashlhi3_1_lea"
12319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
12320         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
12321                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "!TARGET_PARTIAL_REG_STALL
12324    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12325 {
12326   switch (get_attr_type (insn))
12327     {
12328     case TYPE_LEA:
12329       return "#";
12330     case TYPE_ALU:
12331       gcc_assert (operands[2] == const1_rtx);
12332       return "add{w}\t%0, %0";
12333
12334     default:
12335       if (REG_P (operands[2]))
12336         return "sal{w}\t{%b2, %0|%0, %b2}";
12337       else if (operands[2] == const1_rtx
12338                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12339         return "sal{w}\t%0";
12340       else
12341         return "sal{w}\t{%2, %0|%0, %2}";
12342     }
12343 }
12344   [(set (attr "type")
12345      (cond [(eq_attr "alternative" "1")
12346               (const_string "lea")
12347             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12348                           (const_int 0))
12349                       (match_operand 0 "register_operand" ""))
12350                  (match_operand 2 "const1_operand" ""))
12351               (const_string "alu")
12352            ]
12353            (const_string "ishift")))
12354    (set (attr "length_immediate")
12355      (if_then_else
12356        (ior (eq_attr "type" "alu")
12357             (and (eq_attr "type" "ishift")
12358                  (and (match_operand 2 "const1_operand" "")
12359                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12360                           (const_int 0)))))
12361        (const_string "0")
12362        (const_string "*")))
12363    (set_attr "mode" "HI,SI")])
12364
12365 (define_insn "*ashlhi3_1"
12366   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                    (match_operand:QI 2 "nonmemory_operand" "cI")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_PARTIAL_REG_STALL
12371    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12372 {
12373   switch (get_attr_type (insn))
12374     {
12375     case TYPE_ALU:
12376       gcc_assert (operands[2] == const1_rtx);
12377       return "add{w}\t%0, %0";
12378
12379     default:
12380       if (REG_P (operands[2]))
12381         return "sal{w}\t{%b2, %0|%0, %b2}";
12382       else if (operands[2] == const1_rtx
12383                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12384         return "sal{w}\t%0";
12385       else
12386         return "sal{w}\t{%2, %0|%0, %2}";
12387     }
12388 }
12389   [(set (attr "type")
12390      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12391                           (const_int 0))
12392                       (match_operand 0 "register_operand" ""))
12393                  (match_operand 2 "const1_operand" ""))
12394               (const_string "alu")
12395            ]
12396            (const_string "ishift")))
12397    (set (attr "length_immediate")
12398      (if_then_else
12399        (ior (eq_attr "type" "alu")
12400             (and (eq_attr "type" "ishift")
12401                  (and (match_operand 2 "const1_operand" "")
12402                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12403                           (const_int 0)))))
12404        (const_string "0")
12405        (const_string "*")))
12406    (set_attr "mode" "HI")])
12407
12408 ;; This pattern can't accept a variable shift count, since shifts by
12409 ;; zero don't affect the flags.  We assume that shifts by constant
12410 ;; zero are optimized away.
12411 (define_insn "*ashlhi3_cmp"
12412   [(set (reg FLAGS_REG)
12413         (compare
12414           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12416           (const_int 0)))
12417    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12418         (ashift:HI (match_dup 1) (match_dup 2)))]
12419   "(optimize_function_for_size_p (cfun)
12420     || !TARGET_PARTIAL_FLAG_REG_STALL
12421     || (operands[2] == const1_rtx
12422         && (TARGET_SHIFT1
12423             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12424    && ix86_match_ccmode (insn, CCGOCmode)
12425    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12426 {
12427   switch (get_attr_type (insn))
12428     {
12429     case TYPE_ALU:
12430       gcc_assert (operands[2] == const1_rtx);
12431       return "add{w}\t%0, %0";
12432
12433     default:
12434       if (REG_P (operands[2]))
12435         return "sal{w}\t{%b2, %0|%0, %b2}";
12436       else if (operands[2] == const1_rtx
12437                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12438         return "sal{w}\t%0";
12439       else
12440         return "sal{w}\t{%2, %0|%0, %2}";
12441     }
12442 }
12443   [(set (attr "type")
12444      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12445                           (const_int 0))
12446                       (match_operand 0 "register_operand" ""))
12447                  (match_operand 2 "const1_operand" ""))
12448               (const_string "alu")
12449            ]
12450            (const_string "ishift")))
12451    (set (attr "length_immediate")
12452      (if_then_else
12453        (ior (eq_attr "type" "alu")
12454             (and (eq_attr "type" "ishift")
12455                  (and (match_operand 2 "const1_operand" "")
12456                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12457                           (const_int 0)))))
12458        (const_string "0")
12459        (const_string "*")))
12460    (set_attr "mode" "HI")])
12461
12462 (define_insn "*ashlhi3_cconly"
12463   [(set (reg FLAGS_REG)
12464         (compare
12465           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12466                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12467           (const_int 0)))
12468    (clobber (match_scratch:HI 0 "=r"))]
12469   "(optimize_function_for_size_p (cfun)
12470     || !TARGET_PARTIAL_FLAG_REG_STALL
12471     || (operands[2] == const1_rtx
12472         && (TARGET_SHIFT1
12473             || TARGET_DOUBLE_WITH_ADD)))
12474    && ix86_match_ccmode (insn, CCGOCmode)
12475    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12476 {
12477   switch (get_attr_type (insn))
12478     {
12479     case TYPE_ALU:
12480       gcc_assert (operands[2] == const1_rtx);
12481       return "add{w}\t%0, %0";
12482
12483     default:
12484       if (REG_P (operands[2]))
12485         return "sal{w}\t{%b2, %0|%0, %b2}";
12486       else if (operands[2] == const1_rtx
12487                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12488         return "sal{w}\t%0";
12489       else
12490         return "sal{w}\t{%2, %0|%0, %2}";
12491     }
12492 }
12493   [(set (attr "type")
12494      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12495                           (const_int 0))
12496                       (match_operand 0 "register_operand" ""))
12497                  (match_operand 2 "const1_operand" ""))
12498               (const_string "alu")
12499            ]
12500            (const_string "ishift")))
12501    (set (attr "length_immediate")
12502      (if_then_else
12503        (ior (eq_attr "type" "alu")
12504             (and (eq_attr "type" "ishift")
12505                  (and (match_operand 2 "const1_operand" "")
12506                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12507                           (const_int 0)))))
12508        (const_string "0")
12509        (const_string "*")))
12510    (set_attr "mode" "HI")])
12511
12512 (define_expand "ashlqi3"
12513   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12514         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
12515                    (match_operand:QI 2 "nonmemory_operand" "")))]
12516   "TARGET_QIMODE_MATH"
12517   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12518
12519 ;; %%% Potential partial reg stall on alternative 2.  What to do?
12520
12521 (define_insn "*ashlqi3_1_lea"
12522   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
12523         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
12524                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "!TARGET_PARTIAL_REG_STALL
12527    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12528 {
12529   switch (get_attr_type (insn))
12530     {
12531     case TYPE_LEA:
12532       return "#";
12533     case TYPE_ALU:
12534       gcc_assert (operands[2] == const1_rtx);
12535       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12536         return "add{l}\t%k0, %k0";
12537       else
12538         return "add{b}\t%0, %0";
12539
12540     default:
12541       if (REG_P (operands[2]))
12542         {
12543           if (get_attr_mode (insn) == MODE_SI)
12544             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12545           else
12546             return "sal{b}\t{%b2, %0|%0, %b2}";
12547         }
12548       else if (operands[2] == const1_rtx
12549                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12550         {
12551           if (get_attr_mode (insn) == MODE_SI)
12552             return "sal{l}\t%0";
12553           else
12554             return "sal{b}\t%0";
12555         }
12556       else
12557         {
12558           if (get_attr_mode (insn) == MODE_SI)
12559             return "sal{l}\t{%2, %k0|%k0, %2}";
12560           else
12561             return "sal{b}\t{%2, %0|%0, %2}";
12562         }
12563     }
12564 }
12565   [(set (attr "type")
12566      (cond [(eq_attr "alternative" "2")
12567               (const_string "lea")
12568             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12569                           (const_int 0))
12570                       (match_operand 0 "register_operand" ""))
12571                  (match_operand 2 "const1_operand" ""))
12572               (const_string "alu")
12573            ]
12574            (const_string "ishift")))
12575    (set (attr "length_immediate")
12576      (if_then_else
12577        (ior (eq_attr "type" "alu")
12578             (and (eq_attr "type" "ishift")
12579                  (and (match_operand 2 "const1_operand" "")
12580                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12581                           (const_int 0)))))
12582        (const_string "0")
12583        (const_string "*")))
12584    (set_attr "mode" "QI,SI,SI")])
12585
12586 (define_insn "*ashlqi3_1"
12587   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12588         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12589                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12590    (clobber (reg:CC FLAGS_REG))]
12591   "TARGET_PARTIAL_REG_STALL
12592    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12593 {
12594   switch (get_attr_type (insn))
12595     {
12596     case TYPE_ALU:
12597       gcc_assert (operands[2] == const1_rtx);
12598       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12599         return "add{l}\t%k0, %k0";
12600       else
12601         return "add{b}\t%0, %0";
12602
12603     default:
12604       if (REG_P (operands[2]))
12605         {
12606           if (get_attr_mode (insn) == MODE_SI)
12607             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12608           else
12609             return "sal{b}\t{%b2, %0|%0, %b2}";
12610         }
12611       else if (operands[2] == const1_rtx
12612                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12613         {
12614           if (get_attr_mode (insn) == MODE_SI)
12615             return "sal{l}\t%0";
12616           else
12617             return "sal{b}\t%0";
12618         }
12619       else
12620         {
12621           if (get_attr_mode (insn) == MODE_SI)
12622             return "sal{l}\t{%2, %k0|%k0, %2}";
12623           else
12624             return "sal{b}\t{%2, %0|%0, %2}";
12625         }
12626     }
12627 }
12628   [(set (attr "type")
12629      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12630                           (const_int 0))
12631                       (match_operand 0 "register_operand" ""))
12632                  (match_operand 2 "const1_operand" ""))
12633               (const_string "alu")
12634            ]
12635            (const_string "ishift")))
12636    (set (attr "length_immediate")
12637      (if_then_else
12638        (ior (eq_attr "type" "alu")
12639             (and (eq_attr "type" "ishift")
12640                  (and (match_operand 2 "const1_operand" "")
12641                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12642                           (const_int 0)))))
12643        (const_string "0")
12644        (const_string "*")))
12645    (set_attr "mode" "QI,SI")])
12646
12647 ;; This pattern can't accept a variable shift count, since shifts by
12648 ;; zero don't affect the flags.  We assume that shifts by constant
12649 ;; zero are optimized away.
12650 (define_insn "*ashlqi3_cmp"
12651   [(set (reg FLAGS_REG)
12652         (compare
12653           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12654                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12655           (const_int 0)))
12656    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12657         (ashift:QI (match_dup 1) (match_dup 2)))]
12658   "(optimize_function_for_size_p (cfun)
12659     || !TARGET_PARTIAL_FLAG_REG_STALL
12660     || (operands[2] == const1_rtx
12661         && (TARGET_SHIFT1
12662             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12663    && ix86_match_ccmode (insn, CCGOCmode)
12664    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12665 {
12666   switch (get_attr_type (insn))
12667     {
12668     case TYPE_ALU:
12669       gcc_assert (operands[2] == const1_rtx);
12670       return "add{b}\t%0, %0";
12671
12672     default:
12673       if (REG_P (operands[2]))
12674         return "sal{b}\t{%b2, %0|%0, %b2}";
12675       else if (operands[2] == const1_rtx
12676                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12677         return "sal{b}\t%0";
12678       else
12679         return "sal{b}\t{%2, %0|%0, %2}";
12680     }
12681 }
12682   [(set (attr "type")
12683      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12684                           (const_int 0))
12685                       (match_operand 0 "register_operand" ""))
12686                  (match_operand 2 "const1_operand" ""))
12687               (const_string "alu")
12688            ]
12689            (const_string "ishift")))
12690    (set (attr "length_immediate")
12691      (if_then_else
12692        (ior (eq_attr "type" "alu")
12693             (and (eq_attr "type" "ishift")
12694                  (and (match_operand 2 "const1_operand" "")
12695                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12696                           (const_int 0)))))
12697        (const_string "0")
12698        (const_string "*")))
12699    (set_attr "mode" "QI")])
12700
12701 (define_insn "*ashlqi3_cconly"
12702   [(set (reg FLAGS_REG)
12703         (compare
12704           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12705                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12706           (const_int 0)))
12707    (clobber (match_scratch:QI 0 "=q"))]
12708   "(optimize_function_for_size_p (cfun)
12709     || !TARGET_PARTIAL_FLAG_REG_STALL
12710     || (operands[2] == const1_rtx
12711         && (TARGET_SHIFT1
12712             || TARGET_DOUBLE_WITH_ADD)))
12713    && ix86_match_ccmode (insn, CCGOCmode)
12714    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12715 {
12716   switch (get_attr_type (insn))
12717     {
12718     case TYPE_ALU:
12719       gcc_assert (operands[2] == const1_rtx);
12720       return "add{b}\t%0, %0";
12721
12722     default:
12723       if (REG_P (operands[2]))
12724         return "sal{b}\t{%b2, %0|%0, %b2}";
12725       else if (operands[2] == const1_rtx
12726                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12727         return "sal{b}\t%0";
12728       else
12729         return "sal{b}\t{%2, %0|%0, %2}";
12730     }
12731 }
12732   [(set (attr "type")
12733      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12734                           (const_int 0))
12735                       (match_operand 0 "register_operand" ""))
12736                  (match_operand 2 "const1_operand" ""))
12737               (const_string "alu")
12738            ]
12739            (const_string "ishift")))
12740    (set (attr "length_immediate")
12741      (if_then_else
12742        (ior (eq_attr "type" "alu")
12743             (and (eq_attr "type" "ishift")
12744                  (and (match_operand 2 "const1_operand" "")
12745                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12746                           (const_int 0)))))
12747        (const_string "0")
12748        (const_string "*")))
12749    (set_attr "mode" "QI")])
12750
12751 ;; See comment above `ashldi3' about how this works.
12752
12753 (define_expand "ashrti3"
12754   [(set (match_operand:TI 0 "register_operand" "")
12755         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12756                      (match_operand:QI 2 "nonmemory_operand" "")))]
12757   "TARGET_64BIT"
12758   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12759
12760 (define_insn "*ashrti3_1"
12761   [(set (match_operand:TI 0 "register_operand" "=r")
12762         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12763                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12764    (clobber (reg:CC FLAGS_REG))]
12765   "TARGET_64BIT"
12766   "#"
12767   [(set_attr "type" "multi")])
12768
12769 (define_peephole2
12770   [(match_scratch:DI 3 "r")
12771    (parallel [(set (match_operand:TI 0 "register_operand" "")
12772                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12773                                 (match_operand:QI 2 "nonmemory_operand" "")))
12774               (clobber (reg:CC FLAGS_REG))])
12775    (match_dup 3)]
12776   "TARGET_64BIT"
12777   [(const_int 0)]
12778   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12779
12780 (define_split
12781   [(set (match_operand:TI 0 "register_operand" "")
12782         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12783                      (match_operand:QI 2 "nonmemory_operand" "")))
12784    (clobber (reg:CC FLAGS_REG))]
12785   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12786                     ? epilogue_completed : reload_completed)"
12787   [(const_int 0)]
12788   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12789
12790 (define_insn "x86_64_shrd"
12791   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12792         (ior:DI (ashiftrt:DI (match_dup 0)
12793                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12794                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12795                   (minus:QI (const_int 64) (match_dup 2)))))
12796    (clobber (reg:CC FLAGS_REG))]
12797   "TARGET_64BIT"
12798   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12799   [(set_attr "type" "ishift")
12800    (set_attr "prefix_0f" "1")
12801    (set_attr "mode" "DI")
12802    (set_attr "athlon_decode" "vector")
12803    (set_attr "amdfam10_decode" "vector")])
12804
12805 (define_expand "ashrdi3"
12806   [(set (match_operand:DI 0 "shiftdi_operand" "")
12807         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12808                      (match_operand:QI 2 "nonmemory_operand" "")))]
12809   ""
12810   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12811
12812 (define_expand "x86_64_shift_adj_3"
12813   [(use (match_operand:DI 0 "register_operand" ""))
12814    (use (match_operand:DI 1 "register_operand" ""))
12815    (use (match_operand:QI 2 "register_operand" ""))]
12816   ""
12817 {
12818   rtx label = gen_label_rtx ();
12819   rtx tmp;
12820
12821   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12822
12823   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12824   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12825   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12826                               gen_rtx_LABEL_REF (VOIDmode, label),
12827                               pc_rtx);
12828   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12829   JUMP_LABEL (tmp) = label;
12830
12831   emit_move_insn (operands[0], operands[1]);
12832   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12833
12834   emit_label (label);
12835   LABEL_NUSES (label) = 1;
12836
12837   DONE;
12838 })
12839
12840 (define_insn "ashrdi3_63_rex64"
12841   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12842         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12843                      (match_operand:DI 2 "const_int_operand" "i,i")))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "TARGET_64BIT && INTVAL (operands[2]) == 63
12846    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12847    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12848   "@
12849    {cqto|cqo}
12850    sar{q}\t{%2, %0|%0, %2}"
12851   [(set_attr "type" "imovx,ishift")
12852    (set_attr "prefix_0f" "0,*")
12853    (set_attr "length_immediate" "0,*")
12854    (set_attr "modrm" "0,1")
12855    (set_attr "mode" "DI")])
12856
12857 (define_insn "*ashrdi3_1_one_bit_rex64"
12858   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860                      (match_operand:QI 2 "const1_operand" "")))
12861    (clobber (reg:CC FLAGS_REG))]
12862   "TARGET_64BIT
12863    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12865   "sar{q}\t%0"
12866   [(set_attr "type" "ishift")
12867    (set_attr "length_immediate" "0")
12868    (set_attr "mode" "DI")])
12869
12870 (define_insn "*ashrdi3_1_rex64"
12871   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12872         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12873                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12874    (clobber (reg:CC FLAGS_REG))]
12875   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12876   "@
12877    sar{q}\t{%2, %0|%0, %2}
12878    sar{q}\t{%b2, %0|%0, %b2}"
12879   [(set_attr "type" "ishift")
12880    (set_attr "mode" "DI")])
12881
12882 ;; This pattern can't accept a variable shift count, since shifts by
12883 ;; zero don't affect the flags.  We assume that shifts by constant
12884 ;; zero are optimized away.
12885 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12886   [(set (reg FLAGS_REG)
12887         (compare
12888           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12889                        (match_operand:QI 2 "const1_operand" ""))
12890           (const_int 0)))
12891    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12892         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12893   "TARGET_64BIT
12894    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12895    && ix86_match_ccmode (insn, CCGOCmode)
12896    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12897   "sar{q}\t%0"
12898   [(set_attr "type" "ishift")
12899    (set_attr "length_immediate" "0")
12900    (set_attr "mode" "DI")])
12901
12902 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12903   [(set (reg FLAGS_REG)
12904         (compare
12905           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906                        (match_operand:QI 2 "const1_operand" ""))
12907           (const_int 0)))
12908    (clobber (match_scratch:DI 0 "=r"))]
12909   "TARGET_64BIT
12910    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12911    && ix86_match_ccmode (insn, CCGOCmode)
12912    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12913   "sar{q}\t%0"
12914   [(set_attr "type" "ishift")
12915    (set_attr "length_immediate" "0")
12916    (set_attr "mode" "DI")])
12917
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags.  We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*ashrdi3_cmp_rex64"
12922   [(set (reg FLAGS_REG)
12923         (compare
12924           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12925                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12926           (const_int 0)))
12927    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12928         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12929   "TARGET_64BIT
12930    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12931    && ix86_match_ccmode (insn, CCGOCmode)
12932    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12933   "sar{q}\t{%2, %0|%0, %2}"
12934   [(set_attr "type" "ishift")
12935    (set_attr "mode" "DI")])
12936
12937 (define_insn "*ashrdi3_cconly_rex64"
12938   [(set (reg FLAGS_REG)
12939         (compare
12940           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12941                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12942           (const_int 0)))
12943    (clobber (match_scratch:DI 0 "=r"))]
12944   "TARGET_64BIT
12945    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12946    && ix86_match_ccmode (insn, CCGOCmode)
12947    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12948   "sar{q}\t{%2, %0|%0, %2}"
12949   [(set_attr "type" "ishift")
12950    (set_attr "mode" "DI")])
12951
12952 (define_insn "*ashrdi3_1"
12953   [(set (match_operand:DI 0 "register_operand" "=r")
12954         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12955                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "!TARGET_64BIT"
12958   "#"
12959   [(set_attr "type" "multi")])
12960
12961 ;; By default we don't ask for a scratch register, because when DImode
12962 ;; values are manipulated, registers are already at a premium.  But if
12963 ;; we have one handy, we won't turn it away.
12964 (define_peephole2
12965   [(match_scratch:SI 3 "r")
12966    (parallel [(set (match_operand:DI 0 "register_operand" "")
12967                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12968                                 (match_operand:QI 2 "nonmemory_operand" "")))
12969               (clobber (reg:CC FLAGS_REG))])
12970    (match_dup 3)]
12971   "!TARGET_64BIT && TARGET_CMOVE"
12972   [(const_int 0)]
12973   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12974
12975 (define_split
12976   [(set (match_operand:DI 0 "register_operand" "")
12977         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12978                      (match_operand:QI 2 "nonmemory_operand" "")))
12979    (clobber (reg:CC FLAGS_REG))]
12980   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12981                      ? epilogue_completed : reload_completed)"
12982   [(const_int 0)]
12983   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12984
12985 (define_insn "x86_shrd"
12986   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12987         (ior:SI (ashiftrt:SI (match_dup 0)
12988                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12989                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12990                   (minus:QI (const_int 32) (match_dup 2)))))
12991    (clobber (reg:CC FLAGS_REG))]
12992   ""
12993   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12994   [(set_attr "type" "ishift")
12995    (set_attr "prefix_0f" "1")
12996    (set_attr "pent_pair" "np")
12997    (set_attr "mode" "SI")])
12998
12999 (define_expand "x86_shift_adj_3"
13000   [(use (match_operand:SI 0 "register_operand" ""))
13001    (use (match_operand:SI 1 "register_operand" ""))
13002    (use (match_operand:QI 2 "register_operand" ""))]
13003   ""
13004 {
13005   rtx label = gen_label_rtx ();
13006   rtx tmp;
13007
13008   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
13009
13010   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13011   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13012   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13013                               gen_rtx_LABEL_REF (VOIDmode, label),
13014                               pc_rtx);
13015   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
13016   JUMP_LABEL (tmp) = label;
13017
13018   emit_move_insn (operands[0], operands[1]);
13019   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
13020
13021   emit_label (label);
13022   LABEL_NUSES (label) = 1;
13023
13024   DONE;
13025 })
13026
13027 (define_expand "ashrsi3_31"
13028   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13029                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13030                                 (match_operand:SI 2 "const_int_operand" "i,i")))
13031               (clobber (reg:CC FLAGS_REG))])]
13032   "")
13033
13034 (define_insn "*ashrsi3_31"
13035   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13036         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13037                      (match_operand:SI 2 "const_int_operand" "i,i")))
13038    (clobber (reg:CC FLAGS_REG))]
13039   "INTVAL (operands[2]) == 31
13040    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13041    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13042   "@
13043    {cltd|cdq}
13044    sar{l}\t{%2, %0|%0, %2}"
13045   [(set_attr "type" "imovx,ishift")
13046    (set_attr "prefix_0f" "0,*")
13047    (set_attr "length_immediate" "0,*")
13048    (set_attr "modrm" "0,1")
13049    (set_attr "mode" "SI")])
13050
13051 (define_insn "*ashrsi3_31_zext"
13052   [(set (match_operand:DI 0 "register_operand" "=*d,r")
13053         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
13054                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
13055    (clobber (reg:CC FLAGS_REG))]
13056   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13057    && INTVAL (operands[2]) == 31
13058    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13059   "@
13060    {cltd|cdq}
13061    sar{l}\t{%2, %k0|%k0, %2}"
13062   [(set_attr "type" "imovx,ishift")
13063    (set_attr "prefix_0f" "0,*")
13064    (set_attr "length_immediate" "0,*")
13065    (set_attr "modrm" "0,1")
13066    (set_attr "mode" "SI")])
13067
13068 (define_expand "ashrsi3"
13069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13070         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13071                      (match_operand:QI 2 "nonmemory_operand" "")))]
13072   ""
13073   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
13074
13075 (define_insn "*ashrsi3_1_one_bit"
13076   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13077         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13078                      (match_operand:QI 2 "const1_operand" "")))
13079    (clobber (reg:CC FLAGS_REG))]
13080   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13081    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13082   "sar{l}\t%0"
13083   [(set_attr "type" "ishift")
13084    (set_attr "length_immediate" "0")
13085    (set_attr "mode" "SI")])
13086
13087 (define_insn "*ashrsi3_1_one_bit_zext"
13088   [(set (match_operand:DI 0 "register_operand" "=r")
13089         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13090                                      (match_operand:QI 2 "const1_operand" ""))))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "TARGET_64BIT
13093    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13094    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13095   "sar{l}\t%k0"
13096   [(set_attr "type" "ishift")
13097    (set_attr "length_immediate" "0")
13098    (set_attr "mode" "SI")])
13099
13100 (define_insn "*ashrsi3_1"
13101   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13102         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13103                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13104    (clobber (reg:CC FLAGS_REG))]
13105   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13106   "@
13107    sar{l}\t{%2, %0|%0, %2}
13108    sar{l}\t{%b2, %0|%0, %b2}"
13109   [(set_attr "type" "ishift")
13110    (set_attr "mode" "SI")])
13111
13112 (define_insn "*ashrsi3_1_zext"
13113   [(set (match_operand:DI 0 "register_operand" "=r,r")
13114         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
13115                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13116    (clobber (reg:CC FLAGS_REG))]
13117   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13118   "@
13119    sar{l}\t{%2, %k0|%k0, %2}
13120    sar{l}\t{%b2, %k0|%k0, %b2}"
13121   [(set_attr "type" "ishift")
13122    (set_attr "mode" "SI")])
13123
13124 ;; This pattern can't accept a variable shift count, since shifts by
13125 ;; zero don't affect the flags.  We assume that shifts by constant
13126 ;; zero are optimized away.
13127 (define_insn "*ashrsi3_one_bit_cmp"
13128   [(set (reg FLAGS_REG)
13129         (compare
13130           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13131                        (match_operand:QI 2 "const1_operand" ""))
13132           (const_int 0)))
13133    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13134         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13135   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13136    && ix86_match_ccmode (insn, CCGOCmode)
13137    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13138   "sar{l}\t%0"
13139   [(set_attr "type" "ishift")
13140    (set_attr "length_immediate" "0")
13141    (set_attr "mode" "SI")])
13142
13143 (define_insn "*ashrsi3_one_bit_cconly"
13144   [(set (reg FLAGS_REG)
13145         (compare
13146           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13147                        (match_operand:QI 2 "const1_operand" ""))
13148           (const_int 0)))
13149    (clobber (match_scratch:SI 0 "=r"))]
13150   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13151    && ix86_match_ccmode (insn, CCGOCmode)
13152    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13153   "sar{l}\t%0"
13154   [(set_attr "type" "ishift")
13155    (set_attr "length_immediate" "0")
13156    (set_attr "mode" "SI")])
13157
13158 (define_insn "*ashrsi3_one_bit_cmp_zext"
13159   [(set (reg FLAGS_REG)
13160         (compare
13161           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13162                        (match_operand:QI 2 "const1_operand" ""))
13163           (const_int 0)))
13164    (set (match_operand:DI 0 "register_operand" "=r")
13165         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13166   "TARGET_64BIT
13167    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13168    && ix86_match_ccmode (insn, CCmode)
13169    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13170   "sar{l}\t%k0"
13171   [(set_attr "type" "ishift")
13172    (set_attr "length_immediate" "0")
13173    (set_attr "mode" "SI")])
13174
13175 ;; This pattern can't accept a variable shift count, since shifts by
13176 ;; zero don't affect the flags.  We assume that shifts by constant
13177 ;; zero are optimized away.
13178 (define_insn "*ashrsi3_cmp"
13179   [(set (reg FLAGS_REG)
13180         (compare
13181           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13182                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13183           (const_int 0)))
13184    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13185         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13186   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13187    && ix86_match_ccmode (insn, CCGOCmode)
13188    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13189   "sar{l}\t{%2, %0|%0, %2}"
13190   [(set_attr "type" "ishift")
13191    (set_attr "mode" "SI")])
13192
13193 (define_insn "*ashrsi3_cconly"
13194   [(set (reg FLAGS_REG)
13195         (compare
13196           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13197                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13198           (const_int 0)))
13199    (clobber (match_scratch:SI 0 "=r"))]
13200   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13201    && ix86_match_ccmode (insn, CCGOCmode)
13202    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13203   "sar{l}\t{%2, %0|%0, %2}"
13204   [(set_attr "type" "ishift")
13205    (set_attr "mode" "SI")])
13206
13207 (define_insn "*ashrsi3_cmp_zext"
13208   [(set (reg FLAGS_REG)
13209         (compare
13210           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13211                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13212           (const_int 0)))
13213    (set (match_operand:DI 0 "register_operand" "=r")
13214         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13215   "TARGET_64BIT
13216    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13217    && ix86_match_ccmode (insn, CCGOCmode)
13218    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13219   "sar{l}\t{%2, %k0|%k0, %2}"
13220   [(set_attr "type" "ishift")
13221    (set_attr "mode" "SI")])
13222
13223 (define_expand "ashrhi3"
13224   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13225         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13226                      (match_operand:QI 2 "nonmemory_operand" "")))]
13227   "TARGET_HIMODE_MATH"
13228   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
13229
13230 (define_insn "*ashrhi3_1_one_bit"
13231   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13232         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13233                      (match_operand:QI 2 "const1_operand" "")))
13234    (clobber (reg:CC FLAGS_REG))]
13235   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13236    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13237   "sar{w}\t%0"
13238   [(set_attr "type" "ishift")
13239    (set_attr "length_immediate" "0")
13240    (set_attr "mode" "HI")])
13241
13242 (define_insn "*ashrhi3_1"
13243   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13244         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13245                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13246    (clobber (reg:CC FLAGS_REG))]
13247   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13248   "@
13249    sar{w}\t{%2, %0|%0, %2}
13250    sar{w}\t{%b2, %0|%0, %b2}"
13251   [(set_attr "type" "ishift")
13252    (set_attr "mode" "HI")])
13253
13254 ;; This pattern can't accept a variable shift count, since shifts by
13255 ;; zero don't affect the flags.  We assume that shifts by constant
13256 ;; zero are optimized away.
13257 (define_insn "*ashrhi3_one_bit_cmp"
13258   [(set (reg FLAGS_REG)
13259         (compare
13260           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13261                        (match_operand:QI 2 "const1_operand" ""))
13262           (const_int 0)))
13263    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13264         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13265   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13266    && ix86_match_ccmode (insn, CCGOCmode)
13267    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13268   "sar{w}\t%0"
13269   [(set_attr "type" "ishift")
13270    (set_attr "length_immediate" "0")
13271    (set_attr "mode" "HI")])
13272
13273 (define_insn "*ashrhi3_one_bit_cconly"
13274   [(set (reg FLAGS_REG)
13275         (compare
13276           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13277                        (match_operand:QI 2 "const1_operand" ""))
13278           (const_int 0)))
13279    (clobber (match_scratch:HI 0 "=r"))]
13280   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13281    && ix86_match_ccmode (insn, CCGOCmode)
13282    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13283   "sar{w}\t%0"
13284   [(set_attr "type" "ishift")
13285    (set_attr "length_immediate" "0")
13286    (set_attr "mode" "HI")])
13287
13288 ;; This pattern can't accept a variable shift count, since shifts by
13289 ;; zero don't affect the flags.  We assume that shifts by constant
13290 ;; zero are optimized away.
13291 (define_insn "*ashrhi3_cmp"
13292   [(set (reg FLAGS_REG)
13293         (compare
13294           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13295                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13296           (const_int 0)))
13297    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13298         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13299   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13300    && ix86_match_ccmode (insn, CCGOCmode)
13301    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13302   "sar{w}\t{%2, %0|%0, %2}"
13303   [(set_attr "type" "ishift")
13304    (set_attr "mode" "HI")])
13305
13306 (define_insn "*ashrhi3_cconly"
13307   [(set (reg FLAGS_REG)
13308         (compare
13309           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13310                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13311           (const_int 0)))
13312    (clobber (match_scratch:HI 0 "=r"))]
13313   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13314    && ix86_match_ccmode (insn, CCGOCmode)
13315    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13316   "sar{w}\t{%2, %0|%0, %2}"
13317   [(set_attr "type" "ishift")
13318    (set_attr "mode" "HI")])
13319
13320 (define_expand "ashrqi3"
13321   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13322         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13323                      (match_operand:QI 2 "nonmemory_operand" "")))]
13324   "TARGET_QIMODE_MATH"
13325   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
13326
13327 (define_insn "*ashrqi3_1_one_bit"
13328   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13329         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330                      (match_operand:QI 2 "const1_operand" "")))
13331    (clobber (reg:CC FLAGS_REG))]
13332   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13334   "sar{b}\t%0"
13335   [(set_attr "type" "ishift")
13336    (set_attr "length_immediate" "0")
13337    (set_attr "mode" "QI")])
13338
13339 (define_insn "*ashrqi3_1_one_bit_slp"
13340   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13341         (ashiftrt:QI (match_dup 0)
13342                      (match_operand:QI 1 "const1_operand" "")))
13343    (clobber (reg:CC FLAGS_REG))]
13344   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13345    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13346    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13347   "sar{b}\t%0"
13348   [(set_attr "type" "ishift1")
13349    (set_attr "length_immediate" "0")
13350    (set_attr "mode" "QI")])
13351
13352 (define_insn "*ashrqi3_1"
13353   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13354         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13355                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13356    (clobber (reg:CC FLAGS_REG))]
13357   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13358   "@
13359    sar{b}\t{%2, %0|%0, %2}
13360    sar{b}\t{%b2, %0|%0, %b2}"
13361   [(set_attr "type" "ishift")
13362    (set_attr "mode" "QI")])
13363
13364 (define_insn "*ashrqi3_1_slp"
13365   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13366         (ashiftrt:QI (match_dup 0)
13367                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13368    (clobber (reg:CC FLAGS_REG))]
13369   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13370    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13371   "@
13372    sar{b}\t{%1, %0|%0, %1}
13373    sar{b}\t{%b1, %0|%0, %b1}"
13374   [(set_attr "type" "ishift1")
13375    (set_attr "mode" "QI")])
13376
13377 ;; This pattern can't accept a variable shift count, since shifts by
13378 ;; zero don't affect the flags.  We assume that shifts by constant
13379 ;; zero are optimized away.
13380 (define_insn "*ashrqi3_one_bit_cmp"
13381   [(set (reg FLAGS_REG)
13382         (compare
13383           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13384                        (match_operand:QI 2 "const1_operand" "I"))
13385           (const_int 0)))
13386    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13387         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13388   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13389    && ix86_match_ccmode (insn, CCGOCmode)
13390    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13391   "sar{b}\t%0"
13392   [(set_attr "type" "ishift")
13393    (set_attr "length_immediate" "0")
13394    (set_attr "mode" "QI")])
13395
13396 (define_insn "*ashrqi3_one_bit_cconly"
13397   [(set (reg FLAGS_REG)
13398         (compare
13399           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13400                        (match_operand:QI 2 "const1_operand" ""))
13401           (const_int 0)))
13402    (clobber (match_scratch:QI 0 "=q"))]
13403   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13404    && ix86_match_ccmode (insn, CCGOCmode)
13405    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13406   "sar{b}\t%0"
13407   [(set_attr "type" "ishift")
13408    (set_attr "length_immediate" "0")
13409    (set_attr "mode" "QI")])
13410
13411 ;; This pattern can't accept a variable shift count, since shifts by
13412 ;; zero don't affect the flags.  We assume that shifts by constant
13413 ;; zero are optimized away.
13414 (define_insn "*ashrqi3_cmp"
13415   [(set (reg FLAGS_REG)
13416         (compare
13417           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13418                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13419           (const_int 0)))
13420    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13421         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13422   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13423    && ix86_match_ccmode (insn, CCGOCmode)
13424    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13425   "sar{b}\t{%2, %0|%0, %2}"
13426   [(set_attr "type" "ishift")
13427    (set_attr "mode" "QI")])
13428
13429 (define_insn "*ashrqi3_cconly"
13430   [(set (reg FLAGS_REG)
13431         (compare
13432           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13433                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13434           (const_int 0)))
13435    (clobber (match_scratch:QI 0 "=q"))]
13436   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13437    && ix86_match_ccmode (insn, CCGOCmode)
13438    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13439   "sar{b}\t{%2, %0|%0, %2}"
13440   [(set_attr "type" "ishift")
13441    (set_attr "mode" "QI")])
13442
13443 \f
13444 ;; Logical shift instructions
13445
13446 ;; See comment above `ashldi3' about how this works.
13447
13448 (define_expand "lshrti3"
13449   [(set (match_operand:TI 0 "register_operand" "")
13450         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13451                      (match_operand:QI 2 "nonmemory_operand" "")))]
13452   "TARGET_64BIT"
13453   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
13454
13455 ;; This pattern must be defined before *lshrti3_1 to prevent
13456 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
13457
13458 (define_insn "*avx_lshrti3"
13459   [(set (match_operand:TI 0 "register_operand" "=x")
13460         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13461                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13462   "TARGET_AVX"
13463 {
13464   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13465   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13466 }
13467   [(set_attr "type" "sseishft")
13468    (set_attr "prefix" "vex")
13469    (set_attr "length_immediate" "1")
13470    (set_attr "mode" "TI")])
13471
13472 (define_insn "sse2_lshrti3"
13473   [(set (match_operand:TI 0 "register_operand" "=x")
13474         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13475                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13476   "TARGET_SSE2"
13477 {
13478   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13479   return "psrldq\t{%2, %0|%0, %2}";
13480 }
13481   [(set_attr "type" "sseishft")
13482    (set_attr "prefix_data16" "1")
13483    (set_attr "length_immediate" "1")
13484    (set_attr "mode" "TI")])
13485
13486 (define_insn "*lshrti3_1"
13487   [(set (match_operand:TI 0 "register_operand" "=r")
13488         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13489                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "TARGET_64BIT"
13492   "#"
13493   [(set_attr "type" "multi")])
13494
13495 (define_peephole2
13496   [(match_scratch:DI 3 "r")
13497    (parallel [(set (match_operand:TI 0 "register_operand" "")
13498                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13499                                 (match_operand:QI 2 "nonmemory_operand" "")))
13500               (clobber (reg:CC FLAGS_REG))])
13501    (match_dup 3)]
13502   "TARGET_64BIT"
13503   [(const_int 0)]
13504   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13505
13506 (define_split
13507   [(set (match_operand:TI 0 "register_operand" "")
13508         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13509                      (match_operand:QI 2 "nonmemory_operand" "")))
13510    (clobber (reg:CC FLAGS_REG))]
13511   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13512                     ? epilogue_completed : reload_completed)"
13513   [(const_int 0)]
13514   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13515
13516 (define_expand "lshrdi3"
13517   [(set (match_operand:DI 0 "shiftdi_operand" "")
13518         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13519                      (match_operand:QI 2 "nonmemory_operand" "")))]
13520   ""
13521   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
13522
13523 (define_insn "*lshrdi3_1_one_bit_rex64"
13524   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13525         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13526                      (match_operand:QI 2 "const1_operand" "")))
13527    (clobber (reg:CC FLAGS_REG))]
13528   "TARGET_64BIT
13529    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13530    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13531   "shr{q}\t%0"
13532   [(set_attr "type" "ishift")
13533    (set_attr "length_immediate" "0")
13534    (set_attr "mode" "DI")])
13535
13536 (define_insn "*lshrdi3_1_rex64"
13537   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13538         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13539                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13540    (clobber (reg:CC FLAGS_REG))]
13541   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13542   "@
13543    shr{q}\t{%2, %0|%0, %2}
13544    shr{q}\t{%b2, %0|%0, %b2}"
13545   [(set_attr "type" "ishift")
13546    (set_attr "mode" "DI")])
13547
13548 ;; This pattern can't accept a variable shift count, since shifts by
13549 ;; zero don't affect the flags.  We assume that shifts by constant
13550 ;; zero are optimized away.
13551 (define_insn "*lshrdi3_cmp_one_bit_rex64"
13552   [(set (reg FLAGS_REG)
13553         (compare
13554           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13555                        (match_operand:QI 2 "const1_operand" ""))
13556           (const_int 0)))
13557    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13558         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13559   "TARGET_64BIT
13560    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13561    && ix86_match_ccmode (insn, CCGOCmode)
13562    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13563   "shr{q}\t%0"
13564   [(set_attr "type" "ishift")
13565    (set_attr "length_immediate" "0")
13566    (set_attr "mode" "DI")])
13567
13568 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13569   [(set (reg FLAGS_REG)
13570         (compare
13571           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13572                        (match_operand:QI 2 "const1_operand" ""))
13573           (const_int 0)))
13574    (clobber (match_scratch:DI 0 "=r"))]
13575   "TARGET_64BIT
13576    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13577    && ix86_match_ccmode (insn, CCGOCmode)
13578    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13579   "shr{q}\t%0"
13580   [(set_attr "type" "ishift")
13581    (set_attr "length_immediate" "0")
13582    (set_attr "mode" "DI")])
13583
13584 ;; This pattern can't accept a variable shift count, since shifts by
13585 ;; zero don't affect the flags.  We assume that shifts by constant
13586 ;; zero are optimized away.
13587 (define_insn "*lshrdi3_cmp_rex64"
13588   [(set (reg FLAGS_REG)
13589         (compare
13590           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13591                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13592           (const_int 0)))
13593    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13594         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13595   "TARGET_64BIT
13596    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13597    && ix86_match_ccmode (insn, CCGOCmode)
13598    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13599   "shr{q}\t{%2, %0|%0, %2}"
13600   [(set_attr "type" "ishift")
13601    (set_attr "mode" "DI")])
13602
13603 (define_insn "*lshrdi3_cconly_rex64"
13604   [(set (reg FLAGS_REG)
13605         (compare
13606           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13607                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13608           (const_int 0)))
13609    (clobber (match_scratch:DI 0 "=r"))]
13610   "TARGET_64BIT
13611    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13612    && ix86_match_ccmode (insn, CCGOCmode)
13613    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13614   "shr{q}\t{%2, %0|%0, %2}"
13615   [(set_attr "type" "ishift")
13616    (set_attr "mode" "DI")])
13617
13618 (define_insn "*lshrdi3_1"
13619   [(set (match_operand:DI 0 "register_operand" "=r")
13620         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13621                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
13622    (clobber (reg:CC FLAGS_REG))]
13623   "!TARGET_64BIT"
13624   "#"
13625   [(set_attr "type" "multi")])
13626
13627 ;; By default we don't ask for a scratch register, because when DImode
13628 ;; values are manipulated, registers are already at a premium.  But if
13629 ;; we have one handy, we won't turn it away.
13630 (define_peephole2
13631   [(match_scratch:SI 3 "r")
13632    (parallel [(set (match_operand:DI 0 "register_operand" "")
13633                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13634                                 (match_operand:QI 2 "nonmemory_operand" "")))
13635               (clobber (reg:CC FLAGS_REG))])
13636    (match_dup 3)]
13637   "!TARGET_64BIT && TARGET_CMOVE"
13638   [(const_int 0)]
13639   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13640
13641 (define_split
13642   [(set (match_operand:DI 0 "register_operand" "")
13643         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13644                      (match_operand:QI 2 "nonmemory_operand" "")))
13645    (clobber (reg:CC FLAGS_REG))]
13646   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13647                      ? epilogue_completed : reload_completed)"
13648   [(const_int 0)]
13649   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13650
13651 (define_expand "lshrsi3"
13652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13653         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13654                      (match_operand:QI 2 "nonmemory_operand" "")))]
13655   ""
13656   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13657
13658 (define_insn "*lshrsi3_1_one_bit"
13659   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13660         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13661                      (match_operand:QI 2 "const1_operand" "")))
13662    (clobber (reg:CC FLAGS_REG))]
13663   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13664    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13665   "shr{l}\t%0"
13666   [(set_attr "type" "ishift")
13667    (set_attr "length_immediate" "0")
13668    (set_attr "mode" "SI")])
13669
13670 (define_insn "*lshrsi3_1_one_bit_zext"
13671   [(set (match_operand:DI 0 "register_operand" "=r")
13672         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13673                      (match_operand:QI 2 "const1_operand" "")))
13674    (clobber (reg:CC FLAGS_REG))]
13675   "TARGET_64BIT
13676    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13678   "shr{l}\t%k0"
13679   [(set_attr "type" "ishift")
13680    (set_attr "length_immediate" "0")
13681    (set_attr "mode" "SI")])
13682
13683 (define_insn "*lshrsi3_1"
13684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13685         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13686                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13689   "@
13690    shr{l}\t{%2, %0|%0, %2}
13691    shr{l}\t{%b2, %0|%0, %b2}"
13692   [(set_attr "type" "ishift")
13693    (set_attr "mode" "SI")])
13694
13695 (define_insn "*lshrsi3_1_zext"
13696   [(set (match_operand:DI 0 "register_operand" "=r,r")
13697         (zero_extend:DI
13698           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13699                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13700    (clobber (reg:CC FLAGS_REG))]
13701   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13702   "@
13703    shr{l}\t{%2, %k0|%k0, %2}
13704    shr{l}\t{%b2, %k0|%k0, %b2}"
13705   [(set_attr "type" "ishift")
13706    (set_attr "mode" "SI")])
13707
13708 ;; This pattern can't accept a variable shift count, since shifts by
13709 ;; zero don't affect the flags.  We assume that shifts by constant
13710 ;; zero are optimized away.
13711 (define_insn "*lshrsi3_one_bit_cmp"
13712   [(set (reg FLAGS_REG)
13713         (compare
13714           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13715                        (match_operand:QI 2 "const1_operand" ""))
13716           (const_int 0)))
13717    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13718         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13719   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13720    && ix86_match_ccmode (insn, CCGOCmode)
13721    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13722   "shr{l}\t%0"
13723   [(set_attr "type" "ishift")
13724    (set_attr "length_immediate" "0")
13725    (set_attr "mode" "SI")])
13726
13727 (define_insn "*lshrsi3_one_bit_cconly"
13728   [(set (reg FLAGS_REG)
13729         (compare
13730           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13731                        (match_operand:QI 2 "const1_operand" ""))
13732           (const_int 0)))
13733    (clobber (match_scratch:SI 0 "=r"))]
13734   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13735    && ix86_match_ccmode (insn, CCGOCmode)
13736    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13737   "shr{l}\t%0"
13738   [(set_attr "type" "ishift")
13739    (set_attr "length_immediate" "0")
13740    (set_attr "mode" "SI")])
13741
13742 (define_insn "*lshrsi3_cmp_one_bit_zext"
13743   [(set (reg FLAGS_REG)
13744         (compare
13745           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13746                        (match_operand:QI 2 "const1_operand" ""))
13747           (const_int 0)))
13748    (set (match_operand:DI 0 "register_operand" "=r")
13749         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13750   "TARGET_64BIT
13751    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13752    && ix86_match_ccmode (insn, CCGOCmode)
13753    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13754   "shr{l}\t%k0"
13755   [(set_attr "type" "ishift")
13756    (set_attr "length_immediate" "0")
13757    (set_attr "mode" "SI")])
13758
13759 ;; This pattern can't accept a variable shift count, since shifts by
13760 ;; zero don't affect the flags.  We assume that shifts by constant
13761 ;; zero are optimized away.
13762 (define_insn "*lshrsi3_cmp"
13763   [(set (reg FLAGS_REG)
13764         (compare
13765           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13766                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13767           (const_int 0)))
13768    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13769         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13770   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13771    && ix86_match_ccmode (insn, CCGOCmode)
13772    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13773   "shr{l}\t{%2, %0|%0, %2}"
13774   [(set_attr "type" "ishift")
13775    (set_attr "mode" "SI")])
13776
13777 (define_insn "*lshrsi3_cconly"
13778   [(set (reg FLAGS_REG)
13779       (compare
13780         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13781                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13782         (const_int 0)))
13783    (clobber (match_scratch:SI 0 "=r"))]
13784   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13785    && ix86_match_ccmode (insn, CCGOCmode)
13786    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13787   "shr{l}\t{%2, %0|%0, %2}"
13788   [(set_attr "type" "ishift")
13789    (set_attr "mode" "SI")])
13790
13791 (define_insn "*lshrsi3_cmp_zext"
13792   [(set (reg FLAGS_REG)
13793         (compare
13794           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13795                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13796           (const_int 0)))
13797    (set (match_operand:DI 0 "register_operand" "=r")
13798         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13799   "TARGET_64BIT
13800    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13801    && ix86_match_ccmode (insn, CCGOCmode)
13802    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13803   "shr{l}\t{%2, %k0|%k0, %2}"
13804   [(set_attr "type" "ishift")
13805    (set_attr "mode" "SI")])
13806
13807 (define_expand "lshrhi3"
13808   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13809         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13810                      (match_operand:QI 2 "nonmemory_operand" "")))]
13811   "TARGET_HIMODE_MATH"
13812   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13813
13814 (define_insn "*lshrhi3_1_one_bit"
13815   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13816         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13817                      (match_operand:QI 2 "const1_operand" "")))
13818    (clobber (reg:CC FLAGS_REG))]
13819   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13820    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13821   "shr{w}\t%0"
13822   [(set_attr "type" "ishift")
13823    (set_attr "length_immediate" "0")
13824    (set_attr "mode" "HI")])
13825
13826 (define_insn "*lshrhi3_1"
13827   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13828         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13829                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13830    (clobber (reg:CC FLAGS_REG))]
13831   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13832   "@
13833    shr{w}\t{%2, %0|%0, %2}
13834    shr{w}\t{%b2, %0|%0, %b2}"
13835   [(set_attr "type" "ishift")
13836    (set_attr "mode" "HI")])
13837
13838 ;; This pattern can't accept a variable shift count, since shifts by
13839 ;; zero don't affect the flags.  We assume that shifts by constant
13840 ;; zero are optimized away.
13841 (define_insn "*lshrhi3_one_bit_cmp"
13842   [(set (reg FLAGS_REG)
13843         (compare
13844           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13845                        (match_operand:QI 2 "const1_operand" ""))
13846           (const_int 0)))
13847    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13848         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13849   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13850    && ix86_match_ccmode (insn, CCGOCmode)
13851    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13852   "shr{w}\t%0"
13853   [(set_attr "type" "ishift")
13854    (set_attr "length_immediate" "0")
13855    (set_attr "mode" "HI")])
13856
13857 (define_insn "*lshrhi3_one_bit_cconly"
13858   [(set (reg FLAGS_REG)
13859         (compare
13860           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13861                        (match_operand:QI 2 "const1_operand" ""))
13862           (const_int 0)))
13863    (clobber (match_scratch:HI 0 "=r"))]
13864   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13865    && ix86_match_ccmode (insn, CCGOCmode)
13866    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13867   "shr{w}\t%0"
13868   [(set_attr "type" "ishift")
13869    (set_attr "length_immediate" "0")
13870    (set_attr "mode" "HI")])
13871
13872 ;; This pattern can't accept a variable shift count, since shifts by
13873 ;; zero don't affect the flags.  We assume that shifts by constant
13874 ;; zero are optimized away.
13875 (define_insn "*lshrhi3_cmp"
13876   [(set (reg FLAGS_REG)
13877         (compare
13878           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13879                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13880           (const_int 0)))
13881    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13882         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13883   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13884    && ix86_match_ccmode (insn, CCGOCmode)
13885    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13886   "shr{w}\t{%2, %0|%0, %2}"
13887   [(set_attr "type" "ishift")
13888    (set_attr "mode" "HI")])
13889
13890 (define_insn "*lshrhi3_cconly"
13891   [(set (reg FLAGS_REG)
13892         (compare
13893           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13894                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13895           (const_int 0)))
13896    (clobber (match_scratch:HI 0 "=r"))]
13897   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13898    && ix86_match_ccmode (insn, CCGOCmode)
13899    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13900   "shr{w}\t{%2, %0|%0, %2}"
13901   [(set_attr "type" "ishift")
13902    (set_attr "mode" "HI")])
13903
13904 (define_expand "lshrqi3"
13905   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13906         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13907                      (match_operand:QI 2 "nonmemory_operand" "")))]
13908   "TARGET_QIMODE_MATH"
13909   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13910
13911 (define_insn "*lshrqi3_1_one_bit"
13912   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13913         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13914                      (match_operand:QI 2 "const1_operand" "")))
13915    (clobber (reg:CC FLAGS_REG))]
13916   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13917    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13918   "shr{b}\t%0"
13919   [(set_attr "type" "ishift")
13920    (set_attr "length_immediate" "0")
13921    (set_attr "mode" "QI")])
13922
13923 (define_insn "*lshrqi3_1_one_bit_slp"
13924   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13925         (lshiftrt:QI (match_dup 0)
13926                      (match_operand:QI 1 "const1_operand" "")))
13927    (clobber (reg:CC FLAGS_REG))]
13928   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13929    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13930   "shr{b}\t%0"
13931   [(set_attr "type" "ishift1")
13932    (set_attr "length_immediate" "0")
13933    (set_attr "mode" "QI")])
13934
13935 (define_insn "*lshrqi3_1"
13936   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13937         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13938                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13941   "@
13942    shr{b}\t{%2, %0|%0, %2}
13943    shr{b}\t{%b2, %0|%0, %b2}"
13944   [(set_attr "type" "ishift")
13945    (set_attr "mode" "QI")])
13946
13947 (define_insn "*lshrqi3_1_slp"
13948   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13949         (lshiftrt:QI (match_dup 0)
13950                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13951    (clobber (reg:CC FLAGS_REG))]
13952   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13953    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13954   "@
13955    shr{b}\t{%1, %0|%0, %1}
13956    shr{b}\t{%b1, %0|%0, %b1}"
13957   [(set_attr "type" "ishift1")
13958    (set_attr "mode" "QI")])
13959
13960 ;; This pattern can't accept a variable shift count, since shifts by
13961 ;; zero don't affect the flags.  We assume that shifts by constant
13962 ;; zero are optimized away.
13963 (define_insn "*lshrqi2_one_bit_cmp"
13964   [(set (reg FLAGS_REG)
13965         (compare
13966           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13967                        (match_operand:QI 2 "const1_operand" ""))
13968           (const_int 0)))
13969    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13970         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13971   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13972    && ix86_match_ccmode (insn, CCGOCmode)
13973    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13974   "shr{b}\t%0"
13975   [(set_attr "type" "ishift")
13976    (set_attr "length_immediate" "0")
13977    (set_attr "mode" "QI")])
13978
13979 (define_insn "*lshrqi2_one_bit_cconly"
13980   [(set (reg FLAGS_REG)
13981         (compare
13982           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13983                        (match_operand:QI 2 "const1_operand" ""))
13984           (const_int 0)))
13985    (clobber (match_scratch:QI 0 "=q"))]
13986   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13987    && ix86_match_ccmode (insn, CCGOCmode)
13988    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13989   "shr{b}\t%0"
13990   [(set_attr "type" "ishift")
13991    (set_attr "length_immediate" "0")
13992    (set_attr "mode" "QI")])
13993
13994 ;; This pattern can't accept a variable shift count, since shifts by
13995 ;; zero don't affect the flags.  We assume that shifts by constant
13996 ;; zero are optimized away.
13997 (define_insn "*lshrqi2_cmp"
13998   [(set (reg FLAGS_REG)
13999         (compare
14000           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
14002           (const_int 0)))
14003    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14004         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
14005   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14006    && ix86_match_ccmode (insn, CCGOCmode)
14007    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14008   "shr{b}\t{%2, %0|%0, %2}"
14009   [(set_attr "type" "ishift")
14010    (set_attr "mode" "QI")])
14011
14012 (define_insn "*lshrqi2_cconly"
14013   [(set (reg FLAGS_REG)
14014         (compare
14015           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14016                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
14017           (const_int 0)))
14018    (clobber (match_scratch:QI 0 "=q"))]
14019   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14020    && ix86_match_ccmode (insn, CCGOCmode)
14021    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14022   "shr{b}\t{%2, %0|%0, %2}"
14023   [(set_attr "type" "ishift")
14024    (set_attr "mode" "QI")])
14025 \f
14026 ;; Rotate instructions
14027
14028 (define_expand "rotldi3"
14029   [(set (match_operand:DI 0 "shiftdi_operand" "")
14030         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14031                    (match_operand:QI 2 "nonmemory_operand" "")))]
14032  ""
14033 {
14034   if (TARGET_64BIT)
14035     {
14036       ix86_expand_binary_operator (ROTATE, DImode, operands);
14037       DONE;
14038     }
14039   if (!const_1_to_31_operand (operands[2], VOIDmode))
14040     FAIL;
14041   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
14042   DONE;
14043 })
14044
14045 ;; Implement rotation using two double-precision shift instructions
14046 ;; and a scratch register.
14047 (define_insn_and_split "ix86_rotldi3"
14048  [(set (match_operand:DI 0 "register_operand" "=r")
14049        (rotate:DI (match_operand:DI 1 "register_operand" "0")
14050                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
14051   (clobber (reg:CC FLAGS_REG))
14052   (clobber (match_scratch:SI 3 "=&r"))]
14053  "!TARGET_64BIT"
14054  ""
14055  "&& reload_completed"
14056  [(set (match_dup 3) (match_dup 4))
14057   (parallel
14058    [(set (match_dup 4)
14059          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
14060                  (lshiftrt:SI (match_dup 5)
14061                               (minus:QI (const_int 32) (match_dup 2)))))
14062     (clobber (reg:CC FLAGS_REG))])
14063   (parallel
14064    [(set (match_dup 5)
14065          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
14066                  (lshiftrt:SI (match_dup 3)
14067                               (minus:QI (const_int 32) (match_dup 2)))))
14068     (clobber (reg:CC FLAGS_REG))])]
14069  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14070
14071 (define_insn "*rotlsi3_1_one_bit_rex64"
14072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14073         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14074                    (match_operand:QI 2 "const1_operand" "")))
14075    (clobber (reg:CC FLAGS_REG))]
14076   "TARGET_64BIT
14077    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14078    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14079   "rol{q}\t%0"
14080   [(set_attr "type" "rotate")
14081    (set_attr "length_immediate" "0")
14082    (set_attr "mode" "DI")])
14083
14084 (define_insn "*rotldi3_1_rex64"
14085   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14086         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14087                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
14088    (clobber (reg:CC FLAGS_REG))]
14089   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14090   "@
14091    rol{q}\t{%2, %0|%0, %2}
14092    rol{q}\t{%b2, %0|%0, %b2}"
14093   [(set_attr "type" "rotate")
14094    (set_attr "mode" "DI")])
14095
14096 (define_expand "rotlsi3"
14097   [(set (match_operand:SI 0 "nonimmediate_operand" "")
14098         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
14099                    (match_operand:QI 2 "nonmemory_operand" "")))]
14100   ""
14101   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
14102
14103 (define_insn "*rotlsi3_1_one_bit"
14104   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14105         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14106                    (match_operand:QI 2 "const1_operand" "")))
14107    (clobber (reg:CC FLAGS_REG))]
14108   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14109    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14110   "rol{l}\t%0"
14111   [(set_attr "type" "rotate")
14112    (set_attr "length_immediate" "0")
14113    (set_attr "mode" "SI")])
14114
14115 (define_insn "*rotlsi3_1_one_bit_zext"
14116   [(set (match_operand:DI 0 "register_operand" "=r")
14117         (zero_extend:DI
14118           (rotate:SI (match_operand:SI 1 "register_operand" "0")
14119                      (match_operand:QI 2 "const1_operand" ""))))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "TARGET_64BIT
14122    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14123    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14124   "rol{l}\t%k0"
14125   [(set_attr "type" "rotate")
14126    (set_attr "length_immediate" "0")
14127    (set_attr "mode" "SI")])
14128
14129 (define_insn "*rotlsi3_1"
14130   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14131         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14132                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14133    (clobber (reg:CC FLAGS_REG))]
14134   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
14135   "@
14136    rol{l}\t{%2, %0|%0, %2}
14137    rol{l}\t{%b2, %0|%0, %b2}"
14138   [(set_attr "type" "rotate")
14139    (set_attr "mode" "SI")])
14140
14141 (define_insn "*rotlsi3_1_zext"
14142   [(set (match_operand:DI 0 "register_operand" "=r,r")
14143         (zero_extend:DI
14144           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
14145                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14146    (clobber (reg:CC FLAGS_REG))]
14147   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14148   "@
14149    rol{l}\t{%2, %k0|%k0, %2}
14150    rol{l}\t{%b2, %k0|%k0, %b2}"
14151   [(set_attr "type" "rotate")
14152    (set_attr "mode" "SI")])
14153
14154 (define_expand "rotlhi3"
14155   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14156         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
14157                    (match_operand:QI 2 "nonmemory_operand" "")))]
14158   "TARGET_HIMODE_MATH"
14159   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
14160
14161 (define_insn "*rotlhi3_1_one_bit"
14162   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14163         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14164                    (match_operand:QI 2 "const1_operand" "")))
14165    (clobber (reg:CC FLAGS_REG))]
14166   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14167    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
14168   "rol{w}\t%0"
14169   [(set_attr "type" "rotate")
14170    (set_attr "length_immediate" "0")
14171    (set_attr "mode" "HI")])
14172
14173 (define_insn "*rotlhi3_1"
14174   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14175         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14176                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14177    (clobber (reg:CC FLAGS_REG))]
14178   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
14179   "@
14180    rol{w}\t{%2, %0|%0, %2}
14181    rol{w}\t{%b2, %0|%0, %b2}"
14182   [(set_attr "type" "rotate")
14183    (set_attr "mode" "HI")])
14184
14185 (define_split
14186  [(set (match_operand:HI 0 "register_operand" "")
14187        (rotate:HI (match_dup 0) (const_int 8)))
14188   (clobber (reg:CC FLAGS_REG))]
14189  "reload_completed"
14190  [(parallel [(set (strict_low_part (match_dup 0))
14191                   (bswap:HI (match_dup 0)))
14192              (clobber (reg:CC FLAGS_REG))])]
14193  "")
14194
14195 (define_expand "rotlqi3"
14196   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14197         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
14198                    (match_operand:QI 2 "nonmemory_operand" "")))]
14199   "TARGET_QIMODE_MATH"
14200   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
14201
14202 (define_insn "*rotlqi3_1_one_bit_slp"
14203   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14204         (rotate:QI (match_dup 0)
14205                    (match_operand:QI 1 "const1_operand" "")))
14206    (clobber (reg:CC FLAGS_REG))]
14207   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14208    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14209   "rol{b}\t%0"
14210   [(set_attr "type" "rotate1")
14211    (set_attr "length_immediate" "0")
14212    (set_attr "mode" "QI")])
14213
14214 (define_insn "*rotlqi3_1_one_bit"
14215   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14216         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14217                    (match_operand:QI 2 "const1_operand" "")))
14218    (clobber (reg:CC FLAGS_REG))]
14219   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14220    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
14221   "rol{b}\t%0"
14222   [(set_attr "type" "rotate")
14223    (set_attr "length_immediate" "0")
14224    (set_attr "mode" "QI")])
14225
14226 (define_insn "*rotlqi3_1_slp"
14227   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14228         (rotate:QI (match_dup 0)
14229                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
14230    (clobber (reg:CC FLAGS_REG))]
14231   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14232    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14233   "@
14234    rol{b}\t{%1, %0|%0, %1}
14235    rol{b}\t{%b1, %0|%0, %b1}"
14236   [(set_attr "type" "rotate1")
14237    (set_attr "mode" "QI")])
14238
14239 (define_insn "*rotlqi3_1"
14240   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14241         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14242                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14243    (clobber (reg:CC FLAGS_REG))]
14244   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
14245   "@
14246    rol{b}\t{%2, %0|%0, %2}
14247    rol{b}\t{%b2, %0|%0, %b2}"
14248   [(set_attr "type" "rotate")
14249    (set_attr "mode" "QI")])
14250
14251 (define_expand "rotrdi3"
14252   [(set (match_operand:DI 0 "shiftdi_operand" "")
14253         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14254                    (match_operand:QI 2 "nonmemory_operand" "")))]
14255  ""
14256 {
14257   if (TARGET_64BIT)
14258     {
14259       ix86_expand_binary_operator (ROTATERT, DImode, operands);
14260       DONE;
14261     }
14262   if (!const_1_to_31_operand (operands[2], VOIDmode))
14263     FAIL;
14264   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
14265   DONE;
14266 })
14267
14268 ;; Implement rotation using two double-precision shift instructions
14269 ;; and a scratch register.
14270 (define_insn_and_split "ix86_rotrdi3"
14271  [(set (match_operand:DI 0 "register_operand" "=r")
14272        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
14273                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
14274   (clobber (reg:CC FLAGS_REG))
14275   (clobber (match_scratch:SI 3 "=&r"))]
14276  "!TARGET_64BIT"
14277  ""
14278  "&& reload_completed"
14279  [(set (match_dup 3) (match_dup 4))
14280   (parallel
14281    [(set (match_dup 4)
14282          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
14283                  (ashift:SI (match_dup 5)
14284                             (minus:QI (const_int 32) (match_dup 2)))))
14285     (clobber (reg:CC FLAGS_REG))])
14286   (parallel
14287    [(set (match_dup 5)
14288          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
14289                  (ashift:SI (match_dup 3)
14290                             (minus:QI (const_int 32) (match_dup 2)))))
14291     (clobber (reg:CC FLAGS_REG))])]
14292  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14293
14294 (define_insn "*rotrdi3_1_one_bit_rex64"
14295   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14296         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14297                      (match_operand:QI 2 "const1_operand" "")))
14298    (clobber (reg:CC FLAGS_REG))]
14299   "TARGET_64BIT
14300    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14301    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14302   "ror{q}\t%0"
14303   [(set_attr "type" "rotate")
14304    (set_attr "length_immediate" "0")
14305    (set_attr "mode" "DI")])
14306
14307 (define_insn "*rotrdi3_1_rex64"
14308   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14309         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14310                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
14311    (clobber (reg:CC FLAGS_REG))]
14312   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14313   "@
14314    ror{q}\t{%2, %0|%0, %2}
14315    ror{q}\t{%b2, %0|%0, %b2}"
14316   [(set_attr "type" "rotate")
14317    (set_attr "mode" "DI")])
14318
14319 (define_expand "rotrsi3"
14320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
14321         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
14322                      (match_operand:QI 2 "nonmemory_operand" "")))]
14323   ""
14324   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
14325
14326 (define_insn "*rotrsi3_1_one_bit"
14327   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14328         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14329                      (match_operand:QI 2 "const1_operand" "")))
14330    (clobber (reg:CC FLAGS_REG))]
14331   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14332    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14333   "ror{l}\t%0"
14334   [(set_attr "type" "rotate")
14335    (set_attr "length_immediate" "0")
14336    (set_attr "mode" "SI")])
14337
14338 (define_insn "*rotrsi3_1_one_bit_zext"
14339   [(set (match_operand:DI 0 "register_operand" "=r")
14340         (zero_extend:DI
14341           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
14342                        (match_operand:QI 2 "const1_operand" ""))))
14343    (clobber (reg:CC FLAGS_REG))]
14344   "TARGET_64BIT
14345    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14346    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14347   "ror{l}\t%k0"
14348   [(set_attr "type" "rotate")
14349    (set_attr "length_immediate" "0")
14350    (set_attr "mode" "SI")])
14351
14352 (define_insn "*rotrsi3_1"
14353   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14354         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14355                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14356    (clobber (reg:CC FLAGS_REG))]
14357   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14358   "@
14359    ror{l}\t{%2, %0|%0, %2}
14360    ror{l}\t{%b2, %0|%0, %b2}"
14361   [(set_attr "type" "rotate")
14362    (set_attr "mode" "SI")])
14363
14364 (define_insn "*rotrsi3_1_zext"
14365   [(set (match_operand:DI 0 "register_operand" "=r,r")
14366         (zero_extend:DI
14367           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14368                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14369    (clobber (reg:CC FLAGS_REG))]
14370   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14371   "@
14372    ror{l}\t{%2, %k0|%k0, %2}
14373    ror{l}\t{%b2, %k0|%k0, %b2}"
14374   [(set_attr "type" "rotate")
14375    (set_attr "mode" "SI")])
14376
14377 (define_expand "rotrhi3"
14378   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14379         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
14380                      (match_operand:QI 2 "nonmemory_operand" "")))]
14381   "TARGET_HIMODE_MATH"
14382   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14383
14384 (define_insn "*rotrhi3_one_bit"
14385   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14386         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14387                      (match_operand:QI 2 "const1_operand" "")))
14388    (clobber (reg:CC FLAGS_REG))]
14389   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14390    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14391   "ror{w}\t%0"
14392   [(set_attr "type" "rotate")
14393    (set_attr "length_immediate" "0")
14394    (set_attr "mode" "HI")])
14395
14396 (define_insn "*rotrhi3_1"
14397   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14398         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14399                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14400    (clobber (reg:CC FLAGS_REG))]
14401   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14402   "@
14403    ror{w}\t{%2, %0|%0, %2}
14404    ror{w}\t{%b2, %0|%0, %b2}"
14405   [(set_attr "type" "rotate")
14406    (set_attr "mode" "HI")])
14407
14408 (define_split
14409  [(set (match_operand:HI 0 "register_operand" "")
14410        (rotatert:HI (match_dup 0) (const_int 8)))
14411   (clobber (reg:CC FLAGS_REG))]
14412  "reload_completed"
14413  [(parallel [(set (strict_low_part (match_dup 0))
14414                   (bswap:HI (match_dup 0)))
14415              (clobber (reg:CC FLAGS_REG))])]
14416  "")
14417
14418 (define_expand "rotrqi3"
14419   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14420         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
14421                      (match_operand:QI 2 "nonmemory_operand" "")))]
14422   "TARGET_QIMODE_MATH"
14423   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14424
14425 (define_insn "*rotrqi3_1_one_bit"
14426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14427         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14428                      (match_operand:QI 2 "const1_operand" "")))
14429    (clobber (reg:CC FLAGS_REG))]
14430   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14431    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14432   "ror{b}\t%0"
14433   [(set_attr "type" "rotate")
14434    (set_attr "length_immediate" "0")
14435    (set_attr "mode" "QI")])
14436
14437 (define_insn "*rotrqi3_1_one_bit_slp"
14438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14439         (rotatert:QI (match_dup 0)
14440                      (match_operand:QI 1 "const1_operand" "")))
14441    (clobber (reg:CC FLAGS_REG))]
14442   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14443    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14444   "ror{b}\t%0"
14445   [(set_attr "type" "rotate1")
14446    (set_attr "length_immediate" "0")
14447    (set_attr "mode" "QI")])
14448
14449 (define_insn "*rotrqi3_1"
14450   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14451         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14452                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14453    (clobber (reg:CC FLAGS_REG))]
14454   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14455   "@
14456    ror{b}\t{%2, %0|%0, %2}
14457    ror{b}\t{%b2, %0|%0, %b2}"
14458   [(set_attr "type" "rotate")
14459    (set_attr "mode" "QI")])
14460
14461 (define_insn "*rotrqi3_1_slp"
14462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14463         (rotatert:QI (match_dup 0)
14464                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
14465    (clobber (reg:CC FLAGS_REG))]
14466   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14467    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14468   "@
14469    ror{b}\t{%1, %0|%0, %1}
14470    ror{b}\t{%b1, %0|%0, %b1}"
14471   [(set_attr "type" "rotate1")
14472    (set_attr "mode" "QI")])
14473 \f
14474 ;; Bit set / bit test instructions
14475
14476 (define_expand "extv"
14477   [(set (match_operand:SI 0 "register_operand" "")
14478         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
14479                          (match_operand:SI 2 "const8_operand" "")
14480                          (match_operand:SI 3 "const8_operand" "")))]
14481   ""
14482 {
14483   /* Handle extractions from %ah et al.  */
14484   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14485     FAIL;
14486
14487   /* From mips.md: extract_bit_field doesn't verify that our source
14488      matches the predicate, so check it again here.  */
14489   if (! ext_register_operand (operands[1], VOIDmode))
14490     FAIL;
14491 })
14492
14493 (define_expand "extzv"
14494   [(set (match_operand:SI 0 "register_operand" "")
14495         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
14496                          (match_operand:SI 2 "const8_operand" "")
14497                          (match_operand:SI 3 "const8_operand" "")))]
14498   ""
14499 {
14500   /* Handle extractions from %ah et al.  */
14501   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14502     FAIL;
14503
14504   /* From mips.md: extract_bit_field doesn't verify that our source
14505      matches the predicate, so check it again here.  */
14506   if (! ext_register_operand (operands[1], VOIDmode))
14507     FAIL;
14508 })
14509
14510 (define_expand "insv"
14511   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
14512                       (match_operand 1 "const8_operand" "")
14513                       (match_operand 2 "const8_operand" ""))
14514         (match_operand 3 "register_operand" ""))]
14515   ""
14516 {
14517   /* Handle insertions to %ah et al.  */
14518   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14519     FAIL;
14520
14521   /* From mips.md: insert_bit_field doesn't verify that our source
14522      matches the predicate, so check it again here.  */
14523   if (! ext_register_operand (operands[0], VOIDmode))
14524     FAIL;
14525
14526   if (TARGET_64BIT)
14527     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14528   else
14529     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14530
14531   DONE;
14532 })
14533
14534 ;; %%% bts, btr, btc, bt.
14535 ;; In general these instructions are *slow* when applied to memory,
14536 ;; since they enforce atomic operation.  When applied to registers,
14537 ;; it depends on the cpu implementation.  They're never faster than
14538 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14539 ;; no point.  But in 64-bit, we can't hold the relevant immediates
14540 ;; within the instruction itself, so operating on bits in the high
14541 ;; 32-bits of a register becomes easier.
14542 ;;
14543 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
14544 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14545 ;; negdf respectively, so they can never be disabled entirely.
14546
14547 (define_insn "*btsq"
14548   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14549                          (const_int 1)
14550                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14551         (const_int 1))
14552    (clobber (reg:CC FLAGS_REG))]
14553   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14554   "bts{q}\t{%1, %0|%0, %1}"
14555   [(set_attr "type" "alu1")
14556    (set_attr "prefix_0f" "1")
14557    (set_attr "mode" "DI")])
14558
14559 (define_insn "*btrq"
14560   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14561                          (const_int 1)
14562                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14563         (const_int 0))
14564    (clobber (reg:CC FLAGS_REG))]
14565   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14566   "btr{q}\t{%1, %0|%0, %1}"
14567   [(set_attr "type" "alu1")
14568    (set_attr "prefix_0f" "1")
14569    (set_attr "mode" "DI")])
14570
14571 (define_insn "*btcq"
14572   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14573                          (const_int 1)
14574                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14575         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14576    (clobber (reg:CC FLAGS_REG))]
14577   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14578   "btc{q}\t{%1, %0|%0, %1}"
14579   [(set_attr "type" "alu1")
14580    (set_attr "prefix_0f" "1")
14581    (set_attr "mode" "DI")])
14582
14583 ;; Allow Nocona to avoid these instructions if a register is available.
14584
14585 (define_peephole2
14586   [(match_scratch:DI 2 "r")
14587    (parallel [(set (zero_extract:DI
14588                      (match_operand:DI 0 "register_operand" "")
14589                      (const_int 1)
14590                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14591                    (const_int 1))
14592               (clobber (reg:CC FLAGS_REG))])]
14593   "TARGET_64BIT && !TARGET_USE_BT"
14594   [(const_int 0)]
14595 {
14596   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14597   rtx op1;
14598
14599   if (HOST_BITS_PER_WIDE_INT >= 64)
14600     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14601   else if (i < HOST_BITS_PER_WIDE_INT)
14602     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14603   else
14604     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14605
14606   op1 = immed_double_const (lo, hi, DImode);
14607   if (i >= 31)
14608     {
14609       emit_move_insn (operands[2], op1);
14610       op1 = operands[2];
14611     }
14612
14613   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14614   DONE;
14615 })
14616
14617 (define_peephole2
14618   [(match_scratch:DI 2 "r")
14619    (parallel [(set (zero_extract:DI
14620                      (match_operand:DI 0 "register_operand" "")
14621                      (const_int 1)
14622                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14623                    (const_int 0))
14624               (clobber (reg:CC FLAGS_REG))])]
14625   "TARGET_64BIT && !TARGET_USE_BT"
14626   [(const_int 0)]
14627 {
14628   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14629   rtx op1;
14630
14631   if (HOST_BITS_PER_WIDE_INT >= 64)
14632     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14633   else if (i < HOST_BITS_PER_WIDE_INT)
14634     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14635   else
14636     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14637
14638   op1 = immed_double_const (~lo, ~hi, DImode);
14639   if (i >= 32)
14640     {
14641       emit_move_insn (operands[2], op1);
14642       op1 = operands[2];
14643     }
14644
14645   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14646   DONE;
14647 })
14648
14649 (define_peephole2
14650   [(match_scratch:DI 2 "r")
14651    (parallel [(set (zero_extract:DI
14652                      (match_operand:DI 0 "register_operand" "")
14653                      (const_int 1)
14654                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14655               (not:DI (zero_extract:DI
14656                         (match_dup 0) (const_int 1) (match_dup 1))))
14657               (clobber (reg:CC FLAGS_REG))])]
14658   "TARGET_64BIT && !TARGET_USE_BT"
14659   [(const_int 0)]
14660 {
14661   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14662   rtx op1;
14663
14664   if (HOST_BITS_PER_WIDE_INT >= 64)
14665     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14666   else if (i < HOST_BITS_PER_WIDE_INT)
14667     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14668   else
14669     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14670
14671   op1 = immed_double_const (lo, hi, DImode);
14672   if (i >= 31)
14673     {
14674       emit_move_insn (operands[2], op1);
14675       op1 = operands[2];
14676     }
14677
14678   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14679   DONE;
14680 })
14681
14682 (define_insn "*btdi_rex64"
14683   [(set (reg:CCC FLAGS_REG)
14684         (compare:CCC
14685           (zero_extract:DI
14686             (match_operand:DI 0 "register_operand" "r")
14687             (const_int 1)
14688             (match_operand:DI 1 "nonmemory_operand" "rN"))
14689           (const_int 0)))]
14690   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14691   "bt{q}\t{%1, %0|%0, %1}"
14692   [(set_attr "type" "alu1")
14693    (set_attr "prefix_0f" "1")
14694    (set_attr "mode" "DI")])
14695
14696 (define_insn "*btsi"
14697   [(set (reg:CCC FLAGS_REG)
14698         (compare:CCC
14699           (zero_extract:SI
14700             (match_operand:SI 0 "register_operand" "r")
14701             (const_int 1)
14702             (match_operand:SI 1 "nonmemory_operand" "rN"))
14703           (const_int 0)))]
14704   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14705   "bt{l}\t{%1, %0|%0, %1}"
14706   [(set_attr "type" "alu1")
14707    (set_attr "prefix_0f" "1")
14708    (set_attr "mode" "SI")])
14709 \f
14710 ;; Store-flag instructions.
14711
14712 ;; For all sCOND expanders, also expand the compare or test insn that
14713 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14714
14715 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14716 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14717 ;; way, which can later delete the movzx if only QImode is needed.
14718
14719 (define_insn "*setcc_1"
14720   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14721         (match_operator:QI 1 "ix86_comparison_operator"
14722           [(reg FLAGS_REG) (const_int 0)]))]
14723   ""
14724   "set%C1\t%0"
14725   [(set_attr "type" "setcc")
14726    (set_attr "mode" "QI")])
14727
14728 (define_insn "*setcc_2"
14729   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14730         (match_operator:QI 1 "ix86_comparison_operator"
14731           [(reg FLAGS_REG) (const_int 0)]))]
14732   ""
14733   "set%C1\t%0"
14734   [(set_attr "type" "setcc")
14735    (set_attr "mode" "QI")])
14736
14737 ;; In general it is not safe to assume too much about CCmode registers,
14738 ;; so simplify-rtx stops when it sees a second one.  Under certain
14739 ;; conditions this is safe on x86, so help combine not create
14740 ;;
14741 ;;      seta    %al
14742 ;;      testb   %al, %al
14743 ;;      sete    %al
14744
14745 (define_split
14746   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14747         (ne:QI (match_operator 1 "ix86_comparison_operator"
14748                  [(reg FLAGS_REG) (const_int 0)])
14749             (const_int 0)))]
14750   ""
14751   [(set (match_dup 0) (match_dup 1))]
14752 {
14753   PUT_MODE (operands[1], QImode);
14754 })
14755
14756 (define_split
14757   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14758         (ne:QI (match_operator 1 "ix86_comparison_operator"
14759                  [(reg FLAGS_REG) (const_int 0)])
14760             (const_int 0)))]
14761   ""
14762   [(set (match_dup 0) (match_dup 1))]
14763 {
14764   PUT_MODE (operands[1], QImode);
14765 })
14766
14767 (define_split
14768   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14769         (eq:QI (match_operator 1 "ix86_comparison_operator"
14770                  [(reg FLAGS_REG) (const_int 0)])
14771             (const_int 0)))]
14772   ""
14773   [(set (match_dup 0) (match_dup 1))]
14774 {
14775   rtx new_op1 = copy_rtx (operands[1]);
14776   operands[1] = new_op1;
14777   PUT_MODE (new_op1, QImode);
14778   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14779                                              GET_MODE (XEXP (new_op1, 0))));
14780
14781   /* Make sure that (a) the CCmode we have for the flags is strong
14782      enough for the reversed compare or (b) we have a valid FP compare.  */
14783   if (! ix86_comparison_operator (new_op1, VOIDmode))
14784     FAIL;
14785 })
14786
14787 (define_split
14788   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14789         (eq:QI (match_operator 1 "ix86_comparison_operator"
14790                  [(reg FLAGS_REG) (const_int 0)])
14791             (const_int 0)))]
14792   ""
14793   [(set (match_dup 0) (match_dup 1))]
14794 {
14795   rtx new_op1 = copy_rtx (operands[1]);
14796   operands[1] = new_op1;
14797   PUT_MODE (new_op1, QImode);
14798   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14799                                              GET_MODE (XEXP (new_op1, 0))));
14800
14801   /* Make sure that (a) the CCmode we have for the flags is strong
14802      enough for the reversed compare or (b) we have a valid FP compare.  */
14803   if (! ix86_comparison_operator (new_op1, VOIDmode))
14804     FAIL;
14805 })
14806
14807 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14808 ;; subsequent logical operations are used to imitate conditional moves.
14809 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14810 ;; it directly.
14811
14812 (define_insn "*avx_setcc<mode>"
14813   [(set (match_operand:MODEF 0 "register_operand" "=x")
14814         (match_operator:MODEF 1 "avx_comparison_float_operator"
14815           [(match_operand:MODEF 2 "register_operand" "x")
14816            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14817   "TARGET_AVX"
14818   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14819   [(set_attr "type" "ssecmp")
14820    (set_attr "prefix" "vex")
14821    (set_attr "length_immediate" "1")
14822    (set_attr "mode" "<MODE>")])
14823
14824 (define_insn "*sse_setcc<mode>"
14825   [(set (match_operand:MODEF 0 "register_operand" "=x")
14826         (match_operator:MODEF 1 "sse_comparison_operator"
14827           [(match_operand:MODEF 2 "register_operand" "0")
14828            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14829   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14830   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14831   [(set_attr "type" "ssecmp")
14832    (set_attr "length_immediate" "1")
14833    (set_attr "mode" "<MODE>")])
14834
14835 (define_insn "*sse5_setcc<mode>"
14836   [(set (match_operand:MODEF 0 "register_operand" "=x")
14837         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14838           [(match_operand:MODEF 2 "register_operand" "x")
14839            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14840   "TARGET_SSE5"
14841   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14842   [(set_attr "type" "sse4arg")
14843    (set_attr "length_immediate" "1")
14844    (set_attr "mode" "<MODE>")])
14845
14846 \f
14847 ;; Basic conditional jump instructions.
14848 ;; We ignore the overflow flag for signed branch instructions.
14849
14850 (define_insn "*jcc_1"
14851   [(set (pc)
14852         (if_then_else (match_operator 1 "ix86_comparison_operator"
14853                                       [(reg FLAGS_REG) (const_int 0)])
14854                       (label_ref (match_operand 0 "" ""))
14855                       (pc)))]
14856   ""
14857   "%+j%C1\t%l0"
14858   [(set_attr "type" "ibr")
14859    (set_attr "modrm" "0")
14860    (set (attr "length")
14861            (if_then_else (and (ge (minus (match_dup 0) (pc))
14862                                   (const_int -126))
14863                               (lt (minus (match_dup 0) (pc))
14864                                   (const_int 128)))
14865              (const_int 2)
14866              (const_int 6)))])
14867
14868 (define_insn "*jcc_2"
14869   [(set (pc)
14870         (if_then_else (match_operator 1 "ix86_comparison_operator"
14871                                       [(reg FLAGS_REG) (const_int 0)])
14872                       (pc)
14873                       (label_ref (match_operand 0 "" ""))))]
14874   ""
14875   "%+j%c1\t%l0"
14876   [(set_attr "type" "ibr")
14877    (set_attr "modrm" "0")
14878    (set (attr "length")
14879            (if_then_else (and (ge (minus (match_dup 0) (pc))
14880                                   (const_int -126))
14881                               (lt (minus (match_dup 0) (pc))
14882                                   (const_int 128)))
14883              (const_int 2)
14884              (const_int 6)))])
14885
14886 ;; In general it is not safe to assume too much about CCmode registers,
14887 ;; so simplify-rtx stops when it sees a second one.  Under certain
14888 ;; conditions this is safe on x86, so help combine not create
14889 ;;
14890 ;;      seta    %al
14891 ;;      testb   %al, %al
14892 ;;      je      Lfoo
14893
14894 (define_split
14895   [(set (pc)
14896         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14897                                       [(reg FLAGS_REG) (const_int 0)])
14898                           (const_int 0))
14899                       (label_ref (match_operand 1 "" ""))
14900                       (pc)))]
14901   ""
14902   [(set (pc)
14903         (if_then_else (match_dup 0)
14904                       (label_ref (match_dup 1))
14905                       (pc)))]
14906 {
14907   PUT_MODE (operands[0], VOIDmode);
14908 })
14909
14910 (define_split
14911   [(set (pc)
14912         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14913                                       [(reg FLAGS_REG) (const_int 0)])
14914                           (const_int 0))
14915                       (label_ref (match_operand 1 "" ""))
14916                       (pc)))]
14917   ""
14918   [(set (pc)
14919         (if_then_else (match_dup 0)
14920                       (label_ref (match_dup 1))
14921                       (pc)))]
14922 {
14923   rtx new_op0 = copy_rtx (operands[0]);
14924   operands[0] = new_op0;
14925   PUT_MODE (new_op0, VOIDmode);
14926   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14927                                              GET_MODE (XEXP (new_op0, 0))));
14928
14929   /* Make sure that (a) the CCmode we have for the flags is strong
14930      enough for the reversed compare or (b) we have a valid FP compare.  */
14931   if (! ix86_comparison_operator (new_op0, VOIDmode))
14932     FAIL;
14933 })
14934
14935 ;; zero_extend in SImode is correct, since this is what combine pass
14936 ;; generates from shift insn with QImode operand.  Actually, the mode of
14937 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14938 ;; appropriate modulo of the bit offset value.
14939
14940 (define_insn_and_split "*jcc_btdi_rex64"
14941   [(set (pc)
14942         (if_then_else (match_operator 0 "bt_comparison_operator"
14943                         [(zero_extract:DI
14944                            (match_operand:DI 1 "register_operand" "r")
14945                            (const_int 1)
14946                            (zero_extend:SI
14947                              (match_operand:QI 2 "register_operand" "r")))
14948                          (const_int 0)])
14949                       (label_ref (match_operand 3 "" ""))
14950                       (pc)))
14951    (clobber (reg:CC FLAGS_REG))]
14952   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14953   "#"
14954   "&& 1"
14955   [(set (reg:CCC FLAGS_REG)
14956         (compare:CCC
14957           (zero_extract:DI
14958             (match_dup 1)
14959             (const_int 1)
14960             (match_dup 2))
14961           (const_int 0)))
14962    (set (pc)
14963         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14964                       (label_ref (match_dup 3))
14965                       (pc)))]
14966 {
14967   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14968
14969   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14970 })
14971
14972 ;; avoid useless masking of bit offset operand
14973 (define_insn_and_split "*jcc_btdi_mask_rex64"
14974   [(set (pc)
14975         (if_then_else (match_operator 0 "bt_comparison_operator"
14976                         [(zero_extract:DI
14977                            (match_operand:DI 1 "register_operand" "r")
14978                            (const_int 1)
14979                            (and:SI
14980                              (match_operand:SI 2 "register_operand" "r")
14981                              (match_operand:SI 3 "const_int_operand" "n")))])
14982                       (label_ref (match_operand 4 "" ""))
14983                       (pc)))
14984    (clobber (reg:CC FLAGS_REG))]
14985   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14986    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14987   "#"
14988   "&& 1"
14989   [(set (reg:CCC FLAGS_REG)
14990         (compare:CCC
14991           (zero_extract:DI
14992             (match_dup 1)
14993             (const_int 1)
14994             (match_dup 2))
14995           (const_int 0)))
14996    (set (pc)
14997         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14998                       (label_ref (match_dup 4))
14999                       (pc)))]
15000 {
15001   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
15002
15003   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15004 })
15005
15006 (define_insn_and_split "*jcc_btsi"
15007   [(set (pc)
15008         (if_then_else (match_operator 0 "bt_comparison_operator"
15009                         [(zero_extract:SI
15010                            (match_operand:SI 1 "register_operand" "r")
15011                            (const_int 1)
15012                            (zero_extend:SI
15013                              (match_operand:QI 2 "register_operand" "r")))
15014                          (const_int 0)])
15015                       (label_ref (match_operand 3 "" ""))
15016                       (pc)))
15017    (clobber (reg:CC FLAGS_REG))]
15018   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15019   "#"
15020   "&& 1"
15021   [(set (reg:CCC FLAGS_REG)
15022         (compare:CCC
15023           (zero_extract:SI
15024             (match_dup 1)
15025             (const_int 1)
15026             (match_dup 2))
15027           (const_int 0)))
15028    (set (pc)
15029         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15030                       (label_ref (match_dup 3))
15031                       (pc)))]
15032 {
15033   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15034
15035   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15036 })
15037
15038 ;; avoid useless masking of bit offset operand
15039 (define_insn_and_split "*jcc_btsi_mask"
15040   [(set (pc)
15041         (if_then_else (match_operator 0 "bt_comparison_operator"
15042                         [(zero_extract:SI
15043                            (match_operand:SI 1 "register_operand" "r")
15044                            (const_int 1)
15045                            (and:SI
15046                              (match_operand:SI 2 "register_operand" "r")
15047                              (match_operand:SI 3 "const_int_operand" "n")))])
15048                       (label_ref (match_operand 4 "" ""))
15049                       (pc)))
15050    (clobber (reg:CC FLAGS_REG))]
15051   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15052    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15053   "#"
15054   "&& 1"
15055   [(set (reg:CCC FLAGS_REG)
15056         (compare:CCC
15057           (zero_extract:SI
15058             (match_dup 1)
15059             (const_int 1)
15060             (match_dup 2))
15061           (const_int 0)))
15062    (set (pc)
15063         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15064                       (label_ref (match_dup 4))
15065                       (pc)))]
15066   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15067
15068 (define_insn_and_split "*jcc_btsi_1"
15069   [(set (pc)
15070         (if_then_else (match_operator 0 "bt_comparison_operator"
15071                         [(and:SI
15072                            (lshiftrt:SI
15073                              (match_operand:SI 1 "register_operand" "r")
15074                              (match_operand:QI 2 "register_operand" "r"))
15075                            (const_int 1))
15076                          (const_int 0)])
15077                       (label_ref (match_operand 3 "" ""))
15078                       (pc)))
15079    (clobber (reg:CC FLAGS_REG))]
15080   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15081   "#"
15082   "&& 1"
15083   [(set (reg:CCC FLAGS_REG)
15084         (compare:CCC
15085           (zero_extract:SI
15086             (match_dup 1)
15087             (const_int 1)
15088             (match_dup 2))
15089           (const_int 0)))
15090    (set (pc)
15091         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15092                       (label_ref (match_dup 3))
15093                       (pc)))]
15094 {
15095   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15096
15097   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15098 })
15099
15100 ;; avoid useless masking of bit offset operand
15101 (define_insn_and_split "*jcc_btsi_mask_1"
15102   [(set (pc)
15103         (if_then_else
15104           (match_operator 0 "bt_comparison_operator"
15105             [(and:SI
15106                (lshiftrt:SI
15107                  (match_operand:SI 1 "register_operand" "r")
15108                  (subreg:QI
15109                    (and:SI
15110                      (match_operand:SI 2 "register_operand" "r")
15111                      (match_operand:SI 3 "const_int_operand" "n")) 0))
15112                (const_int 1))
15113              (const_int 0)])
15114           (label_ref (match_operand 4 "" ""))
15115           (pc)))
15116    (clobber (reg:CC FLAGS_REG))]
15117   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15118    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15119   "#"
15120   "&& 1"
15121   [(set (reg:CCC FLAGS_REG)
15122         (compare:CCC
15123           (zero_extract:SI
15124             (match_dup 1)
15125             (const_int 1)
15126             (match_dup 2))
15127           (const_int 0)))
15128    (set (pc)
15129         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15130                       (label_ref (match_dup 4))
15131                       (pc)))]
15132   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15133
15134 ;; Define combination compare-and-branch fp compare instructions to help
15135 ;; combine.
15136
15137 (define_insn "*fp_jcc_3_387"
15138   [(set (pc)
15139         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15140                         [(match_operand 1 "register_operand" "f")
15141                          (match_operand 2 "nonimmediate_operand" "fm")])
15142           (label_ref (match_operand 3 "" ""))
15143           (pc)))
15144    (clobber (reg:CCFP FPSR_REG))
15145    (clobber (reg:CCFP FLAGS_REG))
15146    (clobber (match_scratch:HI 4 "=a"))]
15147   "TARGET_80387
15148    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15149    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15150    && SELECT_CC_MODE (GET_CODE (operands[0]),
15151                       operands[1], operands[2]) == CCFPmode
15152    && !TARGET_CMOVE"
15153   "#")
15154
15155 (define_insn "*fp_jcc_4_387"
15156   [(set (pc)
15157         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15158                         [(match_operand 1 "register_operand" "f")
15159                          (match_operand 2 "nonimmediate_operand" "fm")])
15160           (pc)
15161           (label_ref (match_operand 3 "" ""))))
15162    (clobber (reg:CCFP FPSR_REG))
15163    (clobber (reg:CCFP FLAGS_REG))
15164    (clobber (match_scratch:HI 4 "=a"))]
15165   "TARGET_80387
15166    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15167    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15168    && SELECT_CC_MODE (GET_CODE (operands[0]),
15169                       operands[1], operands[2]) == CCFPmode
15170    && !TARGET_CMOVE"
15171   "#")
15172
15173 (define_insn "*fp_jcc_5_387"
15174   [(set (pc)
15175         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15176                         [(match_operand 1 "register_operand" "f")
15177                          (match_operand 2 "register_operand" "f")])
15178           (label_ref (match_operand 3 "" ""))
15179           (pc)))
15180    (clobber (reg:CCFP FPSR_REG))
15181    (clobber (reg:CCFP FLAGS_REG))
15182    (clobber (match_scratch:HI 4 "=a"))]
15183   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15184    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15185    && !TARGET_CMOVE"
15186   "#")
15187
15188 (define_insn "*fp_jcc_6_387"
15189   [(set (pc)
15190         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15191                         [(match_operand 1 "register_operand" "f")
15192                          (match_operand 2 "register_operand" "f")])
15193           (pc)
15194           (label_ref (match_operand 3 "" ""))))
15195    (clobber (reg:CCFP FPSR_REG))
15196    (clobber (reg:CCFP FLAGS_REG))
15197    (clobber (match_scratch:HI 4 "=a"))]
15198   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15199    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15200    && !TARGET_CMOVE"
15201   "#")
15202
15203 (define_insn "*fp_jcc_7_387"
15204   [(set (pc)
15205         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15206                         [(match_operand 1 "register_operand" "f")
15207                          (match_operand 2 "const0_operand" "")])
15208           (label_ref (match_operand 3 "" ""))
15209           (pc)))
15210    (clobber (reg:CCFP FPSR_REG))
15211    (clobber (reg:CCFP FLAGS_REG))
15212    (clobber (match_scratch:HI 4 "=a"))]
15213   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15214    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15215    && SELECT_CC_MODE (GET_CODE (operands[0]),
15216                       operands[1], operands[2]) == CCFPmode
15217    && !TARGET_CMOVE"
15218   "#")
15219
15220 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
15221 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
15222 ;; with a precedence over other operators and is always put in the first
15223 ;; place. Swap condition and operands to match ficom instruction.
15224
15225 (define_insn "*fp_jcc_8<mode>_387"
15226   [(set (pc)
15227         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15228                         [(match_operator 1 "float_operator"
15229                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
15230                            (match_operand 3 "register_operand" "f,f")])
15231           (label_ref (match_operand 4 "" ""))
15232           (pc)))
15233    (clobber (reg:CCFP FPSR_REG))
15234    (clobber (reg:CCFP FLAGS_REG))
15235    (clobber (match_scratch:HI 5 "=a,a"))]
15236   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
15237    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
15238    && GET_MODE (operands[1]) == GET_MODE (operands[3])
15239    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
15240    && !TARGET_CMOVE"
15241   "#")
15242
15243 (define_split
15244   [(set (pc)
15245         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15246                         [(match_operand 1 "register_operand" "")
15247                          (match_operand 2 "nonimmediate_operand" "")])
15248           (match_operand 3 "" "")
15249           (match_operand 4 "" "")))
15250    (clobber (reg:CCFP FPSR_REG))
15251    (clobber (reg:CCFP FLAGS_REG))]
15252   "reload_completed"
15253   [(const_int 0)]
15254 {
15255   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15256                         operands[3], operands[4], NULL_RTX, NULL_RTX);
15257   DONE;
15258 })
15259
15260 (define_split
15261   [(set (pc)
15262         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15263                         [(match_operand 1 "register_operand" "")
15264                          (match_operand 2 "general_operand" "")])
15265           (match_operand 3 "" "")
15266           (match_operand 4 "" "")))
15267    (clobber (reg:CCFP FPSR_REG))
15268    (clobber (reg:CCFP FLAGS_REG))
15269    (clobber (match_scratch:HI 5 "=a"))]
15270   "reload_completed"
15271   [(const_int 0)]
15272 {
15273   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15274                         operands[3], operands[4], operands[5], NULL_RTX);
15275   DONE;
15276 })
15277
15278 (define_split
15279   [(set (pc)
15280         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15281                         [(match_operator 1 "float_operator"
15282                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
15283                            (match_operand 3 "register_operand" "")])
15284           (match_operand 4 "" "")
15285           (match_operand 5 "" "")))
15286    (clobber (reg:CCFP FPSR_REG))
15287    (clobber (reg:CCFP FLAGS_REG))
15288    (clobber (match_scratch:HI 6 "=a"))]
15289   "reload_completed"
15290   [(const_int 0)]
15291 {
15292   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15293   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15294                         operands[3], operands[7],
15295                         operands[4], operands[5], operands[6], NULL_RTX);
15296   DONE;
15297 })
15298
15299 ;; %%% Kill this when reload knows how to do it.
15300 (define_split
15301   [(set (pc)
15302         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15303                         [(match_operator 1 "float_operator"
15304                            [(match_operand:X87MODEI12 2 "register_operand" "")])
15305                            (match_operand 3 "register_operand" "")])
15306           (match_operand 4 "" "")
15307           (match_operand 5 "" "")))
15308    (clobber (reg:CCFP FPSR_REG))
15309    (clobber (reg:CCFP FLAGS_REG))
15310    (clobber (match_scratch:HI 6 "=a"))]
15311   "reload_completed"
15312   [(const_int 0)]
15313 {
15314   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15315   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15316   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15317                         operands[3], operands[7],
15318                         operands[4], operands[5], operands[6], operands[2]);
15319   DONE;
15320 })
15321 \f
15322 ;; Unconditional and other jump instructions
15323
15324 (define_insn "jump"
15325   [(set (pc)
15326         (label_ref (match_operand 0 "" "")))]
15327   ""
15328   "jmp\t%l0"
15329   [(set_attr "type" "ibr")
15330    (set (attr "length")
15331            (if_then_else (and (ge (minus (match_dup 0) (pc))
15332                                   (const_int -126))
15333                               (lt (minus (match_dup 0) (pc))
15334                                   (const_int 128)))
15335              (const_int 2)
15336              (const_int 5)))
15337    (set_attr "modrm" "0")])
15338
15339 (define_expand "indirect_jump"
15340   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
15341   ""
15342   "")
15343
15344 (define_insn "*indirect_jump"
15345   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15346   ""
15347   "jmp\t%A0"
15348   [(set_attr "type" "ibr")
15349    (set_attr "length_immediate" "0")])
15350
15351 (define_expand "tablejump"
15352   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
15353               (use (label_ref (match_operand 1 "" "")))])]
15354   ""
15355 {
15356   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15357      relative.  Convert the relative address to an absolute address.  */
15358   if (flag_pic)
15359     {
15360       rtx op0, op1;
15361       enum rtx_code code;
15362
15363       /* We can't use @GOTOFF for text labels on VxWorks;
15364          see gotoff_operand.  */
15365       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15366         {
15367           code = PLUS;
15368           op0 = operands[0];
15369           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15370         }
15371       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
15372         {
15373           code = PLUS;
15374           op0 = operands[0];
15375           op1 = pic_offset_table_rtx;
15376         }
15377       else
15378         {
15379           code = MINUS;
15380           op0 = pic_offset_table_rtx;
15381           op1 = operands[0];
15382         }
15383
15384       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
15385                                          OPTAB_DIRECT);
15386     }
15387 })
15388
15389 (define_insn "*tablejump_1"
15390   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
15391    (use (label_ref (match_operand 1 "" "")))]
15392   ""
15393   "jmp\t%A0"
15394   [(set_attr "type" "ibr")
15395    (set_attr "length_immediate" "0")])
15396 \f
15397 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15398
15399 (define_peephole2
15400   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15401    (set (match_operand:QI 1 "register_operand" "")
15402         (match_operator:QI 2 "ix86_comparison_operator"
15403           [(reg FLAGS_REG) (const_int 0)]))
15404    (set (match_operand 3 "q_regs_operand" "")
15405         (zero_extend (match_dup 1)))]
15406   "(peep2_reg_dead_p (3, operands[1])
15407     || operands_match_p (operands[1], operands[3]))
15408    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15409   [(set (match_dup 4) (match_dup 0))
15410    (set (strict_low_part (match_dup 5))
15411         (match_dup 2))]
15412 {
15413   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15414   operands[5] = gen_lowpart (QImode, operands[3]);
15415   ix86_expand_clear (operands[3]);
15416 })
15417
15418 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15419
15420 (define_peephole2
15421   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15422    (set (match_operand:QI 1 "register_operand" "")
15423         (match_operator:QI 2 "ix86_comparison_operator"
15424           [(reg FLAGS_REG) (const_int 0)]))
15425    (parallel [(set (match_operand 3 "q_regs_operand" "")
15426                    (zero_extend (match_dup 1)))
15427               (clobber (reg:CC FLAGS_REG))])]
15428   "(peep2_reg_dead_p (3, operands[1])
15429     || operands_match_p (operands[1], operands[3]))
15430    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15431   [(set (match_dup 4) (match_dup 0))
15432    (set (strict_low_part (match_dup 5))
15433         (match_dup 2))]
15434 {
15435   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15436   operands[5] = gen_lowpart (QImode, operands[3]);
15437   ix86_expand_clear (operands[3]);
15438 })
15439 \f
15440 ;; Call instructions.
15441
15442 ;; The predicates normally associated with named expanders are not properly
15443 ;; checked for calls.  This is a bug in the generic code, but it isn't that
15444 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
15445
15446 ;; Call subroutine returning no value.
15447
15448 (define_expand "call_pop"
15449   [(parallel [(call (match_operand:QI 0 "" "")
15450                     (match_operand:SI 1 "" ""))
15451               (set (reg:SI SP_REG)
15452                    (plus:SI (reg:SI SP_REG)
15453                             (match_operand:SI 3 "" "")))])]
15454   "!TARGET_64BIT"
15455 {
15456   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15457   DONE;
15458 })
15459
15460 (define_insn "*call_pop_0"
15461   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15462          (match_operand:SI 1 "" ""))
15463    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15464                             (match_operand:SI 2 "immediate_operand" "")))]
15465   "!TARGET_64BIT"
15466 {
15467   if (SIBLING_CALL_P (insn))
15468     return "jmp\t%P0";
15469   else
15470     return "call\t%P0";
15471 }
15472   [(set_attr "type" "call")])
15473
15474 (define_insn "*call_pop_1"
15475   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15476          (match_operand:SI 1 "" ""))
15477    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15478                             (match_operand:SI 2 "immediate_operand" "i")))]
15479   "!TARGET_64BIT"
15480 {
15481   if (constant_call_address_operand (operands[0], Pmode))
15482     {
15483       if (SIBLING_CALL_P (insn))
15484         return "jmp\t%P0";
15485       else
15486         return "call\t%P0";
15487     }
15488   if (SIBLING_CALL_P (insn))
15489     return "jmp\t%A0";
15490   else
15491     return "call\t%A0";
15492 }
15493   [(set_attr "type" "call")])
15494
15495 (define_expand "call"
15496   [(call (match_operand:QI 0 "" "")
15497          (match_operand 1 "" ""))
15498    (use (match_operand 2 "" ""))]
15499   ""
15500 {
15501   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15502   DONE;
15503 })
15504
15505 (define_expand "sibcall"
15506   [(call (match_operand:QI 0 "" "")
15507          (match_operand 1 "" ""))
15508    (use (match_operand 2 "" ""))]
15509   ""
15510 {
15511   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15512   DONE;
15513 })
15514
15515 (define_insn "*call_0"
15516   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15517          (match_operand 1 "" ""))]
15518   ""
15519 {
15520   if (SIBLING_CALL_P (insn))
15521     return "jmp\t%P0";
15522   else
15523     return "call\t%P0";
15524 }
15525   [(set_attr "type" "call")])
15526
15527 (define_insn "*call_1"
15528   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15529          (match_operand 1 "" ""))]
15530   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15531 {
15532   if (constant_call_address_operand (operands[0], Pmode))
15533     return "call\t%P0";
15534   return "call\t%A0";
15535 }
15536   [(set_attr "type" "call")])
15537
15538 (define_insn "*sibcall_1"
15539   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15540          (match_operand 1 "" ""))]
15541   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15542 {
15543   if (constant_call_address_operand (operands[0], Pmode))
15544     return "jmp\t%P0";
15545   return "jmp\t%A0";
15546 }
15547   [(set_attr "type" "call")])
15548
15549 (define_insn "*call_1_rex64"
15550   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15551          (match_operand 1 "" ""))]
15552   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15553    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15554 {
15555   if (constant_call_address_operand (operands[0], Pmode))
15556     return "call\t%P0";
15557   return "call\t%A0";
15558 }
15559   [(set_attr "type" "call")])
15560
15561 (define_insn "*call_1_rex64_ms_sysv"
15562   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15563          (match_operand 1 "" ""))
15564    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15565    (clobber (reg:TI XMM6_REG))
15566    (clobber (reg:TI XMM7_REG))
15567    (clobber (reg:TI XMM8_REG))
15568    (clobber (reg:TI XMM9_REG))
15569    (clobber (reg:TI XMM10_REG))
15570    (clobber (reg:TI XMM11_REG))
15571    (clobber (reg:TI XMM12_REG))
15572    (clobber (reg:TI XMM13_REG))
15573    (clobber (reg:TI XMM14_REG))
15574    (clobber (reg:TI XMM15_REG))
15575    (clobber (reg:DI SI_REG))
15576    (clobber (reg:DI DI_REG))]
15577   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15578 {
15579   if (constant_call_address_operand (operands[0], Pmode))
15580     return "call\t%P0";
15581   return "call\t%A0";
15582 }
15583   [(set_attr "type" "call")])
15584
15585 (define_insn "*call_1_rex64_large"
15586   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15587          (match_operand 1 "" ""))]
15588   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15589   "call\t%A0"
15590   [(set_attr "type" "call")])
15591
15592 (define_insn "*sibcall_1_rex64"
15593   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15594          (match_operand 1 "" ""))]
15595   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15596   "jmp\t%P0"
15597   [(set_attr "type" "call")])
15598
15599 (define_insn "*sibcall_1_rex64_v"
15600   [(call (mem:QI (reg:DI R11_REG))
15601          (match_operand 0 "" ""))]
15602   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15603   "jmp\t{*%%}r11"
15604   [(set_attr "type" "call")])
15605
15606
15607 ;; Call subroutine, returning value in operand 0
15608
15609 (define_expand "call_value_pop"
15610   [(parallel [(set (match_operand 0 "" "")
15611                    (call (match_operand:QI 1 "" "")
15612                          (match_operand:SI 2 "" "")))
15613               (set (reg:SI SP_REG)
15614                    (plus:SI (reg:SI SP_REG)
15615                             (match_operand:SI 4 "" "")))])]
15616   "!TARGET_64BIT"
15617 {
15618   ix86_expand_call (operands[0], operands[1], operands[2],
15619                     operands[3], operands[4], 0);
15620   DONE;
15621 })
15622
15623 (define_expand "call_value"
15624   [(set (match_operand 0 "" "")
15625         (call (match_operand:QI 1 "" "")
15626               (match_operand:SI 2 "" "")))
15627    (use (match_operand:SI 3 "" ""))]
15628   ;; Operand 2 not used on the i386.
15629   ""
15630 {
15631   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15632   DONE;
15633 })
15634
15635 (define_expand "sibcall_value"
15636   [(set (match_operand 0 "" "")
15637         (call (match_operand:QI 1 "" "")
15638               (match_operand:SI 2 "" "")))
15639    (use (match_operand:SI 3 "" ""))]
15640   ;; Operand 2 not used on the i386.
15641   ""
15642 {
15643   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15644   DONE;
15645 })
15646
15647 ;; Call subroutine returning any type.
15648
15649 (define_expand "untyped_call"
15650   [(parallel [(call (match_operand 0 "" "")
15651                     (const_int 0))
15652               (match_operand 1 "" "")
15653               (match_operand 2 "" "")])]
15654   ""
15655 {
15656   int i;
15657
15658   /* In order to give reg-stack an easier job in validating two
15659      coprocessor registers as containing a possible return value,
15660      simply pretend the untyped call returns a complex long double
15661      value. 
15662
15663      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15664      and should have the default ABI.  */
15665
15666   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15667                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15668                     operands[0], const0_rtx,
15669                     GEN_INT ((TARGET_64BIT
15670                               ? (ix86_abi == SYSV_ABI
15671                                  ? X86_64_SSE_REGPARM_MAX
15672                                  : X86_64_MS_SSE_REGPARM_MAX)
15673                               : X86_32_SSE_REGPARM_MAX)
15674                              - 1),
15675                     NULL, 0);
15676
15677   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15678     {
15679       rtx set = XVECEXP (operands[2], 0, i);
15680       emit_move_insn (SET_DEST (set), SET_SRC (set));
15681     }
15682
15683   /* The optimizer does not know that the call sets the function value
15684      registers we stored in the result block.  We avoid problems by
15685      claiming that all hard registers are used and clobbered at this
15686      point.  */
15687   emit_insn (gen_blockage ());
15688
15689   DONE;
15690 })
15691 \f
15692 ;; Prologue and epilogue instructions
15693
15694 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15695 ;; all of memory.  This blocks insns from being moved across this point.
15696
15697 (define_insn "blockage"
15698   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15699   ""
15700   ""
15701   [(set_attr "length" "0")])
15702
15703 ;; Do not schedule instructions accessing memory across this point.
15704
15705 (define_expand "memory_blockage"
15706   [(set (match_dup 0)
15707         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15708   ""
15709 {
15710   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15711   MEM_VOLATILE_P (operands[0]) = 1;
15712 })
15713
15714 (define_insn "*memory_blockage"
15715   [(set (match_operand:BLK 0 "" "")
15716         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15717   ""
15718   ""
15719   [(set_attr "length" "0")])
15720
15721 ;; As USE insns aren't meaningful after reload, this is used instead
15722 ;; to prevent deleting instructions setting registers for PIC code
15723 (define_insn "prologue_use"
15724   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15725   ""
15726   ""
15727   [(set_attr "length" "0")])
15728
15729 ;; Insn emitted into the body of a function to return from a function.
15730 ;; This is only done if the function's epilogue is known to be simple.
15731 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15732
15733 (define_expand "return"
15734   [(return)]
15735   "ix86_can_use_return_insn_p ()"
15736 {
15737   if (crtl->args.pops_args)
15738     {
15739       rtx popc = GEN_INT (crtl->args.pops_args);
15740       emit_jump_insn (gen_return_pop_internal (popc));
15741       DONE;
15742     }
15743 })
15744
15745 (define_insn "return_internal"
15746   [(return)]
15747   "reload_completed"
15748   "ret"
15749   [(set_attr "length" "1")
15750    (set_attr "atom_unit" "jeu")
15751    (set_attr "length_immediate" "0")
15752    (set_attr "modrm" "0")])
15753
15754 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15755 ;; instruction Athlon and K8 have.
15756
15757 (define_insn "return_internal_long"
15758   [(return)
15759    (unspec [(const_int 0)] UNSPEC_REP)]
15760   "reload_completed"
15761   "rep\;ret"
15762   [(set_attr "length" "2")
15763    (set_attr "atom_unit" "jeu")
15764    (set_attr "length_immediate" "0")
15765    (set_attr "prefix_rep" "1")
15766    (set_attr "modrm" "0")])
15767
15768 (define_insn "return_pop_internal"
15769   [(return)
15770    (use (match_operand:SI 0 "const_int_operand" ""))]
15771   "reload_completed"
15772   "ret\t%0"
15773   [(set_attr "length" "3")
15774    (set_attr "atom_unit" "jeu")
15775    (set_attr "length_immediate" "2")
15776    (set_attr "modrm" "0")])
15777
15778 (define_insn "return_indirect_internal"
15779   [(return)
15780    (use (match_operand:SI 0 "register_operand" "r"))]
15781   "reload_completed"
15782   "jmp\t%A0"
15783   [(set_attr "type" "ibr")
15784    (set_attr "length_immediate" "0")])
15785
15786 (define_insn "nop"
15787   [(const_int 0)]
15788   ""
15789   "nop"
15790   [(set_attr "length" "1")
15791    (set_attr "length_immediate" "0")
15792    (set_attr "modrm" "0")])
15793
15794 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
15795 ;; branch prediction penalty for the third jump in a 16-byte
15796 ;; block on K8.
15797
15798 (define_insn "pad"
15799   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15800   ""
15801 {
15802 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15803   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15804 #else
15805   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15806      The align insn is used to avoid 3 jump instructions in the row to improve
15807      branch prediction and the benefits hardly outweigh the cost of extra 8
15808      nops on the average inserted by full alignment pseudo operation.  */
15809 #endif
15810   return "";
15811 }
15812   [(set_attr "length" "16")])
15813
15814 (define_expand "prologue"
15815   [(const_int 0)]
15816   ""
15817   "ix86_expand_prologue (); DONE;")
15818
15819 (define_insn "set_got"
15820   [(set (match_operand:SI 0 "register_operand" "=r")
15821         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15822    (clobber (reg:CC FLAGS_REG))]
15823   "!TARGET_64BIT"
15824   { return output_set_got (operands[0], NULL_RTX); }
15825   [(set_attr "type" "multi")
15826    (set_attr "length" "12")])
15827
15828 (define_insn "set_got_labelled"
15829   [(set (match_operand:SI 0 "register_operand" "=r")
15830         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15831          UNSPEC_SET_GOT))
15832    (clobber (reg:CC FLAGS_REG))]
15833   "!TARGET_64BIT"
15834   { return output_set_got (operands[0], operands[1]); }
15835   [(set_attr "type" "multi")
15836    (set_attr "length" "12")])
15837
15838 (define_insn "set_got_rex64"
15839   [(set (match_operand:DI 0 "register_operand" "=r")
15840         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15841   "TARGET_64BIT"
15842   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15843   [(set_attr "type" "lea")
15844    (set_attr "length_address" "4")
15845    (set_attr "mode" "DI")])
15846
15847 (define_insn "set_rip_rex64"
15848   [(set (match_operand:DI 0 "register_operand" "=r")
15849         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15850   "TARGET_64BIT"
15851   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15852   [(set_attr "type" "lea")
15853    (set_attr "length_address" "4")
15854    (set_attr "mode" "DI")])
15855
15856 (define_insn "set_got_offset_rex64"
15857   [(set (match_operand:DI 0 "register_operand" "=r")
15858         (unspec:DI
15859           [(label_ref (match_operand 1 "" ""))]
15860           UNSPEC_SET_GOT_OFFSET))]
15861   "TARGET_64BIT"
15862   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15863   [(set_attr "type" "imov")
15864    (set_attr "length_immediate" "0")
15865    (set_attr "length_address" "8")
15866    (set_attr "mode" "DI")])
15867
15868 (define_expand "epilogue"
15869   [(const_int 0)]
15870   ""
15871   "ix86_expand_epilogue (1); DONE;")
15872
15873 (define_expand "sibcall_epilogue"
15874   [(const_int 0)]
15875   ""
15876   "ix86_expand_epilogue (0); DONE;")
15877
15878 (define_expand "eh_return"
15879   [(use (match_operand 0 "register_operand" ""))]
15880   ""
15881 {
15882   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15883
15884   /* Tricky bit: we write the address of the handler to which we will
15885      be returning into someone else's stack frame, one word below the
15886      stack address we wish to restore.  */
15887   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15888   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15889   tmp = gen_rtx_MEM (Pmode, tmp);
15890   emit_move_insn (tmp, ra);
15891
15892   emit_jump_insn (gen_eh_return_internal ());
15893   emit_barrier ();
15894   DONE;
15895 })
15896
15897 (define_insn_and_split "eh_return_internal"
15898   [(eh_return)]
15899   ""
15900   "#"
15901   "epilogue_completed"
15902   [(const_int 0)]
15903   "ix86_expand_epilogue (2); DONE;")
15904
15905 (define_insn "leave"
15906   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15907    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15908    (clobber (mem:BLK (scratch)))]
15909   "!TARGET_64BIT"
15910   "leave"
15911   [(set_attr "type" "leave")])
15912
15913 (define_insn "leave_rex64"
15914   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15915    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15916    (clobber (mem:BLK (scratch)))]
15917   "TARGET_64BIT"
15918   "leave"
15919   [(set_attr "type" "leave")])
15920 \f
15921 (define_expand "ffssi2"
15922   [(parallel
15923      [(set (match_operand:SI 0 "register_operand" "")
15924            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15925       (clobber (match_scratch:SI 2 ""))
15926       (clobber (reg:CC FLAGS_REG))])]
15927   ""
15928 {
15929   if (TARGET_CMOVE)
15930     {
15931       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15932       DONE;
15933     }
15934 })
15935
15936 (define_expand "ffs_cmove"
15937   [(set (match_dup 2) (const_int -1))
15938    (parallel [(set (reg:CCZ FLAGS_REG)
15939                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15940                                 (const_int 0)))
15941               (set (match_operand:SI 0 "register_operand" "")
15942                    (ctz:SI (match_dup 1)))])
15943    (set (match_dup 0) (if_then_else:SI
15944                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15945                         (match_dup 2)
15946                         (match_dup 0)))
15947    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15948               (clobber (reg:CC FLAGS_REG))])]
15949   "TARGET_CMOVE"
15950   "operands[2] = gen_reg_rtx (SImode);")
15951
15952 (define_insn_and_split "*ffs_no_cmove"
15953   [(set (match_operand:SI 0 "register_operand" "=r")
15954         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15955    (clobber (match_scratch:SI 2 "=&q"))
15956    (clobber (reg:CC FLAGS_REG))]
15957   "!TARGET_CMOVE"
15958   "#"
15959   "&& reload_completed"
15960   [(parallel [(set (reg:CCZ FLAGS_REG)
15961                    (compare:CCZ (match_dup 1) (const_int 0)))
15962               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15963    (set (strict_low_part (match_dup 3))
15964         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15965    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15966               (clobber (reg:CC FLAGS_REG))])
15967    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15968               (clobber (reg:CC FLAGS_REG))])
15969    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15970               (clobber (reg:CC FLAGS_REG))])]
15971 {
15972   operands[3] = gen_lowpart (QImode, operands[2]);
15973   ix86_expand_clear (operands[2]);
15974 })
15975
15976 (define_insn "*ffssi_1"
15977   [(set (reg:CCZ FLAGS_REG)
15978         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15979                      (const_int 0)))
15980    (set (match_operand:SI 0 "register_operand" "=r")
15981         (ctz:SI (match_dup 1)))]
15982   ""
15983   "bsf{l}\t{%1, %0|%0, %1}"
15984   [(set_attr "type" "alu1")
15985    (set_attr "prefix_0f" "1")
15986    (set_attr "mode" "SI")])
15987
15988 (define_expand "ffsdi2"
15989   [(set (match_dup 2) (const_int -1))
15990    (parallel [(set (reg:CCZ FLAGS_REG)
15991                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15992                                 (const_int 0)))
15993               (set (match_operand:DI 0 "register_operand" "")
15994                    (ctz:DI (match_dup 1)))])
15995    (set (match_dup 0) (if_then_else:DI
15996                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15997                         (match_dup 2)
15998                         (match_dup 0)))
15999    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16000               (clobber (reg:CC FLAGS_REG))])]
16001   "TARGET_64BIT"
16002   "operands[2] = gen_reg_rtx (DImode);")
16003
16004 (define_insn "*ffsdi_1"
16005   [(set (reg:CCZ FLAGS_REG)
16006         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
16007                      (const_int 0)))
16008    (set (match_operand:DI 0 "register_operand" "=r")
16009         (ctz:DI (match_dup 1)))]
16010   "TARGET_64BIT"
16011   "bsf{q}\t{%1, %0|%0, %1}"
16012   [(set_attr "type" "alu1")
16013    (set_attr "prefix_0f" "1")
16014    (set_attr "mode" "DI")])
16015
16016 (define_insn "ctzsi2"
16017   [(set (match_operand:SI 0 "register_operand" "=r")
16018         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16019    (clobber (reg:CC FLAGS_REG))]
16020   ""
16021   "bsf{l}\t{%1, %0|%0, %1}"
16022   [(set_attr "type" "alu1")
16023    (set_attr "prefix_0f" "1")
16024    (set_attr "mode" "SI")])
16025
16026 (define_insn "ctzdi2"
16027   [(set (match_operand:DI 0 "register_operand" "=r")
16028         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16029    (clobber (reg:CC FLAGS_REG))]
16030   "TARGET_64BIT"
16031   "bsf{q}\t{%1, %0|%0, %1}"
16032   [(set_attr "type" "alu1")
16033    (set_attr "prefix_0f" "1")
16034    (set_attr "mode" "DI")])
16035
16036 (define_expand "clzsi2"
16037   [(parallel
16038      [(set (match_operand:SI 0 "register_operand" "")
16039            (minus:SI (const_int 31)
16040                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16041       (clobber (reg:CC FLAGS_REG))])
16042    (parallel
16043      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16044       (clobber (reg:CC FLAGS_REG))])]
16045   ""
16046 {
16047   if (TARGET_ABM)
16048     {
16049       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16050       DONE;
16051     }
16052 })
16053
16054 (define_insn "clzsi2_abm"
16055   [(set (match_operand:SI 0 "register_operand" "=r")
16056         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16057    (clobber (reg:CC FLAGS_REG))]
16058   "TARGET_ABM"
16059   "lzcnt{l}\t{%1, %0|%0, %1}"
16060   [(set_attr "prefix_rep" "1")
16061    (set_attr "type" "bitmanip")
16062    (set_attr "mode" "SI")])
16063
16064 (define_insn "bsr"
16065   [(set (match_operand:SI 0 "register_operand" "=r")
16066         (minus:SI (const_int 31)
16067                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16068    (clobber (reg:CC FLAGS_REG))]
16069   ""
16070   "bsr{l}\t{%1, %0|%0, %1}"
16071   [(set_attr "type" "alu1")
16072    (set_attr "prefix_0f" "1")
16073    (set_attr "mode" "SI")])
16074
16075 (define_insn "popcount<mode>2"
16076   [(set (match_operand:SWI248 0 "register_operand" "=r")
16077         (popcount:SWI248
16078           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16079    (clobber (reg:CC FLAGS_REG))]
16080   "TARGET_POPCNT"
16081 {
16082 #if TARGET_MACHO
16083   return "popcnt\t{%1, %0|%0, %1}";
16084 #else
16085   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16086 #endif
16087 }
16088   [(set_attr "prefix_rep" "1")
16089    (set_attr "type" "bitmanip")
16090    (set_attr "mode" "<MODE>")])
16091
16092 (define_insn "*popcount<mode>2_cmp"
16093   [(set (reg FLAGS_REG)
16094         (compare
16095           (popcount:SWI248
16096             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16097           (const_int 0)))
16098    (set (match_operand:SWI248 0 "register_operand" "=r")
16099         (popcount:SWI248 (match_dup 1)))]
16100   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16101 {
16102 #if TARGET_MACHO
16103   return "popcnt\t{%1, %0|%0, %1}";
16104 #else
16105   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16106 #endif
16107 }
16108   [(set_attr "prefix_rep" "1")
16109    (set_attr "type" "bitmanip")
16110    (set_attr "mode" "<MODE>")])
16111
16112 (define_insn "*popcountsi2_cmp_zext"
16113   [(set (reg FLAGS_REG)
16114         (compare
16115           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16116           (const_int 0)))
16117    (set (match_operand:DI 0 "register_operand" "=r")
16118         (zero_extend:DI(popcount:SI (match_dup 1))))]
16119   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16120 {
16121 #if TARGET_MACHO
16122   return "popcnt\t{%1, %0|%0, %1}";
16123 #else
16124   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16125 #endif
16126 }
16127   [(set_attr "prefix_rep" "1")
16128    (set_attr "type" "bitmanip")
16129    (set_attr "mode" "SI")])
16130
16131 (define_expand "bswapsi2"
16132   [(set (match_operand:SI 0 "register_operand" "")
16133         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16134   ""
16135 {
16136   if (!(TARGET_BSWAP || TARGET_MOVBE))
16137     {
16138       rtx x = operands[0];
16139
16140       emit_move_insn (x, operands[1]);
16141       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16142       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16143       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16144       DONE;
16145     }
16146 })
16147
16148 (define_insn "*bswapsi_movbe"
16149   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16150         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16151   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16152   "@
16153     bswap\t%0
16154     movbe\t{%1, %0|%0, %1}
16155     movbe\t{%1, %0|%0, %1}"
16156   [(set_attr "type" "*,imov,imov")
16157    (set_attr "modrm" "*,1,1")
16158    (set_attr "prefix_0f" "1")
16159    (set_attr "prefix_extra" "*,1,1")
16160    (set_attr "length" "2,*,*")
16161    (set_attr "mode" "SI")])
16162
16163 (define_insn "*bswapsi_1"
16164   [(set (match_operand:SI 0 "register_operand" "=r")
16165         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16166   "TARGET_BSWAP"
16167   "bswap\t%0"
16168   [(set_attr "prefix_0f" "1")
16169    (set_attr "length" "2")])
16170
16171 (define_insn "*bswaphi_lowpart_1"
16172   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16173         (bswap:HI (match_dup 0)))
16174    (clobber (reg:CC FLAGS_REG))]
16175   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16176   "@
16177     xchg{b}\t{%h0, %b0|%b0, %h0}
16178     rol{w}\t{$8, %0|%0, 8}"
16179   [(set_attr "length" "2,4")
16180    (set_attr "mode" "QI,HI")])
16181
16182 (define_insn "bswaphi_lowpart"
16183   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16184         (bswap:HI (match_dup 0)))
16185    (clobber (reg:CC FLAGS_REG))]
16186   ""
16187   "rol{w}\t{$8, %0|%0, 8}"
16188   [(set_attr "length" "4")
16189    (set_attr "mode" "HI")])
16190
16191 (define_expand "bswapdi2"
16192   [(set (match_operand:DI 0 "register_operand" "")
16193         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16194   "TARGET_64BIT"
16195   "")
16196
16197 (define_insn "*bswapdi_movbe"
16198   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16199         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16200   "TARGET_64BIT && TARGET_MOVBE
16201    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16202   "@
16203     bswap\t%0
16204     movbe\t{%1, %0|%0, %1}
16205     movbe\t{%1, %0|%0, %1}"
16206   [(set_attr "type" "*,imov,imov")
16207    (set_attr "modrm" "*,1,1")
16208    (set_attr "prefix_0f" "1")
16209    (set_attr "prefix_extra" "*,1,1")
16210    (set_attr "length" "3,*,*")
16211    (set_attr "mode" "DI")])
16212
16213 (define_insn "*bswapdi_1"
16214   [(set (match_operand:DI 0 "register_operand" "=r")
16215         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16216   "TARGET_64BIT"
16217   "bswap\t%0"
16218   [(set_attr "prefix_0f" "1")
16219    (set_attr "length" "3")])
16220
16221 (define_expand "clzdi2"
16222   [(parallel
16223      [(set (match_operand:DI 0 "register_operand" "")
16224            (minus:DI (const_int 63)
16225                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16226       (clobber (reg:CC FLAGS_REG))])
16227    (parallel
16228      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16229       (clobber (reg:CC FLAGS_REG))])]
16230   "TARGET_64BIT"
16231 {
16232   if (TARGET_ABM)
16233     {
16234       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16235       DONE;
16236     }
16237 })
16238
16239 (define_insn "clzdi2_abm"
16240   [(set (match_operand:DI 0 "register_operand" "=r")
16241         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16242    (clobber (reg:CC FLAGS_REG))]
16243   "TARGET_64BIT && TARGET_ABM"
16244   "lzcnt{q}\t{%1, %0|%0, %1}"
16245   [(set_attr "prefix_rep" "1")
16246    (set_attr "type" "bitmanip")
16247    (set_attr "mode" "DI")])
16248
16249 (define_insn "bsr_rex64"
16250   [(set (match_operand:DI 0 "register_operand" "=r")
16251         (minus:DI (const_int 63)
16252                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16253    (clobber (reg:CC FLAGS_REG))]
16254   "TARGET_64BIT"
16255   "bsr{q}\t{%1, %0|%0, %1}"
16256   [(set_attr "type" "alu1")
16257    (set_attr "prefix_0f" "1")
16258    (set_attr "mode" "DI")])
16259
16260 (define_expand "clzhi2"
16261   [(parallel
16262      [(set (match_operand:HI 0 "register_operand" "")
16263            (minus:HI (const_int 15)
16264                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16265       (clobber (reg:CC FLAGS_REG))])
16266    (parallel
16267      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16268       (clobber (reg:CC FLAGS_REG))])]
16269   ""
16270 {
16271   if (TARGET_ABM)
16272     {
16273       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16274       DONE;
16275     }
16276 })
16277
16278 (define_insn "clzhi2_abm"
16279   [(set (match_operand:HI 0 "register_operand" "=r")
16280         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16281    (clobber (reg:CC FLAGS_REG))]
16282   "TARGET_ABM"
16283   "lzcnt{w}\t{%1, %0|%0, %1}"
16284   [(set_attr "prefix_rep" "1")
16285    (set_attr "type" "bitmanip")
16286    (set_attr "mode" "HI")])
16287
16288 (define_insn "*bsrhi"
16289   [(set (match_operand:HI 0 "register_operand" "=r")
16290         (minus:HI (const_int 15)
16291                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16292    (clobber (reg:CC FLAGS_REG))]
16293   ""
16294   "bsr{w}\t{%1, %0|%0, %1}"
16295   [(set_attr "type" "alu1")
16296    (set_attr "prefix_0f" "1")
16297    (set_attr "mode" "HI")])
16298
16299 (define_expand "paritydi2"
16300   [(set (match_operand:DI 0 "register_operand" "")
16301         (parity:DI (match_operand:DI 1 "register_operand" "")))]
16302   "! TARGET_POPCNT"
16303 {
16304   rtx scratch = gen_reg_rtx (QImode);
16305   rtx cond;
16306
16307   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16308                                 NULL_RTX, operands[1]));
16309
16310   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16311                          gen_rtx_REG (CCmode, FLAGS_REG),
16312                          const0_rtx);
16313   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16314
16315   if (TARGET_64BIT)
16316     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16317   else
16318     {
16319       rtx tmp = gen_reg_rtx (SImode);
16320
16321       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16322       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16323     }
16324   DONE;
16325 })
16326
16327 (define_insn_and_split "paritydi2_cmp"
16328   [(set (reg:CC FLAGS_REG)
16329         (parity:CC (match_operand:DI 3 "register_operand" "0")))
16330    (clobber (match_scratch:DI 0 "=r"))
16331    (clobber (match_scratch:SI 1 "=&r"))
16332    (clobber (match_scratch:HI 2 "=Q"))]
16333   "! TARGET_POPCNT"
16334   "#"
16335   "&& reload_completed"
16336   [(parallel
16337      [(set (match_dup 1)
16338            (xor:SI (match_dup 1) (match_dup 4)))
16339       (clobber (reg:CC FLAGS_REG))])
16340    (parallel
16341      [(set (reg:CC FLAGS_REG)
16342            (parity:CC (match_dup 1)))
16343       (clobber (match_dup 1))
16344       (clobber (match_dup 2))])]
16345 {
16346   operands[4] = gen_lowpart (SImode, operands[3]);
16347
16348   if (TARGET_64BIT)
16349     {
16350       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16351       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16352     }
16353   else
16354     operands[1] = gen_highpart (SImode, operands[3]);
16355 })
16356
16357 (define_expand "paritysi2"
16358   [(set (match_operand:SI 0 "register_operand" "")
16359         (parity:SI (match_operand:SI 1 "register_operand" "")))]
16360   "! TARGET_POPCNT"
16361 {
16362   rtx scratch = gen_reg_rtx (QImode);
16363   rtx cond;
16364
16365   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16366
16367   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16368                          gen_rtx_REG (CCmode, FLAGS_REG),
16369                          const0_rtx);
16370   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16371
16372   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16373   DONE;
16374 })
16375
16376 (define_insn_and_split "paritysi2_cmp"
16377   [(set (reg:CC FLAGS_REG)
16378         (parity:CC (match_operand:SI 2 "register_operand" "0")))
16379    (clobber (match_scratch:SI 0 "=r"))
16380    (clobber (match_scratch:HI 1 "=&Q"))]
16381   "! TARGET_POPCNT"
16382   "#"
16383   "&& reload_completed"
16384   [(parallel
16385      [(set (match_dup 1)
16386            (xor:HI (match_dup 1) (match_dup 3)))
16387       (clobber (reg:CC FLAGS_REG))])
16388    (parallel
16389      [(set (reg:CC FLAGS_REG)
16390            (parity:CC (match_dup 1)))
16391       (clobber (match_dup 1))])]
16392 {
16393   operands[3] = gen_lowpart (HImode, operands[2]);
16394
16395   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16396   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16397 })
16398
16399 (define_insn "*parityhi2_cmp"
16400   [(set (reg:CC FLAGS_REG)
16401         (parity:CC (match_operand:HI 1 "register_operand" "0")))
16402    (clobber (match_scratch:HI 0 "=Q"))]
16403   "! TARGET_POPCNT"
16404   "xor{b}\t{%h0, %b0|%b0, %h0}"
16405   [(set_attr "length" "2")
16406    (set_attr "mode" "HI")])
16407
16408 (define_insn "*parityqi2_cmp"
16409   [(set (reg:CC FLAGS_REG)
16410         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16411   "! TARGET_POPCNT"
16412   "test{b}\t%0, %0"
16413   [(set_attr "length" "2")
16414    (set_attr "mode" "QI")])
16415 \f
16416 ;; Thread-local storage patterns for ELF.
16417 ;;
16418 ;; Note that these code sequences must appear exactly as shown
16419 ;; in order to allow linker relaxation.
16420
16421 (define_insn "*tls_global_dynamic_32_gnu"
16422   [(set (match_operand:SI 0 "register_operand" "=a")
16423         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16424                     (match_operand:SI 2 "tls_symbolic_operand" "")
16425                     (match_operand:SI 3 "call_insn_operand" "")]
16426                     UNSPEC_TLS_GD))
16427    (clobber (match_scratch:SI 4 "=d"))
16428    (clobber (match_scratch:SI 5 "=c"))
16429    (clobber (reg:CC FLAGS_REG))]
16430   "!TARGET_64BIT && TARGET_GNU_TLS"
16431   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16432   [(set_attr "type" "multi")
16433    (set_attr "length" "12")])
16434
16435 (define_insn "*tls_global_dynamic_32_sun"
16436   [(set (match_operand:SI 0 "register_operand" "=a")
16437         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16438                     (match_operand:SI 2 "tls_symbolic_operand" "")
16439                     (match_operand:SI 3 "call_insn_operand" "")]
16440                     UNSPEC_TLS_GD))
16441    (clobber (match_scratch:SI 4 "=d"))
16442    (clobber (match_scratch:SI 5 "=c"))
16443    (clobber (reg:CC FLAGS_REG))]
16444   "!TARGET_64BIT && TARGET_SUN_TLS"
16445   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16446         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16447   [(set_attr "type" "multi")
16448    (set_attr "length" "14")])
16449
16450 (define_expand "tls_global_dynamic_32"
16451   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16452                    (unspec:SI
16453                     [(match_dup 2)
16454                      (match_operand:SI 1 "tls_symbolic_operand" "")
16455                      (match_dup 3)]
16456                     UNSPEC_TLS_GD))
16457               (clobber (match_scratch:SI 4 ""))
16458               (clobber (match_scratch:SI 5 ""))
16459               (clobber (reg:CC FLAGS_REG))])]
16460   ""
16461 {
16462   if (flag_pic)
16463     operands[2] = pic_offset_table_rtx;
16464   else
16465     {
16466       operands[2] = gen_reg_rtx (Pmode);
16467       emit_insn (gen_set_got (operands[2]));
16468     }
16469   if (TARGET_GNU2_TLS)
16470     {
16471        emit_insn (gen_tls_dynamic_gnu2_32
16472                   (operands[0], operands[1], operands[2]));
16473        DONE;
16474     }
16475   operands[3] = ix86_tls_get_addr ();
16476 })
16477
16478 (define_insn "*tls_global_dynamic_64"
16479   [(set (match_operand:DI 0 "register_operand" "=a")
16480         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16481                  (match_operand:DI 3 "" "")))
16482    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16483               UNSPEC_TLS_GD)]
16484   "TARGET_64BIT"
16485   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16486   [(set_attr "type" "multi")
16487    (set_attr "length" "16")])
16488
16489 (define_expand "tls_global_dynamic_64"
16490   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16491                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16492               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16493                          UNSPEC_TLS_GD)])]
16494   ""
16495 {
16496   if (TARGET_GNU2_TLS)
16497     {
16498        emit_insn (gen_tls_dynamic_gnu2_64
16499                   (operands[0], operands[1]));
16500        DONE;
16501     }
16502   operands[2] = ix86_tls_get_addr ();
16503 })
16504
16505 (define_insn "*tls_local_dynamic_base_32_gnu"
16506   [(set (match_operand:SI 0 "register_operand" "=a")
16507         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16508                     (match_operand:SI 2 "call_insn_operand" "")]
16509                    UNSPEC_TLS_LD_BASE))
16510    (clobber (match_scratch:SI 3 "=d"))
16511    (clobber (match_scratch:SI 4 "=c"))
16512    (clobber (reg:CC FLAGS_REG))]
16513   "!TARGET_64BIT && TARGET_GNU_TLS"
16514   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16515   [(set_attr "type" "multi")
16516    (set_attr "length" "11")])
16517
16518 (define_insn "*tls_local_dynamic_base_32_sun"
16519   [(set (match_operand:SI 0 "register_operand" "=a")
16520         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16521                     (match_operand:SI 2 "call_insn_operand" "")]
16522                    UNSPEC_TLS_LD_BASE))
16523    (clobber (match_scratch:SI 3 "=d"))
16524    (clobber (match_scratch:SI 4 "=c"))
16525    (clobber (reg:CC FLAGS_REG))]
16526   "!TARGET_64BIT && TARGET_SUN_TLS"
16527   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16528         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16529   [(set_attr "type" "multi")
16530    (set_attr "length" "13")])
16531
16532 (define_expand "tls_local_dynamic_base_32"
16533   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16534                    (unspec:SI [(match_dup 1) (match_dup 2)]
16535                               UNSPEC_TLS_LD_BASE))
16536               (clobber (match_scratch:SI 3 ""))
16537               (clobber (match_scratch:SI 4 ""))
16538               (clobber (reg:CC FLAGS_REG))])]
16539   ""
16540 {
16541   if (flag_pic)
16542     operands[1] = pic_offset_table_rtx;
16543   else
16544     {
16545       operands[1] = gen_reg_rtx (Pmode);
16546       emit_insn (gen_set_got (operands[1]));
16547     }
16548   if (TARGET_GNU2_TLS)
16549     {
16550        emit_insn (gen_tls_dynamic_gnu2_32
16551                   (operands[0], ix86_tls_module_base (), operands[1]));
16552        DONE;
16553     }
16554   operands[2] = ix86_tls_get_addr ();
16555 })
16556
16557 (define_insn "*tls_local_dynamic_base_64"
16558   [(set (match_operand:DI 0 "register_operand" "=a")
16559         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16560                  (match_operand:DI 2 "" "")))
16561    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16562   "TARGET_64BIT"
16563   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16564   [(set_attr "type" "multi")
16565    (set_attr "length" "12")])
16566
16567 (define_expand "tls_local_dynamic_base_64"
16568   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16569                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16570               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16571   ""
16572 {
16573   if (TARGET_GNU2_TLS)
16574     {
16575        emit_insn (gen_tls_dynamic_gnu2_64
16576                   (operands[0], ix86_tls_module_base ()));
16577        DONE;
16578     }
16579   operands[1] = ix86_tls_get_addr ();
16580 })
16581
16582 ;; Local dynamic of a single variable is a lose.  Show combine how
16583 ;; to convert that back to global dynamic.
16584
16585 (define_insn_and_split "*tls_local_dynamic_32_once"
16586   [(set (match_operand:SI 0 "register_operand" "=a")
16587         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16588                              (match_operand:SI 2 "call_insn_operand" "")]
16589                             UNSPEC_TLS_LD_BASE)
16590                  (const:SI (unspec:SI
16591                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16592                             UNSPEC_DTPOFF))))
16593    (clobber (match_scratch:SI 4 "=d"))
16594    (clobber (match_scratch:SI 5 "=c"))
16595    (clobber (reg:CC FLAGS_REG))]
16596   ""
16597   "#"
16598   ""
16599   [(parallel [(set (match_dup 0)
16600                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16601                               UNSPEC_TLS_GD))
16602               (clobber (match_dup 4))
16603               (clobber (match_dup 5))
16604               (clobber (reg:CC FLAGS_REG))])]
16605   "")
16606
16607 ;; Load and add the thread base pointer from %gs:0.
16608
16609 (define_insn "*load_tp_si"
16610   [(set (match_operand:SI 0 "register_operand" "=r")
16611         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16612   "!TARGET_64BIT"
16613   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16614   [(set_attr "type" "imov")
16615    (set_attr "modrm" "0")
16616    (set_attr "length" "7")
16617    (set_attr "memory" "load")
16618    (set_attr "imm_disp" "false")])
16619
16620 (define_insn "*add_tp_si"
16621   [(set (match_operand:SI 0 "register_operand" "=r")
16622         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16623                  (match_operand:SI 1 "register_operand" "0")))
16624    (clobber (reg:CC FLAGS_REG))]
16625   "!TARGET_64BIT"
16626   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16627   [(set_attr "type" "alu")
16628    (set_attr "modrm" "0")
16629    (set_attr "length" "7")
16630    (set_attr "memory" "load")
16631    (set_attr "imm_disp" "false")])
16632
16633 (define_insn "*load_tp_di"
16634   [(set (match_operand:DI 0 "register_operand" "=r")
16635         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16636   "TARGET_64BIT"
16637   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16638   [(set_attr "type" "imov")
16639    (set_attr "modrm" "0")
16640    (set_attr "length" "7")
16641    (set_attr "memory" "load")
16642    (set_attr "imm_disp" "false")])
16643
16644 (define_insn "*add_tp_di"
16645   [(set (match_operand:DI 0 "register_operand" "=r")
16646         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16647                  (match_operand:DI 1 "register_operand" "0")))
16648    (clobber (reg:CC FLAGS_REG))]
16649   "TARGET_64BIT"
16650   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16651   [(set_attr "type" "alu")
16652    (set_attr "modrm" "0")
16653    (set_attr "length" "7")
16654    (set_attr "memory" "load")
16655    (set_attr "imm_disp" "false")])
16656
16657 ;; GNU2 TLS patterns can be split.
16658
16659 (define_expand "tls_dynamic_gnu2_32"
16660   [(set (match_dup 3)
16661         (plus:SI (match_operand:SI 2 "register_operand" "")
16662                  (const:SI
16663                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16664                              UNSPEC_TLSDESC))))
16665    (parallel
16666     [(set (match_operand:SI 0 "register_operand" "")
16667           (unspec:SI [(match_dup 1) (match_dup 3)
16668                       (match_dup 2) (reg:SI SP_REG)]
16669                       UNSPEC_TLSDESC))
16670      (clobber (reg:CC FLAGS_REG))])]
16671   "!TARGET_64BIT && TARGET_GNU2_TLS"
16672 {
16673   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16674   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16675 })
16676
16677 (define_insn "*tls_dynamic_lea_32"
16678   [(set (match_operand:SI 0 "register_operand" "=r")
16679         (plus:SI (match_operand:SI 1 "register_operand" "b")
16680                  (const:SI
16681                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16682                               UNSPEC_TLSDESC))))]
16683   "!TARGET_64BIT && TARGET_GNU2_TLS"
16684   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16685   [(set_attr "type" "lea")
16686    (set_attr "mode" "SI")
16687    (set_attr "length" "6")
16688    (set_attr "length_address" "4")])
16689
16690 (define_insn "*tls_dynamic_call_32"
16691   [(set (match_operand:SI 0 "register_operand" "=a")
16692         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16693                     (match_operand:SI 2 "register_operand" "0")
16694                     ;; we have to make sure %ebx still points to the GOT
16695                     (match_operand:SI 3 "register_operand" "b")
16696                     (reg:SI SP_REG)]
16697                    UNSPEC_TLSDESC))
16698    (clobber (reg:CC FLAGS_REG))]
16699   "!TARGET_64BIT && TARGET_GNU2_TLS"
16700   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16701   [(set_attr "type" "call")
16702    (set_attr "length" "2")
16703    (set_attr "length_address" "0")])
16704
16705 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16706   [(set (match_operand:SI 0 "register_operand" "=&a")
16707         (plus:SI
16708          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16709                      (match_operand:SI 4 "" "")
16710                      (match_operand:SI 2 "register_operand" "b")
16711                      (reg:SI SP_REG)]
16712                     UNSPEC_TLSDESC)
16713          (const:SI (unspec:SI
16714                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16715                     UNSPEC_DTPOFF))))
16716    (clobber (reg:CC FLAGS_REG))]
16717   "!TARGET_64BIT && TARGET_GNU2_TLS"
16718   "#"
16719   ""
16720   [(set (match_dup 0) (match_dup 5))]
16721 {
16722   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16723   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16724 })
16725
16726 (define_expand "tls_dynamic_gnu2_64"
16727   [(set (match_dup 2)
16728         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16729                    UNSPEC_TLSDESC))
16730    (parallel
16731     [(set (match_operand:DI 0 "register_operand" "")
16732           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16733                      UNSPEC_TLSDESC))
16734      (clobber (reg:CC FLAGS_REG))])]
16735   "TARGET_64BIT && TARGET_GNU2_TLS"
16736 {
16737   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16738   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16739 })
16740
16741 (define_insn "*tls_dynamic_lea_64"
16742   [(set (match_operand:DI 0 "register_operand" "=r")
16743         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16744                    UNSPEC_TLSDESC))]
16745   "TARGET_64BIT && TARGET_GNU2_TLS"
16746   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16747   [(set_attr "type" "lea")
16748    (set_attr "mode" "DI")
16749    (set_attr "length" "7")
16750    (set_attr "length_address" "4")])
16751
16752 (define_insn "*tls_dynamic_call_64"
16753   [(set (match_operand:DI 0 "register_operand" "=a")
16754         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16755                     (match_operand:DI 2 "register_operand" "0")
16756                     (reg:DI SP_REG)]
16757                    UNSPEC_TLSDESC))
16758    (clobber (reg:CC FLAGS_REG))]
16759   "TARGET_64BIT && TARGET_GNU2_TLS"
16760   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16761   [(set_attr "type" "call")
16762    (set_attr "length" "2")
16763    (set_attr "length_address" "0")])
16764
16765 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16766   [(set (match_operand:DI 0 "register_operand" "=&a")
16767         (plus:DI
16768          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16769                      (match_operand:DI 3 "" "")
16770                      (reg:DI SP_REG)]
16771                     UNSPEC_TLSDESC)
16772          (const:DI (unspec:DI
16773                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16774                     UNSPEC_DTPOFF))))
16775    (clobber (reg:CC FLAGS_REG))]
16776   "TARGET_64BIT && TARGET_GNU2_TLS"
16777   "#"
16778   ""
16779   [(set (match_dup 0) (match_dup 4))]
16780 {
16781   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16782   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16783 })
16784
16785 ;;
16786 \f
16787 ;; These patterns match the binary 387 instructions for addM3, subM3,
16788 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16789 ;; SFmode.  The first is the normal insn, the second the same insn but
16790 ;; with one operand a conversion, and the third the same insn but with
16791 ;; the other operand a conversion.  The conversion may be SFmode or
16792 ;; SImode if the target mode DFmode, but only SImode if the target mode
16793 ;; is SFmode.
16794
16795 ;; Gcc is slightly more smart about handling normal two address instructions
16796 ;; so use special patterns for add and mull.
16797
16798 (define_insn "*fop_<mode>_comm_mixed_avx"
16799   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16800         (match_operator:MODEF 3 "binary_fp_operator"
16801           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16802            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16803   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16804    && COMMUTATIVE_ARITH_P (operands[3])
16805    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16806   "* return output_387_binary_op (insn, operands);"
16807   [(set (attr "type")
16808         (if_then_else (eq_attr "alternative" "1")
16809            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16810               (const_string "ssemul")
16811               (const_string "sseadd"))
16812            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16813               (const_string "fmul")
16814               (const_string "fop"))))
16815    (set_attr "prefix" "orig,maybe_vex")
16816    (set_attr "mode" "<MODE>")])
16817
16818 (define_insn "*fop_<mode>_comm_mixed"
16819   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16820         (match_operator:MODEF 3 "binary_fp_operator"
16821           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16822            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16823   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16824    && COMMUTATIVE_ARITH_P (operands[3])
16825    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16826   "* return output_387_binary_op (insn, operands);"
16827   [(set (attr "type")
16828         (if_then_else (eq_attr "alternative" "1")
16829            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16830               (const_string "ssemul")
16831               (const_string "sseadd"))
16832            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16833               (const_string "fmul")
16834               (const_string "fop"))))
16835    (set_attr "mode" "<MODE>")])
16836
16837 (define_insn "*fop_<mode>_comm_avx"
16838   [(set (match_operand:MODEF 0 "register_operand" "=x")
16839         (match_operator:MODEF 3 "binary_fp_operator"
16840           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16841            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16842   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16843    && COMMUTATIVE_ARITH_P (operands[3])
16844    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16845   "* return output_387_binary_op (insn, operands);"
16846   [(set (attr "type")
16847         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16848            (const_string "ssemul")
16849            (const_string "sseadd")))
16850    (set_attr "prefix" "vex")
16851    (set_attr "mode" "<MODE>")])
16852
16853 (define_insn "*fop_<mode>_comm_sse"
16854   [(set (match_operand:MODEF 0 "register_operand" "=x")
16855         (match_operator:MODEF 3 "binary_fp_operator"
16856           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16857            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16858   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16859    && COMMUTATIVE_ARITH_P (operands[3])
16860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16861   "* return output_387_binary_op (insn, operands);"
16862   [(set (attr "type")
16863         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16864            (const_string "ssemul")
16865            (const_string "sseadd")))
16866    (set_attr "mode" "<MODE>")])
16867
16868 (define_insn "*fop_<mode>_comm_i387"
16869   [(set (match_operand:MODEF 0 "register_operand" "=f")
16870         (match_operator:MODEF 3 "binary_fp_operator"
16871           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16872            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16873   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16874    && COMMUTATIVE_ARITH_P (operands[3])
16875    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16876   "* return output_387_binary_op (insn, operands);"
16877   [(set (attr "type")
16878         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16879            (const_string "fmul")
16880            (const_string "fop")))
16881    (set_attr "mode" "<MODE>")])
16882
16883 (define_insn "*fop_<mode>_1_mixed_avx"
16884   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16885         (match_operator:MODEF 3 "binary_fp_operator"
16886           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16887            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16888   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16889    && !COMMUTATIVE_ARITH_P (operands[3])
16890    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16891   "* return output_387_binary_op (insn, operands);"
16892   [(set (attr "type")
16893         (cond [(and (eq_attr "alternative" "2")
16894                     (match_operand:MODEF 3 "mult_operator" ""))
16895                  (const_string "ssemul")
16896                (and (eq_attr "alternative" "2")
16897                     (match_operand:MODEF 3 "div_operator" ""))
16898                  (const_string "ssediv")
16899                (eq_attr "alternative" "2")
16900                  (const_string "sseadd")
16901                (match_operand:MODEF 3 "mult_operator" "")
16902                  (const_string "fmul")
16903                (match_operand:MODEF 3 "div_operator" "")
16904                  (const_string "fdiv")
16905               ]
16906               (const_string "fop")))
16907    (set_attr "prefix" "orig,orig,maybe_vex")
16908    (set_attr "mode" "<MODE>")])
16909
16910 (define_insn "*fop_<mode>_1_mixed"
16911   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16912         (match_operator:MODEF 3 "binary_fp_operator"
16913           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16914            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16915   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16916    && !COMMUTATIVE_ARITH_P (operands[3])
16917    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16918   "* return output_387_binary_op (insn, operands);"
16919   [(set (attr "type")
16920         (cond [(and (eq_attr "alternative" "2")
16921                     (match_operand:MODEF 3 "mult_operator" ""))
16922                  (const_string "ssemul")
16923                (and (eq_attr "alternative" "2")
16924                     (match_operand:MODEF 3 "div_operator" ""))
16925                  (const_string "ssediv")
16926                (eq_attr "alternative" "2")
16927                  (const_string "sseadd")
16928                (match_operand:MODEF 3 "mult_operator" "")
16929                  (const_string "fmul")
16930                (match_operand:MODEF 3 "div_operator" "")
16931                  (const_string "fdiv")
16932               ]
16933               (const_string "fop")))
16934    (set_attr "mode" "<MODE>")])
16935
16936 (define_insn "*rcpsf2_sse"
16937   [(set (match_operand:SF 0 "register_operand" "=x")
16938         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16939                    UNSPEC_RCP))]
16940   "TARGET_SSE_MATH"
16941   "%vrcpss\t{%1, %d0|%d0, %1}"
16942   [(set_attr "type" "sse")
16943    (set_attr "atom_sse_attr" "rcp")
16944    (set_attr "prefix" "maybe_vex")
16945    (set_attr "mode" "SF")])
16946
16947 (define_insn "*fop_<mode>_1_avx"
16948   [(set (match_operand:MODEF 0 "register_operand" "=x")
16949         (match_operator:MODEF 3 "binary_fp_operator"
16950           [(match_operand:MODEF 1 "register_operand" "x")
16951            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16952   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16953    && !COMMUTATIVE_ARITH_P (operands[3])"
16954   "* return output_387_binary_op (insn, operands);"
16955   [(set (attr "type")
16956         (cond [(match_operand:MODEF 3 "mult_operator" "")
16957                  (const_string "ssemul")
16958                (match_operand:MODEF 3 "div_operator" "")
16959                  (const_string "ssediv")
16960               ]
16961               (const_string "sseadd")))
16962    (set_attr "prefix" "vex")
16963    (set_attr "mode" "<MODE>")])
16964
16965 (define_insn "*fop_<mode>_1_sse"
16966   [(set (match_operand:MODEF 0 "register_operand" "=x")
16967         (match_operator:MODEF 3 "binary_fp_operator"
16968           [(match_operand:MODEF 1 "register_operand" "0")
16969            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16970   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16971    && !COMMUTATIVE_ARITH_P (operands[3])"
16972   "* return output_387_binary_op (insn, operands);"
16973   [(set (attr "type")
16974         (cond [(match_operand:MODEF 3 "mult_operator" "")
16975                  (const_string "ssemul")
16976                (match_operand:MODEF 3 "div_operator" "")
16977                  (const_string "ssediv")
16978               ]
16979               (const_string "sseadd")))
16980    (set_attr "mode" "<MODE>")])
16981
16982 ;; This pattern is not fully shadowed by the pattern above.
16983 (define_insn "*fop_<mode>_1_i387"
16984   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16985         (match_operator:MODEF 3 "binary_fp_operator"
16986           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16987            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16988   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16989    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16990    && !COMMUTATIVE_ARITH_P (operands[3])
16991    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16992   "* return output_387_binary_op (insn, operands);"
16993   [(set (attr "type")
16994         (cond [(match_operand:MODEF 3 "mult_operator" "")
16995                  (const_string "fmul")
16996                (match_operand:MODEF 3 "div_operator" "")
16997                  (const_string "fdiv")
16998               ]
16999               (const_string "fop")))
17000    (set_attr "mode" "<MODE>")])
17001
17002 ;; ??? Add SSE splitters for these!
17003 (define_insn "*fop_<MODEF:mode>_2_i387"
17004   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17005         (match_operator:MODEF 3 "binary_fp_operator"
17006           [(float:MODEF
17007              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17008            (match_operand:MODEF 2 "register_operand" "0,0")]))]
17009   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17010    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17011    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17012   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17013   [(set (attr "type")
17014         (cond [(match_operand:MODEF 3 "mult_operator" "")
17015                  (const_string "fmul")
17016                (match_operand:MODEF 3 "div_operator" "")
17017                  (const_string "fdiv")
17018               ]
17019               (const_string "fop")))
17020    (set_attr "fp_int_src" "true")
17021    (set_attr "mode" "<X87MODEI12:MODE>")])
17022
17023 (define_insn "*fop_<MODEF:mode>_3_i387"
17024   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17025         (match_operator:MODEF 3 "binary_fp_operator"
17026           [(match_operand:MODEF 1 "register_operand" "0,0")
17027            (float:MODEF
17028              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17029   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17030    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17031    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17032   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17033   [(set (attr "type")
17034         (cond [(match_operand:MODEF 3 "mult_operator" "")
17035                  (const_string "fmul")
17036                (match_operand:MODEF 3 "div_operator" "")
17037                  (const_string "fdiv")
17038               ]
17039               (const_string "fop")))
17040    (set_attr "fp_int_src" "true")
17041    (set_attr "mode" "<MODE>")])
17042
17043 (define_insn "*fop_df_4_i387"
17044   [(set (match_operand:DF 0 "register_operand" "=f,f")
17045         (match_operator:DF 3 "binary_fp_operator"
17046            [(float_extend:DF
17047              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17048             (match_operand:DF 2 "register_operand" "0,f")]))]
17049   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17050    && !(TARGET_SSE2 && TARGET_SSE_MATH)
17051    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17052   "* return output_387_binary_op (insn, operands);"
17053   [(set (attr "type")
17054         (cond [(match_operand:DF 3 "mult_operator" "")
17055                  (const_string "fmul")
17056                (match_operand:DF 3 "div_operator" "")
17057                  (const_string "fdiv")
17058               ]
17059               (const_string "fop")))
17060    (set_attr "mode" "SF")])
17061
17062 (define_insn "*fop_df_5_i387"
17063   [(set (match_operand:DF 0 "register_operand" "=f,f")
17064         (match_operator:DF 3 "binary_fp_operator"
17065           [(match_operand:DF 1 "register_operand" "0,f")
17066            (float_extend:DF
17067             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17068   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17069    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17070   "* return output_387_binary_op (insn, operands);"
17071   [(set (attr "type")
17072         (cond [(match_operand:DF 3 "mult_operator" "")
17073                  (const_string "fmul")
17074                (match_operand:DF 3 "div_operator" "")
17075                  (const_string "fdiv")
17076               ]
17077               (const_string "fop")))
17078    (set_attr "mode" "SF")])
17079
17080 (define_insn "*fop_df_6_i387"
17081   [(set (match_operand:DF 0 "register_operand" "=f,f")
17082         (match_operator:DF 3 "binary_fp_operator"
17083           [(float_extend:DF
17084             (match_operand:SF 1 "register_operand" "0,f"))
17085            (float_extend:DF
17086             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17087   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17088    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17089   "* return output_387_binary_op (insn, operands);"
17090   [(set (attr "type")
17091         (cond [(match_operand:DF 3 "mult_operator" "")
17092                  (const_string "fmul")
17093                (match_operand:DF 3 "div_operator" "")
17094                  (const_string "fdiv")
17095               ]
17096               (const_string "fop")))
17097    (set_attr "mode" "SF")])
17098
17099 (define_insn "*fop_xf_comm_i387"
17100   [(set (match_operand:XF 0 "register_operand" "=f")
17101         (match_operator:XF 3 "binary_fp_operator"
17102                         [(match_operand:XF 1 "register_operand" "%0")
17103                          (match_operand:XF 2 "register_operand" "f")]))]
17104   "TARGET_80387
17105    && COMMUTATIVE_ARITH_P (operands[3])"
17106   "* return output_387_binary_op (insn, operands);"
17107   [(set (attr "type")
17108         (if_then_else (match_operand:XF 3 "mult_operator" "")
17109            (const_string "fmul")
17110            (const_string "fop")))
17111    (set_attr "mode" "XF")])
17112
17113 (define_insn "*fop_xf_1_i387"
17114   [(set (match_operand:XF 0 "register_operand" "=f,f")
17115         (match_operator:XF 3 "binary_fp_operator"
17116                         [(match_operand:XF 1 "register_operand" "0,f")
17117                          (match_operand:XF 2 "register_operand" "f,0")]))]
17118   "TARGET_80387
17119    && !COMMUTATIVE_ARITH_P (operands[3])"
17120   "* return output_387_binary_op (insn, operands);"
17121   [(set (attr "type")
17122         (cond [(match_operand:XF 3 "mult_operator" "")
17123                  (const_string "fmul")
17124                (match_operand:XF 3 "div_operator" "")
17125                  (const_string "fdiv")
17126               ]
17127               (const_string "fop")))
17128    (set_attr "mode" "XF")])
17129
17130 (define_insn "*fop_xf_2_i387"
17131   [(set (match_operand:XF 0 "register_operand" "=f,f")
17132         (match_operator:XF 3 "binary_fp_operator"
17133           [(float:XF
17134              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17135            (match_operand:XF 2 "register_operand" "0,0")]))]
17136   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17137   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17138   [(set (attr "type")
17139         (cond [(match_operand:XF 3 "mult_operator" "")
17140                  (const_string "fmul")
17141                (match_operand:XF 3 "div_operator" "")
17142                  (const_string "fdiv")
17143               ]
17144               (const_string "fop")))
17145    (set_attr "fp_int_src" "true")
17146    (set_attr "mode" "<MODE>")])
17147
17148 (define_insn "*fop_xf_3_i387"
17149   [(set (match_operand:XF 0 "register_operand" "=f,f")
17150         (match_operator:XF 3 "binary_fp_operator"
17151           [(match_operand:XF 1 "register_operand" "0,0")
17152            (float:XF
17153              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17154   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17155   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17156   [(set (attr "type")
17157         (cond [(match_operand:XF 3 "mult_operator" "")
17158                  (const_string "fmul")
17159                (match_operand:XF 3 "div_operator" "")
17160                  (const_string "fdiv")
17161               ]
17162               (const_string "fop")))
17163    (set_attr "fp_int_src" "true")
17164    (set_attr "mode" "<MODE>")])
17165
17166 (define_insn "*fop_xf_4_i387"
17167   [(set (match_operand:XF 0 "register_operand" "=f,f")
17168         (match_operator:XF 3 "binary_fp_operator"
17169            [(float_extend:XF
17170               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17171             (match_operand:XF 2 "register_operand" "0,f")]))]
17172   "TARGET_80387"
17173   "* return output_387_binary_op (insn, operands);"
17174   [(set (attr "type")
17175         (cond [(match_operand:XF 3 "mult_operator" "")
17176                  (const_string "fmul")
17177                (match_operand:XF 3 "div_operator" "")
17178                  (const_string "fdiv")
17179               ]
17180               (const_string "fop")))
17181    (set_attr "mode" "<MODE>")])
17182
17183 (define_insn "*fop_xf_5_i387"
17184   [(set (match_operand:XF 0 "register_operand" "=f,f")
17185         (match_operator:XF 3 "binary_fp_operator"
17186           [(match_operand:XF 1 "register_operand" "0,f")
17187            (float_extend:XF
17188              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17189   "TARGET_80387"
17190   "* return output_387_binary_op (insn, operands);"
17191   [(set (attr "type")
17192         (cond [(match_operand:XF 3 "mult_operator" "")
17193                  (const_string "fmul")
17194                (match_operand:XF 3 "div_operator" "")
17195                  (const_string "fdiv")
17196               ]
17197               (const_string "fop")))
17198    (set_attr "mode" "<MODE>")])
17199
17200 (define_insn "*fop_xf_6_i387"
17201   [(set (match_operand:XF 0 "register_operand" "=f,f")
17202         (match_operator:XF 3 "binary_fp_operator"
17203           [(float_extend:XF
17204              (match_operand:MODEF 1 "register_operand" "0,f"))
17205            (float_extend:XF
17206              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17207   "TARGET_80387"
17208   "* return output_387_binary_op (insn, operands);"
17209   [(set (attr "type")
17210         (cond [(match_operand:XF 3 "mult_operator" "")
17211                  (const_string "fmul")
17212                (match_operand:XF 3 "div_operator" "")
17213                  (const_string "fdiv")
17214               ]
17215               (const_string "fop")))
17216    (set_attr "mode" "<MODE>")])
17217
17218 (define_split
17219   [(set (match_operand 0 "register_operand" "")
17220         (match_operator 3 "binary_fp_operator"
17221            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17222             (match_operand 2 "register_operand" "")]))]
17223   "reload_completed
17224    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17225    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17226   [(const_int 0)]
17227 {
17228   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17229   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17230   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17231                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17232                                           GET_MODE (operands[3]),
17233                                           operands[4],
17234                                           operands[2])));
17235   ix86_free_from_memory (GET_MODE (operands[1]));
17236   DONE;
17237 })
17238
17239 (define_split
17240   [(set (match_operand 0 "register_operand" "")
17241         (match_operator 3 "binary_fp_operator"
17242            [(match_operand 1 "register_operand" "")
17243             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17244   "reload_completed
17245    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17246    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17247   [(const_int 0)]
17248 {
17249   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17250   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17251   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17252                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17253                                           GET_MODE (operands[3]),
17254                                           operands[1],
17255                                           operands[4])));
17256   ix86_free_from_memory (GET_MODE (operands[2]));
17257   DONE;
17258 })
17259 \f
17260 ;; FPU special functions.
17261
17262 ;; This pattern implements a no-op XFmode truncation for
17263 ;; all fancy i386 XFmode math functions.
17264
17265 (define_insn "truncxf<mode>2_i387_noop_unspec"
17266   [(set (match_operand:MODEF 0 "register_operand" "=f")
17267         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17268         UNSPEC_TRUNC_NOOP))]
17269   "TARGET_USE_FANCY_MATH_387"
17270   "* return output_387_reg_move (insn, operands);"
17271   [(set_attr "type" "fmov")
17272    (set_attr "mode" "<MODE>")])
17273
17274 (define_insn "sqrtxf2"
17275   [(set (match_operand:XF 0 "register_operand" "=f")
17276         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17277   "TARGET_USE_FANCY_MATH_387"
17278   "fsqrt"
17279   [(set_attr "type" "fpspc")
17280    (set_attr "mode" "XF")
17281    (set_attr "athlon_decode" "direct")
17282    (set_attr "amdfam10_decode" "direct")])
17283
17284 (define_insn "sqrt_extend<mode>xf2_i387"
17285   [(set (match_operand:XF 0 "register_operand" "=f")
17286         (sqrt:XF
17287           (float_extend:XF
17288             (match_operand:MODEF 1 "register_operand" "0"))))]
17289   "TARGET_USE_FANCY_MATH_387"
17290   "fsqrt"
17291   [(set_attr "type" "fpspc")
17292    (set_attr "mode" "XF")
17293    (set_attr "athlon_decode" "direct")
17294    (set_attr "amdfam10_decode" "direct")])
17295
17296 (define_insn "*rsqrtsf2_sse"
17297   [(set (match_operand:SF 0 "register_operand" "=x")
17298         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17299                    UNSPEC_RSQRT))]
17300   "TARGET_SSE_MATH"
17301   "%vrsqrtss\t{%1, %d0|%d0, %1}"
17302   [(set_attr "type" "sse")
17303    (set_attr "atom_sse_attr" "rcp")
17304    (set_attr "prefix" "maybe_vex")
17305    (set_attr "mode" "SF")])
17306
17307 (define_expand "rsqrtsf2"
17308   [(set (match_operand:SF 0 "register_operand" "")
17309         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17310                    UNSPEC_RSQRT))]
17311   "TARGET_SSE_MATH"
17312 {
17313   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17314   DONE;
17315 })
17316
17317 (define_insn "*sqrt<mode>2_sse"
17318   [(set (match_operand:MODEF 0 "register_operand" "=x")
17319         (sqrt:MODEF
17320           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17321   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17322   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17323   [(set_attr "type" "sse")
17324    (set_attr "atom_sse_attr" "sqrt")
17325    (set_attr "prefix" "maybe_vex")
17326    (set_attr "mode" "<MODE>")
17327    (set_attr "athlon_decode" "*")
17328    (set_attr "amdfam10_decode" "*")])
17329
17330 (define_expand "sqrt<mode>2"
17331   [(set (match_operand:MODEF 0 "register_operand" "")
17332         (sqrt:MODEF
17333           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17334   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17335    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17336 {
17337   if (<MODE>mode == SFmode
17338       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17339       && flag_finite_math_only && !flag_trapping_math
17340       && flag_unsafe_math_optimizations)
17341     {
17342       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17343       DONE;
17344     }
17345
17346   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17347     {
17348       rtx op0 = gen_reg_rtx (XFmode);
17349       rtx op1 = force_reg (<MODE>mode, operands[1]);
17350
17351       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17352       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17353       DONE;
17354    }
17355 })
17356
17357 (define_insn "fpremxf4_i387"
17358   [(set (match_operand:XF 0 "register_operand" "=f")
17359         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17360                     (match_operand:XF 3 "register_operand" "1")]
17361                    UNSPEC_FPREM_F))
17362    (set (match_operand:XF 1 "register_operand" "=u")
17363         (unspec:XF [(match_dup 2) (match_dup 3)]
17364                    UNSPEC_FPREM_U))
17365    (set (reg:CCFP FPSR_REG)
17366         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17367                      UNSPEC_C2_FLAG))]
17368   "TARGET_USE_FANCY_MATH_387"
17369   "fprem"
17370   [(set_attr "type" "fpspc")
17371    (set_attr "mode" "XF")])
17372
17373 (define_expand "fmodxf3"
17374   [(use (match_operand:XF 0 "register_operand" ""))
17375    (use (match_operand:XF 1 "general_operand" ""))
17376    (use (match_operand:XF 2 "general_operand" ""))]
17377   "TARGET_USE_FANCY_MATH_387"
17378 {
17379   rtx label = gen_label_rtx ();
17380
17381   rtx op1 = gen_reg_rtx (XFmode);
17382   rtx op2 = gen_reg_rtx (XFmode);
17383
17384   emit_move_insn (op2, operands[2]);
17385   emit_move_insn (op1, operands[1]);
17386
17387   emit_label (label);
17388   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17389   ix86_emit_fp_unordered_jump (label);
17390   LABEL_NUSES (label) = 1;
17391
17392   emit_move_insn (operands[0], op1);
17393   DONE;
17394 })
17395
17396 (define_expand "fmod<mode>3"
17397   [(use (match_operand:MODEF 0 "register_operand" ""))
17398    (use (match_operand:MODEF 1 "general_operand" ""))
17399    (use (match_operand:MODEF 2 "general_operand" ""))]
17400   "TARGET_USE_FANCY_MATH_387"
17401 {
17402   rtx label = gen_label_rtx ();
17403
17404   rtx op1 = gen_reg_rtx (XFmode);
17405   rtx op2 = gen_reg_rtx (XFmode);
17406
17407   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17408   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17409
17410   emit_label (label);
17411   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17412   ix86_emit_fp_unordered_jump (label);
17413   LABEL_NUSES (label) = 1;
17414
17415   /* Truncate the result properly for strict SSE math.  */
17416   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17417       && !TARGET_MIX_SSE_I387)
17418     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17419   else
17420     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17421
17422   DONE;
17423 })
17424
17425 (define_insn "fprem1xf4_i387"
17426   [(set (match_operand:XF 0 "register_operand" "=f")
17427         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17428                     (match_operand:XF 3 "register_operand" "1")]
17429                    UNSPEC_FPREM1_F))
17430    (set (match_operand:XF 1 "register_operand" "=u")
17431         (unspec:XF [(match_dup 2) (match_dup 3)]
17432                    UNSPEC_FPREM1_U))
17433    (set (reg:CCFP FPSR_REG)
17434         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17435                      UNSPEC_C2_FLAG))]
17436   "TARGET_USE_FANCY_MATH_387"
17437   "fprem1"
17438   [(set_attr "type" "fpspc")
17439    (set_attr "mode" "XF")])
17440
17441 (define_expand "remainderxf3"
17442   [(use (match_operand:XF 0 "register_operand" ""))
17443    (use (match_operand:XF 1 "general_operand" ""))
17444    (use (match_operand:XF 2 "general_operand" ""))]
17445   "TARGET_USE_FANCY_MATH_387"
17446 {
17447   rtx label = gen_label_rtx ();
17448
17449   rtx op1 = gen_reg_rtx (XFmode);
17450   rtx op2 = gen_reg_rtx (XFmode);
17451
17452   emit_move_insn (op2, operands[2]);
17453   emit_move_insn (op1, operands[1]);
17454
17455   emit_label (label);
17456   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17457   ix86_emit_fp_unordered_jump (label);
17458   LABEL_NUSES (label) = 1;
17459
17460   emit_move_insn (operands[0], op1);
17461   DONE;
17462 })
17463
17464 (define_expand "remainder<mode>3"
17465   [(use (match_operand:MODEF 0 "register_operand" ""))
17466    (use (match_operand:MODEF 1 "general_operand" ""))
17467    (use (match_operand:MODEF 2 "general_operand" ""))]
17468   "TARGET_USE_FANCY_MATH_387"
17469 {
17470   rtx label = gen_label_rtx ();
17471
17472   rtx op1 = gen_reg_rtx (XFmode);
17473   rtx op2 = gen_reg_rtx (XFmode);
17474
17475   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17476   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17477
17478   emit_label (label);
17479
17480   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17481   ix86_emit_fp_unordered_jump (label);
17482   LABEL_NUSES (label) = 1;
17483
17484   /* Truncate the result properly for strict SSE math.  */
17485   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17486       && !TARGET_MIX_SSE_I387)
17487     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17488   else
17489     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17490
17491   DONE;
17492 })
17493
17494 (define_insn "*sinxf2_i387"
17495   [(set (match_operand:XF 0 "register_operand" "=f")
17496         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17497   "TARGET_USE_FANCY_MATH_387
17498    && flag_unsafe_math_optimizations"
17499   "fsin"
17500   [(set_attr "type" "fpspc")
17501    (set_attr "mode" "XF")])
17502
17503 (define_insn "*sin_extend<mode>xf2_i387"
17504   [(set (match_operand:XF 0 "register_operand" "=f")
17505         (unspec:XF [(float_extend:XF
17506                       (match_operand:MODEF 1 "register_operand" "0"))]
17507                    UNSPEC_SIN))]
17508   "TARGET_USE_FANCY_MATH_387
17509    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17510        || TARGET_MIX_SSE_I387)
17511    && flag_unsafe_math_optimizations"
17512   "fsin"
17513   [(set_attr "type" "fpspc")
17514    (set_attr "mode" "XF")])
17515
17516 (define_insn "*cosxf2_i387"
17517   [(set (match_operand:XF 0 "register_operand" "=f")
17518         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17519   "TARGET_USE_FANCY_MATH_387
17520    && flag_unsafe_math_optimizations"
17521   "fcos"
17522   [(set_attr "type" "fpspc")
17523    (set_attr "mode" "XF")])
17524
17525 (define_insn "*cos_extend<mode>xf2_i387"
17526   [(set (match_operand:XF 0 "register_operand" "=f")
17527         (unspec:XF [(float_extend:XF
17528                       (match_operand:MODEF 1 "register_operand" "0"))]
17529                    UNSPEC_COS))]
17530   "TARGET_USE_FANCY_MATH_387
17531    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17532        || TARGET_MIX_SSE_I387)
17533    && flag_unsafe_math_optimizations"
17534   "fcos"
17535   [(set_attr "type" "fpspc")
17536    (set_attr "mode" "XF")])
17537
17538 ;; When sincos pattern is defined, sin and cos builtin functions will be
17539 ;; expanded to sincos pattern with one of its outputs left unused.
17540 ;; CSE pass will figure out if two sincos patterns can be combined,
17541 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17542 ;; depending on the unused output.
17543
17544 (define_insn "sincosxf3"
17545   [(set (match_operand:XF 0 "register_operand" "=f")
17546         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17547                    UNSPEC_SINCOS_COS))
17548    (set (match_operand:XF 1 "register_operand" "=u")
17549         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17550   "TARGET_USE_FANCY_MATH_387
17551    && flag_unsafe_math_optimizations"
17552   "fsincos"
17553   [(set_attr "type" "fpspc")
17554    (set_attr "mode" "XF")])
17555
17556 (define_split
17557   [(set (match_operand:XF 0 "register_operand" "")
17558         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17559                    UNSPEC_SINCOS_COS))
17560    (set (match_operand:XF 1 "register_operand" "")
17561         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17562   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17563    && !(reload_completed || reload_in_progress)"
17564   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17565   "")
17566
17567 (define_split
17568   [(set (match_operand:XF 0 "register_operand" "")
17569         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17570                    UNSPEC_SINCOS_COS))
17571    (set (match_operand:XF 1 "register_operand" "")
17572         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17573   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17574    && !(reload_completed || reload_in_progress)"
17575   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17576   "")
17577
17578 (define_insn "sincos_extend<mode>xf3_i387"
17579   [(set (match_operand:XF 0 "register_operand" "=f")
17580         (unspec:XF [(float_extend:XF
17581                       (match_operand:MODEF 2 "register_operand" "0"))]
17582                    UNSPEC_SINCOS_COS))
17583    (set (match_operand:XF 1 "register_operand" "=u")
17584         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17585   "TARGET_USE_FANCY_MATH_387
17586    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17587        || TARGET_MIX_SSE_I387)
17588    && flag_unsafe_math_optimizations"
17589   "fsincos"
17590   [(set_attr "type" "fpspc")
17591    (set_attr "mode" "XF")])
17592
17593 (define_split
17594   [(set (match_operand:XF 0 "register_operand" "")
17595         (unspec:XF [(float_extend:XF
17596                       (match_operand:MODEF 2 "register_operand" ""))]
17597                    UNSPEC_SINCOS_COS))
17598    (set (match_operand:XF 1 "register_operand" "")
17599         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17600   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17601    && !(reload_completed || reload_in_progress)"
17602   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17603   "")
17604
17605 (define_split
17606   [(set (match_operand:XF 0 "register_operand" "")
17607         (unspec:XF [(float_extend:XF
17608                       (match_operand:MODEF 2 "register_operand" ""))]
17609                    UNSPEC_SINCOS_COS))
17610    (set (match_operand:XF 1 "register_operand" "")
17611         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17612   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17613    && !(reload_completed || reload_in_progress)"
17614   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17615   "")
17616
17617 (define_expand "sincos<mode>3"
17618   [(use (match_operand:MODEF 0 "register_operand" ""))
17619    (use (match_operand:MODEF 1 "register_operand" ""))
17620    (use (match_operand:MODEF 2 "register_operand" ""))]
17621   "TARGET_USE_FANCY_MATH_387
17622    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17623        || TARGET_MIX_SSE_I387)
17624    && flag_unsafe_math_optimizations"
17625 {
17626   rtx op0 = gen_reg_rtx (XFmode);
17627   rtx op1 = gen_reg_rtx (XFmode);
17628
17629   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17630   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17632   DONE;
17633 })
17634
17635 (define_insn "fptanxf4_i387"
17636   [(set (match_operand:XF 0 "register_operand" "=f")
17637         (match_operand:XF 3 "const_double_operand" "F"))
17638    (set (match_operand:XF 1 "register_operand" "=u")
17639         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17640                    UNSPEC_TAN))]
17641   "TARGET_USE_FANCY_MATH_387
17642    && flag_unsafe_math_optimizations
17643    && standard_80387_constant_p (operands[3]) == 2"
17644   "fptan"
17645   [(set_attr "type" "fpspc")
17646    (set_attr "mode" "XF")])
17647
17648 (define_insn "fptan_extend<mode>xf4_i387"
17649   [(set (match_operand:MODEF 0 "register_operand" "=f")
17650         (match_operand:MODEF 3 "const_double_operand" "F"))
17651    (set (match_operand:XF 1 "register_operand" "=u")
17652         (unspec:XF [(float_extend:XF
17653                       (match_operand:MODEF 2 "register_operand" "0"))]
17654                    UNSPEC_TAN))]
17655   "TARGET_USE_FANCY_MATH_387
17656    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17657        || TARGET_MIX_SSE_I387)
17658    && flag_unsafe_math_optimizations
17659    && standard_80387_constant_p (operands[3]) == 2"
17660   "fptan"
17661   [(set_attr "type" "fpspc")
17662    (set_attr "mode" "XF")])
17663
17664 (define_expand "tanxf2"
17665   [(use (match_operand:XF 0 "register_operand" ""))
17666    (use (match_operand:XF 1 "register_operand" ""))]
17667   "TARGET_USE_FANCY_MATH_387
17668    && flag_unsafe_math_optimizations"
17669 {
17670   rtx one = gen_reg_rtx (XFmode);
17671   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17672
17673   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17674   DONE;
17675 })
17676
17677 (define_expand "tan<mode>2"
17678   [(use (match_operand:MODEF 0 "register_operand" ""))
17679    (use (match_operand:MODEF 1 "register_operand" ""))]
17680   "TARGET_USE_FANCY_MATH_387
17681    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17682        || TARGET_MIX_SSE_I387)
17683    && flag_unsafe_math_optimizations"
17684 {
17685   rtx op0 = gen_reg_rtx (XFmode);
17686
17687   rtx one = gen_reg_rtx (<MODE>mode);
17688   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17689
17690   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17691                                              operands[1], op2));
17692   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17693   DONE;
17694 })
17695
17696 (define_insn "*fpatanxf3_i387"
17697   [(set (match_operand:XF 0 "register_operand" "=f")
17698         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17699                     (match_operand:XF 2 "register_operand" "u")]
17700                    UNSPEC_FPATAN))
17701    (clobber (match_scratch:XF 3 "=2"))]
17702   "TARGET_USE_FANCY_MATH_387
17703    && flag_unsafe_math_optimizations"
17704   "fpatan"
17705   [(set_attr "type" "fpspc")
17706    (set_attr "mode" "XF")])
17707
17708 (define_insn "fpatan_extend<mode>xf3_i387"
17709   [(set (match_operand:XF 0 "register_operand" "=f")
17710         (unspec:XF [(float_extend:XF
17711                       (match_operand:MODEF 1 "register_operand" "0"))
17712                     (float_extend:XF
17713                       (match_operand:MODEF 2 "register_operand" "u"))]
17714                    UNSPEC_FPATAN))
17715    (clobber (match_scratch:XF 3 "=2"))]
17716   "TARGET_USE_FANCY_MATH_387
17717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17718        || TARGET_MIX_SSE_I387)
17719    && flag_unsafe_math_optimizations"
17720   "fpatan"
17721   [(set_attr "type" "fpspc")
17722    (set_attr "mode" "XF")])
17723
17724 (define_expand "atan2xf3"
17725   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17726                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17727                                (match_operand:XF 1 "register_operand" "")]
17728                               UNSPEC_FPATAN))
17729               (clobber (match_scratch:XF 3 ""))])]
17730   "TARGET_USE_FANCY_MATH_387
17731    && flag_unsafe_math_optimizations"
17732   "")
17733
17734 (define_expand "atan2<mode>3"
17735   [(use (match_operand:MODEF 0 "register_operand" ""))
17736    (use (match_operand:MODEF 1 "register_operand" ""))
17737    (use (match_operand:MODEF 2 "register_operand" ""))]
17738   "TARGET_USE_FANCY_MATH_387
17739    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17740        || TARGET_MIX_SSE_I387)
17741    && flag_unsafe_math_optimizations"
17742 {
17743   rtx op0 = gen_reg_rtx (XFmode);
17744
17745   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17746   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17747   DONE;
17748 })
17749
17750 (define_expand "atanxf2"
17751   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17752                    (unspec:XF [(match_dup 2)
17753                                (match_operand:XF 1 "register_operand" "")]
17754                               UNSPEC_FPATAN))
17755               (clobber (match_scratch:XF 3 ""))])]
17756   "TARGET_USE_FANCY_MATH_387
17757    && flag_unsafe_math_optimizations"
17758 {
17759   operands[2] = gen_reg_rtx (XFmode);
17760   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17761 })
17762
17763 (define_expand "atan<mode>2"
17764   [(use (match_operand:MODEF 0 "register_operand" ""))
17765    (use (match_operand:MODEF 1 "register_operand" ""))]
17766   "TARGET_USE_FANCY_MATH_387
17767    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17768        || TARGET_MIX_SSE_I387)
17769    && flag_unsafe_math_optimizations"
17770 {
17771   rtx op0 = gen_reg_rtx (XFmode);
17772
17773   rtx op2 = gen_reg_rtx (<MODE>mode);
17774   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17775
17776   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17777   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17778   DONE;
17779 })
17780
17781 (define_expand "asinxf2"
17782   [(set (match_dup 2)
17783         (mult:XF (match_operand:XF 1 "register_operand" "")
17784                  (match_dup 1)))
17785    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17786    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17787    (parallel [(set (match_operand:XF 0 "register_operand" "")
17788                    (unspec:XF [(match_dup 5) (match_dup 1)]
17789                               UNSPEC_FPATAN))
17790               (clobber (match_scratch:XF 6 ""))])]
17791   "TARGET_USE_FANCY_MATH_387
17792    && flag_unsafe_math_optimizations"
17793 {
17794   int i;
17795
17796   if (optimize_insn_for_size_p ())
17797     FAIL;
17798
17799   for (i = 2; i < 6; i++)
17800     operands[i] = gen_reg_rtx (XFmode);
17801
17802   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17803 })
17804
17805 (define_expand "asin<mode>2"
17806   [(use (match_operand:MODEF 0 "register_operand" ""))
17807    (use (match_operand:MODEF 1 "general_operand" ""))]
17808  "TARGET_USE_FANCY_MATH_387
17809    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17810        || TARGET_MIX_SSE_I387)
17811    && flag_unsafe_math_optimizations"
17812 {
17813   rtx op0 = gen_reg_rtx (XFmode);
17814   rtx op1 = gen_reg_rtx (XFmode);
17815
17816   if (optimize_insn_for_size_p ())
17817     FAIL;
17818
17819   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17820   emit_insn (gen_asinxf2 (op0, op1));
17821   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17822   DONE;
17823 })
17824
17825 (define_expand "acosxf2"
17826   [(set (match_dup 2)
17827         (mult:XF (match_operand:XF 1 "register_operand" "")
17828                  (match_dup 1)))
17829    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17830    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17831    (parallel [(set (match_operand:XF 0 "register_operand" "")
17832                    (unspec:XF [(match_dup 1) (match_dup 5)]
17833                               UNSPEC_FPATAN))
17834               (clobber (match_scratch:XF 6 ""))])]
17835   "TARGET_USE_FANCY_MATH_387
17836    && flag_unsafe_math_optimizations"
17837 {
17838   int i;
17839
17840   if (optimize_insn_for_size_p ())
17841     FAIL;
17842
17843   for (i = 2; i < 6; i++)
17844     operands[i] = gen_reg_rtx (XFmode);
17845
17846   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17847 })
17848
17849 (define_expand "acos<mode>2"
17850   [(use (match_operand:MODEF 0 "register_operand" ""))
17851    (use (match_operand:MODEF 1 "general_operand" ""))]
17852  "TARGET_USE_FANCY_MATH_387
17853    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17854        || TARGET_MIX_SSE_I387)
17855    && flag_unsafe_math_optimizations"
17856 {
17857   rtx op0 = gen_reg_rtx (XFmode);
17858   rtx op1 = gen_reg_rtx (XFmode);
17859
17860   if (optimize_insn_for_size_p ())
17861     FAIL;
17862
17863   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17864   emit_insn (gen_acosxf2 (op0, op1));
17865   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17866   DONE;
17867 })
17868
17869 (define_insn "fyl2xxf3_i387"
17870   [(set (match_operand:XF 0 "register_operand" "=f")
17871         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17872                     (match_operand:XF 2 "register_operand" "u")]
17873                    UNSPEC_FYL2X))
17874    (clobber (match_scratch:XF 3 "=2"))]
17875   "TARGET_USE_FANCY_MATH_387
17876    && flag_unsafe_math_optimizations"
17877   "fyl2x"
17878   [(set_attr "type" "fpspc")
17879    (set_attr "mode" "XF")])
17880
17881 (define_insn "fyl2x_extend<mode>xf3_i387"
17882   [(set (match_operand:XF 0 "register_operand" "=f")
17883         (unspec:XF [(float_extend:XF
17884                       (match_operand:MODEF 1 "register_operand" "0"))
17885                     (match_operand:XF 2 "register_operand" "u")]
17886                    UNSPEC_FYL2X))
17887    (clobber (match_scratch:XF 3 "=2"))]
17888   "TARGET_USE_FANCY_MATH_387
17889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17890        || TARGET_MIX_SSE_I387)
17891    && flag_unsafe_math_optimizations"
17892   "fyl2x"
17893   [(set_attr "type" "fpspc")
17894    (set_attr "mode" "XF")])
17895
17896 (define_expand "logxf2"
17897   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17898                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17899                                (match_dup 2)] UNSPEC_FYL2X))
17900               (clobber (match_scratch:XF 3 ""))])]
17901   "TARGET_USE_FANCY_MATH_387
17902    && flag_unsafe_math_optimizations"
17903 {
17904   operands[2] = gen_reg_rtx (XFmode);
17905   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17906 })
17907
17908 (define_expand "log<mode>2"
17909   [(use (match_operand:MODEF 0 "register_operand" ""))
17910    (use (match_operand:MODEF 1 "register_operand" ""))]
17911   "TARGET_USE_FANCY_MATH_387
17912    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17913        || TARGET_MIX_SSE_I387)
17914    && flag_unsafe_math_optimizations"
17915 {
17916   rtx op0 = gen_reg_rtx (XFmode);
17917
17918   rtx op2 = gen_reg_rtx (XFmode);
17919   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17920
17921   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17922   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17923   DONE;
17924 })
17925
17926 (define_expand "log10xf2"
17927   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17928                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17929                                (match_dup 2)] UNSPEC_FYL2X))
17930               (clobber (match_scratch:XF 3 ""))])]
17931   "TARGET_USE_FANCY_MATH_387
17932    && flag_unsafe_math_optimizations"
17933 {
17934   operands[2] = gen_reg_rtx (XFmode);
17935   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17936 })
17937
17938 (define_expand "log10<mode>2"
17939   [(use (match_operand:MODEF 0 "register_operand" ""))
17940    (use (match_operand:MODEF 1 "register_operand" ""))]
17941   "TARGET_USE_FANCY_MATH_387
17942    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17943        || TARGET_MIX_SSE_I387)
17944    && flag_unsafe_math_optimizations"
17945 {
17946   rtx op0 = gen_reg_rtx (XFmode);
17947
17948   rtx op2 = gen_reg_rtx (XFmode);
17949   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17950
17951   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17952   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17953   DONE;
17954 })
17955
17956 (define_expand "log2xf2"
17957   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17958                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17959                                (match_dup 2)] UNSPEC_FYL2X))
17960               (clobber (match_scratch:XF 3 ""))])]
17961   "TARGET_USE_FANCY_MATH_387
17962    && flag_unsafe_math_optimizations"
17963 {
17964   operands[2] = gen_reg_rtx (XFmode);
17965   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17966 })
17967
17968 (define_expand "log2<mode>2"
17969   [(use (match_operand:MODEF 0 "register_operand" ""))
17970    (use (match_operand:MODEF 1 "register_operand" ""))]
17971   "TARGET_USE_FANCY_MATH_387
17972    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17973        || TARGET_MIX_SSE_I387)
17974    && flag_unsafe_math_optimizations"
17975 {
17976   rtx op0 = gen_reg_rtx (XFmode);
17977
17978   rtx op2 = gen_reg_rtx (XFmode);
17979   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17980
17981   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17982   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17983   DONE;
17984 })
17985
17986 (define_insn "fyl2xp1xf3_i387"
17987   [(set (match_operand:XF 0 "register_operand" "=f")
17988         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17989                     (match_operand:XF 2 "register_operand" "u")]
17990                    UNSPEC_FYL2XP1))
17991    (clobber (match_scratch:XF 3 "=2"))]
17992   "TARGET_USE_FANCY_MATH_387
17993    && flag_unsafe_math_optimizations"
17994   "fyl2xp1"
17995   [(set_attr "type" "fpspc")
17996    (set_attr "mode" "XF")])
17997
17998 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17999   [(set (match_operand:XF 0 "register_operand" "=f")
18000         (unspec:XF [(float_extend:XF
18001                       (match_operand:MODEF 1 "register_operand" "0"))
18002                     (match_operand:XF 2 "register_operand" "u")]
18003                    UNSPEC_FYL2XP1))
18004    (clobber (match_scratch:XF 3 "=2"))]
18005   "TARGET_USE_FANCY_MATH_387
18006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18007        || TARGET_MIX_SSE_I387)
18008    && flag_unsafe_math_optimizations"
18009   "fyl2xp1"
18010   [(set_attr "type" "fpspc")
18011    (set_attr "mode" "XF")])
18012
18013 (define_expand "log1pxf2"
18014   [(use (match_operand:XF 0 "register_operand" ""))
18015    (use (match_operand:XF 1 "register_operand" ""))]
18016   "TARGET_USE_FANCY_MATH_387
18017    && flag_unsafe_math_optimizations"
18018 {
18019   if (optimize_insn_for_size_p ())
18020     FAIL;
18021
18022   ix86_emit_i387_log1p (operands[0], operands[1]);
18023   DONE;
18024 })
18025
18026 (define_expand "log1p<mode>2"
18027   [(use (match_operand:MODEF 0 "register_operand" ""))
18028    (use (match_operand:MODEF 1 "register_operand" ""))]
18029   "TARGET_USE_FANCY_MATH_387
18030    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18031        || TARGET_MIX_SSE_I387)
18032    && flag_unsafe_math_optimizations"
18033 {
18034   rtx op0;
18035
18036   if (optimize_insn_for_size_p ())
18037     FAIL;
18038
18039   op0 = gen_reg_rtx (XFmode);
18040
18041   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18042
18043   ix86_emit_i387_log1p (op0, operands[1]);
18044   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18045   DONE;
18046 })
18047
18048 (define_insn "fxtractxf3_i387"
18049   [(set (match_operand:XF 0 "register_operand" "=f")
18050         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18051                    UNSPEC_XTRACT_FRACT))
18052    (set (match_operand:XF 1 "register_operand" "=u")
18053         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18054   "TARGET_USE_FANCY_MATH_387
18055    && flag_unsafe_math_optimizations"
18056   "fxtract"
18057   [(set_attr "type" "fpspc")
18058    (set_attr "mode" "XF")])
18059
18060 (define_insn "fxtract_extend<mode>xf3_i387"
18061   [(set (match_operand:XF 0 "register_operand" "=f")
18062         (unspec:XF [(float_extend:XF
18063                       (match_operand:MODEF 2 "register_operand" "0"))]
18064                    UNSPEC_XTRACT_FRACT))
18065    (set (match_operand:XF 1 "register_operand" "=u")
18066         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18067   "TARGET_USE_FANCY_MATH_387
18068    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18069        || TARGET_MIX_SSE_I387)
18070    && flag_unsafe_math_optimizations"
18071   "fxtract"
18072   [(set_attr "type" "fpspc")
18073    (set_attr "mode" "XF")])
18074
18075 (define_expand "logbxf2"
18076   [(parallel [(set (match_dup 2)
18077                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18078                               UNSPEC_XTRACT_FRACT))
18079               (set (match_operand:XF 0 "register_operand" "")
18080                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18081   "TARGET_USE_FANCY_MATH_387
18082    && flag_unsafe_math_optimizations"
18083 {
18084   operands[2] = gen_reg_rtx (XFmode);
18085 })
18086
18087 (define_expand "logb<mode>2"
18088   [(use (match_operand:MODEF 0 "register_operand" ""))
18089    (use (match_operand:MODEF 1 "register_operand" ""))]
18090   "TARGET_USE_FANCY_MATH_387
18091    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18092        || TARGET_MIX_SSE_I387)
18093    && flag_unsafe_math_optimizations"
18094 {
18095   rtx op0 = gen_reg_rtx (XFmode);
18096   rtx op1 = gen_reg_rtx (XFmode);
18097
18098   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18099   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18100   DONE;
18101 })
18102
18103 (define_expand "ilogbxf2"
18104   [(use (match_operand:SI 0 "register_operand" ""))
18105    (use (match_operand:XF 1 "register_operand" ""))]
18106   "TARGET_USE_FANCY_MATH_387
18107    && flag_unsafe_math_optimizations"
18108 {
18109   rtx op0, op1;
18110
18111   if (optimize_insn_for_size_p ())
18112     FAIL;
18113
18114   op0 = gen_reg_rtx (XFmode);
18115   op1 = gen_reg_rtx (XFmode);
18116
18117   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18118   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18119   DONE;
18120 })
18121
18122 (define_expand "ilogb<mode>2"
18123   [(use (match_operand:SI 0 "register_operand" ""))
18124    (use (match_operand:MODEF 1 "register_operand" ""))]
18125   "TARGET_USE_FANCY_MATH_387
18126    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18127        || TARGET_MIX_SSE_I387)
18128    && flag_unsafe_math_optimizations"
18129 {
18130   rtx op0, op1;
18131
18132   if (optimize_insn_for_size_p ())
18133     FAIL;
18134
18135   op0 = gen_reg_rtx (XFmode);
18136   op1 = gen_reg_rtx (XFmode);
18137
18138   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18139   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18140   DONE;
18141 })
18142
18143 (define_insn "*f2xm1xf2_i387"
18144   [(set (match_operand:XF 0 "register_operand" "=f")
18145         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18146                    UNSPEC_F2XM1))]
18147   "TARGET_USE_FANCY_MATH_387
18148    && flag_unsafe_math_optimizations"
18149   "f2xm1"
18150   [(set_attr "type" "fpspc")
18151    (set_attr "mode" "XF")])
18152
18153 (define_insn "*fscalexf4_i387"
18154   [(set (match_operand:XF 0 "register_operand" "=f")
18155         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18156                     (match_operand:XF 3 "register_operand" "1")]
18157                    UNSPEC_FSCALE_FRACT))
18158    (set (match_operand:XF 1 "register_operand" "=u")
18159         (unspec:XF [(match_dup 2) (match_dup 3)]
18160                    UNSPEC_FSCALE_EXP))]
18161   "TARGET_USE_FANCY_MATH_387
18162    && flag_unsafe_math_optimizations"
18163   "fscale"
18164   [(set_attr "type" "fpspc")
18165    (set_attr "mode" "XF")])
18166
18167 (define_expand "expNcorexf3"
18168   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18169                                (match_operand:XF 2 "register_operand" "")))
18170    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18171    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18172    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18173    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18174    (parallel [(set (match_operand:XF 0 "register_operand" "")
18175                    (unspec:XF [(match_dup 8) (match_dup 4)]
18176                               UNSPEC_FSCALE_FRACT))
18177               (set (match_dup 9)
18178                    (unspec:XF [(match_dup 8) (match_dup 4)]
18179                               UNSPEC_FSCALE_EXP))])]
18180   "TARGET_USE_FANCY_MATH_387
18181    && flag_unsafe_math_optimizations"
18182 {
18183   int i;
18184
18185   if (optimize_insn_for_size_p ())
18186     FAIL;
18187
18188   for (i = 3; i < 10; i++)
18189     operands[i] = gen_reg_rtx (XFmode);
18190
18191   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
18192 })
18193
18194 (define_expand "expxf2"
18195   [(use (match_operand:XF 0 "register_operand" ""))
18196    (use (match_operand:XF 1 "register_operand" ""))]
18197   "TARGET_USE_FANCY_MATH_387
18198    && flag_unsafe_math_optimizations"
18199 {
18200   rtx op2;
18201
18202   if (optimize_insn_for_size_p ())
18203     FAIL;
18204
18205   op2 = gen_reg_rtx (XFmode);
18206   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18207
18208   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18209   DONE;
18210 })
18211
18212 (define_expand "exp<mode>2"
18213   [(use (match_operand:MODEF 0 "register_operand" ""))
18214    (use (match_operand:MODEF 1 "general_operand" ""))]
18215  "TARGET_USE_FANCY_MATH_387
18216    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18217        || TARGET_MIX_SSE_I387)
18218    && flag_unsafe_math_optimizations"
18219 {
18220   rtx op0, op1;
18221
18222   if (optimize_insn_for_size_p ())
18223     FAIL;
18224
18225   op0 = gen_reg_rtx (XFmode);
18226   op1 = gen_reg_rtx (XFmode);
18227
18228   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18229   emit_insn (gen_expxf2 (op0, op1));
18230   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18231   DONE;
18232 })
18233
18234 (define_expand "exp10xf2"
18235   [(use (match_operand:XF 0 "register_operand" ""))
18236    (use (match_operand:XF 1 "register_operand" ""))]
18237   "TARGET_USE_FANCY_MATH_387
18238    && flag_unsafe_math_optimizations"
18239 {
18240   rtx op2;
18241
18242   if (optimize_insn_for_size_p ())
18243     FAIL;
18244
18245   op2 = gen_reg_rtx (XFmode);
18246   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18247
18248   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18249   DONE;
18250 })
18251
18252 (define_expand "exp10<mode>2"
18253   [(use (match_operand:MODEF 0 "register_operand" ""))
18254    (use (match_operand:MODEF 1 "general_operand" ""))]
18255  "TARGET_USE_FANCY_MATH_387
18256    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18257        || TARGET_MIX_SSE_I387)
18258    && flag_unsafe_math_optimizations"
18259 {
18260   rtx op0, op1;
18261
18262   if (optimize_insn_for_size_p ())
18263     FAIL;
18264
18265   op0 = gen_reg_rtx (XFmode);
18266   op1 = gen_reg_rtx (XFmode);
18267
18268   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18269   emit_insn (gen_exp10xf2 (op0, op1));
18270   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18271   DONE;
18272 })
18273
18274 (define_expand "exp2xf2"
18275   [(use (match_operand:XF 0 "register_operand" ""))
18276    (use (match_operand:XF 1 "register_operand" ""))]
18277   "TARGET_USE_FANCY_MATH_387
18278    && flag_unsafe_math_optimizations"
18279 {
18280   rtx op2;
18281
18282   if (optimize_insn_for_size_p ())
18283     FAIL;
18284
18285   op2 = gen_reg_rtx (XFmode);
18286   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
18287
18288   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18289   DONE;
18290 })
18291
18292 (define_expand "exp2<mode>2"
18293   [(use (match_operand:MODEF 0 "register_operand" ""))
18294    (use (match_operand:MODEF 1 "general_operand" ""))]
18295  "TARGET_USE_FANCY_MATH_387
18296    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18297        || TARGET_MIX_SSE_I387)
18298    && flag_unsafe_math_optimizations"
18299 {
18300   rtx op0, op1;
18301
18302   if (optimize_insn_for_size_p ())
18303     FAIL;
18304
18305   op0 = gen_reg_rtx (XFmode);
18306   op1 = gen_reg_rtx (XFmode);
18307
18308   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18309   emit_insn (gen_exp2xf2 (op0, op1));
18310   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18311   DONE;
18312 })
18313
18314 (define_expand "expm1xf2"
18315   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18316                                (match_dup 2)))
18317    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18318    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18319    (set (match_dup 9) (float_extend:XF (match_dup 13)))
18320    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18321    (parallel [(set (match_dup 7)
18322                    (unspec:XF [(match_dup 6) (match_dup 4)]
18323                               UNSPEC_FSCALE_FRACT))
18324               (set (match_dup 8)
18325                    (unspec:XF [(match_dup 6) (match_dup 4)]
18326                               UNSPEC_FSCALE_EXP))])
18327    (parallel [(set (match_dup 10)
18328                    (unspec:XF [(match_dup 9) (match_dup 8)]
18329                               UNSPEC_FSCALE_FRACT))
18330               (set (match_dup 11)
18331                    (unspec:XF [(match_dup 9) (match_dup 8)]
18332                               UNSPEC_FSCALE_EXP))])
18333    (set (match_dup 12) (minus:XF (match_dup 10)
18334                                  (float_extend:XF (match_dup 13))))
18335    (set (match_operand:XF 0 "register_operand" "")
18336         (plus:XF (match_dup 12) (match_dup 7)))]
18337   "TARGET_USE_FANCY_MATH_387
18338    && flag_unsafe_math_optimizations"
18339 {
18340   int i;
18341
18342   if (optimize_insn_for_size_p ())
18343     FAIL;
18344
18345   for (i = 2; i < 13; i++)
18346     operands[i] = gen_reg_rtx (XFmode);
18347
18348   operands[13]
18349     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18350
18351   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18352 })
18353
18354 (define_expand "expm1<mode>2"
18355   [(use (match_operand:MODEF 0 "register_operand" ""))
18356    (use (match_operand:MODEF 1 "general_operand" ""))]
18357  "TARGET_USE_FANCY_MATH_387
18358    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18359        || TARGET_MIX_SSE_I387)
18360    && flag_unsafe_math_optimizations"
18361 {
18362   rtx op0, op1;
18363
18364   if (optimize_insn_for_size_p ())
18365     FAIL;
18366
18367   op0 = gen_reg_rtx (XFmode);
18368   op1 = gen_reg_rtx (XFmode);
18369
18370   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18371   emit_insn (gen_expm1xf2 (op0, op1));
18372   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18373   DONE;
18374 })
18375
18376 (define_expand "ldexpxf3"
18377   [(set (match_dup 3)
18378         (float:XF (match_operand:SI 2 "register_operand" "")))
18379    (parallel [(set (match_operand:XF 0 " register_operand" "")
18380                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18381                                (match_dup 3)]
18382                               UNSPEC_FSCALE_FRACT))
18383               (set (match_dup 4)
18384                    (unspec:XF [(match_dup 1) (match_dup 3)]
18385                               UNSPEC_FSCALE_EXP))])]
18386   "TARGET_USE_FANCY_MATH_387
18387    && flag_unsafe_math_optimizations"
18388 {
18389   if (optimize_insn_for_size_p ())
18390     FAIL;
18391
18392   operands[3] = gen_reg_rtx (XFmode);
18393   operands[4] = gen_reg_rtx (XFmode);
18394 })
18395
18396 (define_expand "ldexp<mode>3"
18397   [(use (match_operand:MODEF 0 "register_operand" ""))
18398    (use (match_operand:MODEF 1 "general_operand" ""))
18399    (use (match_operand:SI 2 "register_operand" ""))]
18400  "TARGET_USE_FANCY_MATH_387
18401    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18402        || TARGET_MIX_SSE_I387)
18403    && flag_unsafe_math_optimizations"
18404 {
18405   rtx op0, op1;
18406
18407   if (optimize_insn_for_size_p ())
18408     FAIL;
18409
18410   op0 = gen_reg_rtx (XFmode);
18411   op1 = gen_reg_rtx (XFmode);
18412
18413   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18414   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18415   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18416   DONE;
18417 })
18418
18419 (define_expand "scalbxf3"
18420   [(parallel [(set (match_operand:XF 0 " register_operand" "")
18421                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18422                                (match_operand:XF 2 "register_operand" "")]
18423                               UNSPEC_FSCALE_FRACT))
18424               (set (match_dup 3)
18425                    (unspec:XF [(match_dup 1) (match_dup 2)]
18426                               UNSPEC_FSCALE_EXP))])]
18427   "TARGET_USE_FANCY_MATH_387
18428    && flag_unsafe_math_optimizations"
18429 {
18430   if (optimize_insn_for_size_p ())
18431     FAIL;
18432
18433   operands[3] = gen_reg_rtx (XFmode);
18434 })
18435
18436 (define_expand "scalb<mode>3"
18437   [(use (match_operand:MODEF 0 "register_operand" ""))
18438    (use (match_operand:MODEF 1 "general_operand" ""))
18439    (use (match_operand:MODEF 2 "general_operand" ""))]
18440  "TARGET_USE_FANCY_MATH_387
18441    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18442        || TARGET_MIX_SSE_I387)
18443    && flag_unsafe_math_optimizations"
18444 {
18445   rtx op0, op1, op2;
18446
18447   if (optimize_insn_for_size_p ())
18448     FAIL;
18449
18450   op0 = gen_reg_rtx (XFmode);
18451   op1 = gen_reg_rtx (XFmode);
18452   op2 = gen_reg_rtx (XFmode);
18453
18454   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18455   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18456   emit_insn (gen_scalbxf3 (op0, op1, op2));
18457   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18458   DONE;
18459 })
18460
18461 (define_expand "significandxf2"
18462   [(parallel [(set (match_operand:XF 0 "register_operand" "")
18463                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18464                               UNSPEC_XTRACT_FRACT))
18465               (set (match_dup 2)
18466                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18467   "TARGET_USE_FANCY_MATH_387
18468    && flag_unsafe_math_optimizations"
18469 {
18470   operands[2] = gen_reg_rtx (XFmode);
18471 })
18472
18473 (define_expand "significand<mode>2"
18474   [(use (match_operand:MODEF 0 "register_operand" ""))
18475    (use (match_operand:MODEF 1 "register_operand" ""))]
18476   "TARGET_USE_FANCY_MATH_387
18477    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18478        || TARGET_MIX_SSE_I387)
18479    && flag_unsafe_math_optimizations"
18480 {
18481   rtx op0 = gen_reg_rtx (XFmode);
18482   rtx op1 = gen_reg_rtx (XFmode);
18483
18484   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18485   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18486   DONE;
18487 })
18488 \f
18489
18490 (define_insn "sse4_1_round<mode>2"
18491   [(set (match_operand:MODEF 0 "register_operand" "=x")
18492         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18493                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
18494                       UNSPEC_ROUND))]
18495   "TARGET_ROUND"
18496   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18497   [(set_attr "type" "ssecvt")
18498    (set_attr "prefix_extra" "1")
18499    (set_attr "prefix" "maybe_vex")
18500    (set_attr "mode" "<MODE>")])
18501
18502 (define_insn "rintxf2"
18503   [(set (match_operand:XF 0 "register_operand" "=f")
18504         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18505                    UNSPEC_FRNDINT))]
18506   "TARGET_USE_FANCY_MATH_387
18507    && flag_unsafe_math_optimizations"
18508   "frndint"
18509   [(set_attr "type" "fpspc")
18510    (set_attr "mode" "XF")])
18511
18512 (define_expand "rint<mode>2"
18513   [(use (match_operand:MODEF 0 "register_operand" ""))
18514    (use (match_operand:MODEF 1 "register_operand" ""))]
18515   "(TARGET_USE_FANCY_MATH_387
18516     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18517         || TARGET_MIX_SSE_I387)
18518     && flag_unsafe_math_optimizations)
18519    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18520        && !flag_trapping_math)"
18521 {
18522   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18523       && !flag_trapping_math)
18524     {
18525       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18526         FAIL;
18527       if (TARGET_ROUND)
18528         emit_insn (gen_sse4_1_round<mode>2
18529                    (operands[0], operands[1], GEN_INT (0x04)));
18530       else
18531         ix86_expand_rint (operand0, operand1);
18532     }
18533   else
18534     {
18535       rtx op0 = gen_reg_rtx (XFmode);
18536       rtx op1 = gen_reg_rtx (XFmode);
18537
18538       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18539       emit_insn (gen_rintxf2 (op0, op1));
18540
18541       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18542     }
18543   DONE;
18544 })
18545
18546 (define_expand "round<mode>2"
18547   [(match_operand:MODEF 0 "register_operand" "")
18548    (match_operand:MODEF 1 "nonimmediate_operand" "")]
18549   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18550    && !flag_trapping_math && !flag_rounding_math"
18551 {
18552   if (optimize_insn_for_size_p ())
18553     FAIL;
18554   if (TARGET_64BIT || (<MODE>mode != DFmode))
18555     ix86_expand_round (operand0, operand1);
18556   else
18557     ix86_expand_rounddf_32 (operand0, operand1);
18558   DONE;
18559 })
18560
18561 (define_insn_and_split "*fistdi2_1"
18562   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18563         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18564                    UNSPEC_FIST))]
18565   "TARGET_USE_FANCY_MATH_387
18566    && !(reload_completed || reload_in_progress)"
18567   "#"
18568   "&& 1"
18569   [(const_int 0)]
18570 {
18571   if (memory_operand (operands[0], VOIDmode))
18572     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18573   else
18574     {
18575       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18576       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18577                                          operands[2]));
18578     }
18579   DONE;
18580 }
18581   [(set_attr "type" "fpspc")
18582    (set_attr "mode" "DI")])
18583
18584 (define_insn "fistdi2"
18585   [(set (match_operand:DI 0 "memory_operand" "=m")
18586         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18587                    UNSPEC_FIST))
18588    (clobber (match_scratch:XF 2 "=&1f"))]
18589   "TARGET_USE_FANCY_MATH_387"
18590   "* return output_fix_trunc (insn, operands, 0);"
18591   [(set_attr "type" "fpspc")
18592    (set_attr "mode" "DI")])
18593
18594 (define_insn "fistdi2_with_temp"
18595   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18596         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18597                    UNSPEC_FIST))
18598    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18599    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18600   "TARGET_USE_FANCY_MATH_387"
18601   "#"
18602   [(set_attr "type" "fpspc")
18603    (set_attr "mode" "DI")])
18604
18605 (define_split
18606   [(set (match_operand:DI 0 "register_operand" "")
18607         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18608                    UNSPEC_FIST))
18609    (clobber (match_operand:DI 2 "memory_operand" ""))
18610    (clobber (match_scratch 3 ""))]
18611   "reload_completed"
18612   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18613               (clobber (match_dup 3))])
18614    (set (match_dup 0) (match_dup 2))]
18615   "")
18616
18617 (define_split
18618   [(set (match_operand:DI 0 "memory_operand" "")
18619         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18620                    UNSPEC_FIST))
18621    (clobber (match_operand:DI 2 "memory_operand" ""))
18622    (clobber (match_scratch 3 ""))]
18623   "reload_completed"
18624   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18625               (clobber (match_dup 3))])]
18626   "")
18627
18628 (define_insn_and_split "*fist<mode>2_1"
18629   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18630         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18631                            UNSPEC_FIST))]
18632   "TARGET_USE_FANCY_MATH_387
18633    && !(reload_completed || reload_in_progress)"
18634   "#"
18635   "&& 1"
18636   [(const_int 0)]
18637 {
18638   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18639   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18640                                         operands[2]));
18641   DONE;
18642 }
18643   [(set_attr "type" "fpspc")
18644    (set_attr "mode" "<MODE>")])
18645
18646 (define_insn "fist<mode>2"
18647   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18648         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18649                            UNSPEC_FIST))]
18650   "TARGET_USE_FANCY_MATH_387"
18651   "* return output_fix_trunc (insn, operands, 0);"
18652   [(set_attr "type" "fpspc")
18653    (set_attr "mode" "<MODE>")])
18654
18655 (define_insn "fist<mode>2_with_temp"
18656   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18657         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18658                            UNSPEC_FIST))
18659    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18660   "TARGET_USE_FANCY_MATH_387"
18661   "#"
18662   [(set_attr "type" "fpspc")
18663    (set_attr "mode" "<MODE>")])
18664
18665 (define_split
18666   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18667         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18668                            UNSPEC_FIST))
18669    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18670   "reload_completed"
18671   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18672    (set (match_dup 0) (match_dup 2))]
18673   "")
18674
18675 (define_split
18676   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18677         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18678                            UNSPEC_FIST))
18679    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18680   "reload_completed"
18681   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18682   "")
18683
18684 (define_expand "lrintxf<mode>2"
18685   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18686      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18687                       UNSPEC_FIST))]
18688   "TARGET_USE_FANCY_MATH_387"
18689   "")
18690
18691 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18692   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18693      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18694                         UNSPEC_FIX_NOTRUNC))]
18695   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18696    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18697   "")
18698
18699 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18700   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18701    (match_operand:MODEF 1 "register_operand" "")]
18702   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18703    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18704    && !flag_trapping_math && !flag_rounding_math"
18705 {
18706   if (optimize_insn_for_size_p ())
18707     FAIL;
18708   ix86_expand_lround (operand0, operand1);
18709   DONE;
18710 })
18711
18712 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18713 (define_insn_and_split "frndintxf2_floor"
18714   [(set (match_operand:XF 0 "register_operand" "")
18715         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18716          UNSPEC_FRNDINT_FLOOR))
18717    (clobber (reg:CC FLAGS_REG))]
18718   "TARGET_USE_FANCY_MATH_387
18719    && flag_unsafe_math_optimizations
18720    && !(reload_completed || reload_in_progress)"
18721   "#"
18722   "&& 1"
18723   [(const_int 0)]
18724 {
18725   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18726
18727   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18728   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18729
18730   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18731                                         operands[2], operands[3]));
18732   DONE;
18733 }
18734   [(set_attr "type" "frndint")
18735    (set_attr "i387_cw" "floor")
18736    (set_attr "mode" "XF")])
18737
18738 (define_insn "frndintxf2_floor_i387"
18739   [(set (match_operand:XF 0 "register_operand" "=f")
18740         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18741          UNSPEC_FRNDINT_FLOOR))
18742    (use (match_operand:HI 2 "memory_operand" "m"))
18743    (use (match_operand:HI 3 "memory_operand" "m"))]
18744   "TARGET_USE_FANCY_MATH_387
18745    && flag_unsafe_math_optimizations"
18746   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18747   [(set_attr "type" "frndint")
18748    (set_attr "i387_cw" "floor")
18749    (set_attr "mode" "XF")])
18750
18751 (define_expand "floorxf2"
18752   [(use (match_operand:XF 0 "register_operand" ""))
18753    (use (match_operand:XF 1 "register_operand" ""))]
18754   "TARGET_USE_FANCY_MATH_387
18755    && flag_unsafe_math_optimizations"
18756 {
18757   if (optimize_insn_for_size_p ())
18758     FAIL;
18759   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18760   DONE;
18761 })
18762
18763 (define_expand "floor<mode>2"
18764   [(use (match_operand:MODEF 0 "register_operand" ""))
18765    (use (match_operand:MODEF 1 "register_operand" ""))]
18766   "(TARGET_USE_FANCY_MATH_387
18767     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18768         || TARGET_MIX_SSE_I387)
18769     && flag_unsafe_math_optimizations)
18770    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18771        && !flag_trapping_math)"
18772 {
18773   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18774       && !flag_trapping_math
18775       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18776     {
18777       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18778         FAIL;
18779       if (TARGET_ROUND)
18780         emit_insn (gen_sse4_1_round<mode>2
18781                    (operands[0], operands[1], GEN_INT (0x01)));
18782       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18783         ix86_expand_floorceil (operand0, operand1, true);
18784       else
18785         ix86_expand_floorceildf_32 (operand0, operand1, true);
18786     }
18787   else
18788     {
18789       rtx op0, op1;
18790
18791       if (optimize_insn_for_size_p ())
18792         FAIL;
18793
18794       op0 = gen_reg_rtx (XFmode);
18795       op1 = gen_reg_rtx (XFmode);
18796       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18797       emit_insn (gen_frndintxf2_floor (op0, op1));
18798
18799       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18800     }
18801   DONE;
18802 })
18803
18804 (define_insn_and_split "*fist<mode>2_floor_1"
18805   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18806         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18807          UNSPEC_FIST_FLOOR))
18808    (clobber (reg:CC FLAGS_REG))]
18809   "TARGET_USE_FANCY_MATH_387
18810    && flag_unsafe_math_optimizations
18811    && !(reload_completed || reload_in_progress)"
18812   "#"
18813   "&& 1"
18814   [(const_int 0)]
18815 {
18816   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18817
18818   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18819   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18820   if (memory_operand (operands[0], VOIDmode))
18821     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18822                                       operands[2], operands[3]));
18823   else
18824     {
18825       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18826       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18827                                                   operands[2], operands[3],
18828                                                   operands[4]));
18829     }
18830   DONE;
18831 }
18832   [(set_attr "type" "fistp")
18833    (set_attr "i387_cw" "floor")
18834    (set_attr "mode" "<MODE>")])
18835
18836 (define_insn "fistdi2_floor"
18837   [(set (match_operand:DI 0 "memory_operand" "=m")
18838         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18839          UNSPEC_FIST_FLOOR))
18840    (use (match_operand:HI 2 "memory_operand" "m"))
18841    (use (match_operand:HI 3 "memory_operand" "m"))
18842    (clobber (match_scratch:XF 4 "=&1f"))]
18843   "TARGET_USE_FANCY_MATH_387
18844    && flag_unsafe_math_optimizations"
18845   "* return output_fix_trunc (insn, operands, 0);"
18846   [(set_attr "type" "fistp")
18847    (set_attr "i387_cw" "floor")
18848    (set_attr "mode" "DI")])
18849
18850 (define_insn "fistdi2_floor_with_temp"
18851   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18852         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18853          UNSPEC_FIST_FLOOR))
18854    (use (match_operand:HI 2 "memory_operand" "m,m"))
18855    (use (match_operand:HI 3 "memory_operand" "m,m"))
18856    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18857    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18858   "TARGET_USE_FANCY_MATH_387
18859    && flag_unsafe_math_optimizations"
18860   "#"
18861   [(set_attr "type" "fistp")
18862    (set_attr "i387_cw" "floor")
18863    (set_attr "mode" "DI")])
18864
18865 (define_split
18866   [(set (match_operand:DI 0 "register_operand" "")
18867         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18868          UNSPEC_FIST_FLOOR))
18869    (use (match_operand:HI 2 "memory_operand" ""))
18870    (use (match_operand:HI 3 "memory_operand" ""))
18871    (clobber (match_operand:DI 4 "memory_operand" ""))
18872    (clobber (match_scratch 5 ""))]
18873   "reload_completed"
18874   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18875               (use (match_dup 2))
18876               (use (match_dup 3))
18877               (clobber (match_dup 5))])
18878    (set (match_dup 0) (match_dup 4))]
18879   "")
18880
18881 (define_split
18882   [(set (match_operand:DI 0 "memory_operand" "")
18883         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18884          UNSPEC_FIST_FLOOR))
18885    (use (match_operand:HI 2 "memory_operand" ""))
18886    (use (match_operand:HI 3 "memory_operand" ""))
18887    (clobber (match_operand:DI 4 "memory_operand" ""))
18888    (clobber (match_scratch 5 ""))]
18889   "reload_completed"
18890   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18891               (use (match_dup 2))
18892               (use (match_dup 3))
18893               (clobber (match_dup 5))])]
18894   "")
18895
18896 (define_insn "fist<mode>2_floor"
18897   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18898         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18899          UNSPEC_FIST_FLOOR))
18900    (use (match_operand:HI 2 "memory_operand" "m"))
18901    (use (match_operand:HI 3 "memory_operand" "m"))]
18902   "TARGET_USE_FANCY_MATH_387
18903    && flag_unsafe_math_optimizations"
18904   "* return output_fix_trunc (insn, operands, 0);"
18905   [(set_attr "type" "fistp")
18906    (set_attr "i387_cw" "floor")
18907    (set_attr "mode" "<MODE>")])
18908
18909 (define_insn "fist<mode>2_floor_with_temp"
18910   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18911         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18912          UNSPEC_FIST_FLOOR))
18913    (use (match_operand:HI 2 "memory_operand" "m,m"))
18914    (use (match_operand:HI 3 "memory_operand" "m,m"))
18915    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18916   "TARGET_USE_FANCY_MATH_387
18917    && flag_unsafe_math_optimizations"
18918   "#"
18919   [(set_attr "type" "fistp")
18920    (set_attr "i387_cw" "floor")
18921    (set_attr "mode" "<MODE>")])
18922
18923 (define_split
18924   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18925         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18926          UNSPEC_FIST_FLOOR))
18927    (use (match_operand:HI 2 "memory_operand" ""))
18928    (use (match_operand:HI 3 "memory_operand" ""))
18929    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18930   "reload_completed"
18931   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18932                                   UNSPEC_FIST_FLOOR))
18933               (use (match_dup 2))
18934               (use (match_dup 3))])
18935    (set (match_dup 0) (match_dup 4))]
18936   "")
18937
18938 (define_split
18939   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18940         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18941          UNSPEC_FIST_FLOOR))
18942    (use (match_operand:HI 2 "memory_operand" ""))
18943    (use (match_operand:HI 3 "memory_operand" ""))
18944    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18945   "reload_completed"
18946   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18947                                   UNSPEC_FIST_FLOOR))
18948               (use (match_dup 2))
18949               (use (match_dup 3))])]
18950   "")
18951
18952 (define_expand "lfloorxf<mode>2"
18953   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18954                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18955                     UNSPEC_FIST_FLOOR))
18956               (clobber (reg:CC FLAGS_REG))])]
18957   "TARGET_USE_FANCY_MATH_387
18958    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18959    && flag_unsafe_math_optimizations"
18960   "")
18961
18962 (define_expand "lfloor<mode>di2"
18963   [(match_operand:DI 0 "nonimmediate_operand" "")
18964    (match_operand:MODEF 1 "register_operand" "")]
18965   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18966    && !flag_trapping_math"
18967 {
18968   if (optimize_insn_for_size_p ())
18969     FAIL;
18970   ix86_expand_lfloorceil (operand0, operand1, true);
18971   DONE;
18972 })
18973
18974 (define_expand "lfloor<mode>si2"
18975   [(match_operand:SI 0 "nonimmediate_operand" "")
18976    (match_operand:MODEF 1 "register_operand" "")]
18977   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18978    && !flag_trapping_math"
18979 {
18980   if (optimize_insn_for_size_p () && TARGET_64BIT)
18981     FAIL;
18982   ix86_expand_lfloorceil (operand0, operand1, true);
18983   DONE;
18984 })
18985
18986 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18987 (define_insn_and_split "frndintxf2_ceil"
18988   [(set (match_operand:XF 0 "register_operand" "")
18989         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18990          UNSPEC_FRNDINT_CEIL))
18991    (clobber (reg:CC FLAGS_REG))]
18992   "TARGET_USE_FANCY_MATH_387
18993    && flag_unsafe_math_optimizations
18994    && !(reload_completed || reload_in_progress)"
18995   "#"
18996   "&& 1"
18997   [(const_int 0)]
18998 {
18999   ix86_optimize_mode_switching[I387_CEIL] = 1;
19000
19001   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19002   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19003
19004   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
19005                                        operands[2], operands[3]));
19006   DONE;
19007 }
19008   [(set_attr "type" "frndint")
19009    (set_attr "i387_cw" "ceil")
19010    (set_attr "mode" "XF")])
19011
19012 (define_insn "frndintxf2_ceil_i387"
19013   [(set (match_operand:XF 0 "register_operand" "=f")
19014         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19015          UNSPEC_FRNDINT_CEIL))
19016    (use (match_operand:HI 2 "memory_operand" "m"))
19017    (use (match_operand:HI 3 "memory_operand" "m"))]
19018   "TARGET_USE_FANCY_MATH_387
19019    && flag_unsafe_math_optimizations"
19020   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19021   [(set_attr "type" "frndint")
19022    (set_attr "i387_cw" "ceil")
19023    (set_attr "mode" "XF")])
19024
19025 (define_expand "ceilxf2"
19026   [(use (match_operand:XF 0 "register_operand" ""))
19027    (use (match_operand:XF 1 "register_operand" ""))]
19028   "TARGET_USE_FANCY_MATH_387
19029    && flag_unsafe_math_optimizations"
19030 {
19031   if (optimize_insn_for_size_p ())
19032     FAIL;
19033   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19034   DONE;
19035 })
19036
19037 (define_expand "ceil<mode>2"
19038   [(use (match_operand:MODEF 0 "register_operand" ""))
19039    (use (match_operand:MODEF 1 "register_operand" ""))]
19040   "(TARGET_USE_FANCY_MATH_387
19041     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19042         || TARGET_MIX_SSE_I387)
19043     && flag_unsafe_math_optimizations)
19044    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19045        && !flag_trapping_math)"
19046 {
19047   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19048       && !flag_trapping_math
19049       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19050     {
19051       if (TARGET_ROUND)
19052         emit_insn (gen_sse4_1_round<mode>2
19053                    (operands[0], operands[1], GEN_INT (0x02)));
19054       else if (optimize_insn_for_size_p ())
19055         FAIL;
19056       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19057         ix86_expand_floorceil (operand0, operand1, false);
19058       else
19059         ix86_expand_floorceildf_32 (operand0, operand1, false);
19060     }
19061   else
19062     {
19063       rtx op0, op1;
19064
19065       if (optimize_insn_for_size_p ())
19066         FAIL;
19067
19068       op0 = gen_reg_rtx (XFmode);
19069       op1 = gen_reg_rtx (XFmode);
19070       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19071       emit_insn (gen_frndintxf2_ceil (op0, op1));
19072
19073       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19074     }
19075   DONE;
19076 })
19077
19078 (define_insn_and_split "*fist<mode>2_ceil_1"
19079   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19080         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19081          UNSPEC_FIST_CEIL))
19082    (clobber (reg:CC FLAGS_REG))]
19083   "TARGET_USE_FANCY_MATH_387
19084    && flag_unsafe_math_optimizations
19085    && !(reload_completed || reload_in_progress)"
19086   "#"
19087   "&& 1"
19088   [(const_int 0)]
19089 {
19090   ix86_optimize_mode_switching[I387_CEIL] = 1;
19091
19092   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19093   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19094   if (memory_operand (operands[0], VOIDmode))
19095     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19096                                      operands[2], operands[3]));
19097   else
19098     {
19099       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19100       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19101                                                  operands[2], operands[3],
19102                                                  operands[4]));
19103     }
19104   DONE;
19105 }
19106   [(set_attr "type" "fistp")
19107    (set_attr "i387_cw" "ceil")
19108    (set_attr "mode" "<MODE>")])
19109
19110 (define_insn "fistdi2_ceil"
19111   [(set (match_operand:DI 0 "memory_operand" "=m")
19112         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19113          UNSPEC_FIST_CEIL))
19114    (use (match_operand:HI 2 "memory_operand" "m"))
19115    (use (match_operand:HI 3 "memory_operand" "m"))
19116    (clobber (match_scratch:XF 4 "=&1f"))]
19117   "TARGET_USE_FANCY_MATH_387
19118    && flag_unsafe_math_optimizations"
19119   "* return output_fix_trunc (insn, operands, 0);"
19120   [(set_attr "type" "fistp")
19121    (set_attr "i387_cw" "ceil")
19122    (set_attr "mode" "DI")])
19123
19124 (define_insn "fistdi2_ceil_with_temp"
19125   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19126         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19127          UNSPEC_FIST_CEIL))
19128    (use (match_operand:HI 2 "memory_operand" "m,m"))
19129    (use (match_operand:HI 3 "memory_operand" "m,m"))
19130    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19131    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19132   "TARGET_USE_FANCY_MATH_387
19133    && flag_unsafe_math_optimizations"
19134   "#"
19135   [(set_attr "type" "fistp")
19136    (set_attr "i387_cw" "ceil")
19137    (set_attr "mode" "DI")])
19138
19139 (define_split
19140   [(set (match_operand:DI 0 "register_operand" "")
19141         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19142          UNSPEC_FIST_CEIL))
19143    (use (match_operand:HI 2 "memory_operand" ""))
19144    (use (match_operand:HI 3 "memory_operand" ""))
19145    (clobber (match_operand:DI 4 "memory_operand" ""))
19146    (clobber (match_scratch 5 ""))]
19147   "reload_completed"
19148   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19149               (use (match_dup 2))
19150               (use (match_dup 3))
19151               (clobber (match_dup 5))])
19152    (set (match_dup 0) (match_dup 4))]
19153   "")
19154
19155 (define_split
19156   [(set (match_operand:DI 0 "memory_operand" "")
19157         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19158          UNSPEC_FIST_CEIL))
19159    (use (match_operand:HI 2 "memory_operand" ""))
19160    (use (match_operand:HI 3 "memory_operand" ""))
19161    (clobber (match_operand:DI 4 "memory_operand" ""))
19162    (clobber (match_scratch 5 ""))]
19163   "reload_completed"
19164   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19165               (use (match_dup 2))
19166               (use (match_dup 3))
19167               (clobber (match_dup 5))])]
19168   "")
19169
19170 (define_insn "fist<mode>2_ceil"
19171   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19172         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19173          UNSPEC_FIST_CEIL))
19174    (use (match_operand:HI 2 "memory_operand" "m"))
19175    (use (match_operand:HI 3 "memory_operand" "m"))]
19176   "TARGET_USE_FANCY_MATH_387
19177    && flag_unsafe_math_optimizations"
19178   "* return output_fix_trunc (insn, operands, 0);"
19179   [(set_attr "type" "fistp")
19180    (set_attr "i387_cw" "ceil")
19181    (set_attr "mode" "<MODE>")])
19182
19183 (define_insn "fist<mode>2_ceil_with_temp"
19184   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19185         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19186          UNSPEC_FIST_CEIL))
19187    (use (match_operand:HI 2 "memory_operand" "m,m"))
19188    (use (match_operand:HI 3 "memory_operand" "m,m"))
19189    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19190   "TARGET_USE_FANCY_MATH_387
19191    && flag_unsafe_math_optimizations"
19192   "#"
19193   [(set_attr "type" "fistp")
19194    (set_attr "i387_cw" "ceil")
19195    (set_attr "mode" "<MODE>")])
19196
19197 (define_split
19198   [(set (match_operand:X87MODEI12 0 "register_operand" "")
19199         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19200          UNSPEC_FIST_CEIL))
19201    (use (match_operand:HI 2 "memory_operand" ""))
19202    (use (match_operand:HI 3 "memory_operand" ""))
19203    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19204   "reload_completed"
19205   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19206                                   UNSPEC_FIST_CEIL))
19207               (use (match_dup 2))
19208               (use (match_dup 3))])
19209    (set (match_dup 0) (match_dup 4))]
19210   "")
19211
19212 (define_split
19213   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19214         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19215          UNSPEC_FIST_CEIL))
19216    (use (match_operand:HI 2 "memory_operand" ""))
19217    (use (match_operand:HI 3 "memory_operand" ""))
19218    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19219   "reload_completed"
19220   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19221                                   UNSPEC_FIST_CEIL))
19222               (use (match_dup 2))
19223               (use (match_dup 3))])]
19224   "")
19225
19226 (define_expand "lceilxf<mode>2"
19227   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19228                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19229                     UNSPEC_FIST_CEIL))
19230               (clobber (reg:CC FLAGS_REG))])]
19231   "TARGET_USE_FANCY_MATH_387
19232    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19233    && flag_unsafe_math_optimizations"
19234   "")
19235
19236 (define_expand "lceil<mode>di2"
19237   [(match_operand:DI 0 "nonimmediate_operand" "")
19238    (match_operand:MODEF 1 "register_operand" "")]
19239   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19240    && !flag_trapping_math"
19241 {
19242   ix86_expand_lfloorceil (operand0, operand1, false);
19243   DONE;
19244 })
19245
19246 (define_expand "lceil<mode>si2"
19247   [(match_operand:SI 0 "nonimmediate_operand" "")
19248    (match_operand:MODEF 1 "register_operand" "")]
19249   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19250    && !flag_trapping_math"
19251 {
19252   ix86_expand_lfloorceil (operand0, operand1, false);
19253   DONE;
19254 })
19255
19256 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19257 (define_insn_and_split "frndintxf2_trunc"
19258   [(set (match_operand:XF 0 "register_operand" "")
19259         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19260          UNSPEC_FRNDINT_TRUNC))
19261    (clobber (reg:CC FLAGS_REG))]
19262   "TARGET_USE_FANCY_MATH_387
19263    && flag_unsafe_math_optimizations
19264    && !(reload_completed || reload_in_progress)"
19265   "#"
19266   "&& 1"
19267   [(const_int 0)]
19268 {
19269   ix86_optimize_mode_switching[I387_TRUNC] = 1;
19270
19271   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19272   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19273
19274   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19275                                         operands[2], operands[3]));
19276   DONE;
19277 }
19278   [(set_attr "type" "frndint")
19279    (set_attr "i387_cw" "trunc")
19280    (set_attr "mode" "XF")])
19281
19282 (define_insn "frndintxf2_trunc_i387"
19283   [(set (match_operand:XF 0 "register_operand" "=f")
19284         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19285          UNSPEC_FRNDINT_TRUNC))
19286    (use (match_operand:HI 2 "memory_operand" "m"))
19287    (use (match_operand:HI 3 "memory_operand" "m"))]
19288   "TARGET_USE_FANCY_MATH_387
19289    && flag_unsafe_math_optimizations"
19290   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19291   [(set_attr "type" "frndint")
19292    (set_attr "i387_cw" "trunc")
19293    (set_attr "mode" "XF")])
19294
19295 (define_expand "btruncxf2"
19296   [(use (match_operand:XF 0 "register_operand" ""))
19297    (use (match_operand:XF 1 "register_operand" ""))]
19298   "TARGET_USE_FANCY_MATH_387
19299    && flag_unsafe_math_optimizations"
19300 {
19301   if (optimize_insn_for_size_p ())
19302     FAIL;
19303   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19304   DONE;
19305 })
19306
19307 (define_expand "btrunc<mode>2"
19308   [(use (match_operand:MODEF 0 "register_operand" ""))
19309    (use (match_operand:MODEF 1 "register_operand" ""))]
19310   "(TARGET_USE_FANCY_MATH_387
19311     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19312         || TARGET_MIX_SSE_I387)
19313     && flag_unsafe_math_optimizations)
19314    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19315        && !flag_trapping_math)"
19316 {
19317   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19318       && !flag_trapping_math
19319       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19320     {
19321       if (TARGET_ROUND)
19322         emit_insn (gen_sse4_1_round<mode>2
19323                    (operands[0], operands[1], GEN_INT (0x03)));
19324       else if (optimize_insn_for_size_p ())
19325         FAIL;
19326       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19327         ix86_expand_trunc (operand0, operand1);
19328       else
19329         ix86_expand_truncdf_32 (operand0, operand1);
19330     }
19331   else
19332     {
19333       rtx op0, op1;
19334
19335       if (optimize_insn_for_size_p ())
19336         FAIL;
19337
19338       op0 = gen_reg_rtx (XFmode);
19339       op1 = gen_reg_rtx (XFmode);
19340       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19341       emit_insn (gen_frndintxf2_trunc (op0, op1));
19342
19343       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19344     }
19345   DONE;
19346 })
19347
19348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19349 (define_insn_and_split "frndintxf2_mask_pm"
19350   [(set (match_operand:XF 0 "register_operand" "")
19351         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19352          UNSPEC_FRNDINT_MASK_PM))
19353    (clobber (reg:CC FLAGS_REG))]
19354   "TARGET_USE_FANCY_MATH_387
19355    && flag_unsafe_math_optimizations
19356    && !(reload_completed || reload_in_progress)"
19357   "#"
19358   "&& 1"
19359   [(const_int 0)]
19360 {
19361   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19362
19363   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19364   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19365
19366   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19367                                           operands[2], operands[3]));
19368   DONE;
19369 }
19370   [(set_attr "type" "frndint")
19371    (set_attr "i387_cw" "mask_pm")
19372    (set_attr "mode" "XF")])
19373
19374 (define_insn "frndintxf2_mask_pm_i387"
19375   [(set (match_operand:XF 0 "register_operand" "=f")
19376         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19377          UNSPEC_FRNDINT_MASK_PM))
19378    (use (match_operand:HI 2 "memory_operand" "m"))
19379    (use (match_operand:HI 3 "memory_operand" "m"))]
19380   "TARGET_USE_FANCY_MATH_387
19381    && flag_unsafe_math_optimizations"
19382   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19383   [(set_attr "type" "frndint")
19384    (set_attr "i387_cw" "mask_pm")
19385    (set_attr "mode" "XF")])
19386
19387 (define_expand "nearbyintxf2"
19388   [(use (match_operand:XF 0 "register_operand" ""))
19389    (use (match_operand:XF 1 "register_operand" ""))]
19390   "TARGET_USE_FANCY_MATH_387
19391    && flag_unsafe_math_optimizations"
19392 {
19393   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19394
19395   DONE;
19396 })
19397
19398 (define_expand "nearbyint<mode>2"
19399   [(use (match_operand:MODEF 0 "register_operand" ""))
19400    (use (match_operand:MODEF 1 "register_operand" ""))]
19401   "TARGET_USE_FANCY_MATH_387
19402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19403        || TARGET_MIX_SSE_I387)
19404    && flag_unsafe_math_optimizations"
19405 {
19406   rtx op0 = gen_reg_rtx (XFmode);
19407   rtx op1 = gen_reg_rtx (XFmode);
19408
19409   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19410   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19411
19412   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19413   DONE;
19414 })
19415
19416 (define_insn "fxam<mode>2_i387"
19417   [(set (match_operand:HI 0 "register_operand" "=a")
19418         (unspec:HI
19419           [(match_operand:X87MODEF 1 "register_operand" "f")]
19420           UNSPEC_FXAM))]
19421   "TARGET_USE_FANCY_MATH_387"
19422   "fxam\n\tfnstsw\t%0"
19423   [(set_attr "type" "multi")
19424    (set_attr "length" "4")
19425    (set_attr "unit" "i387")
19426    (set_attr "mode" "<MODE>")])
19427
19428 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19429   [(set (match_operand:HI 0 "register_operand" "")
19430         (unspec:HI
19431           [(match_operand:MODEF 1 "memory_operand" "")]
19432           UNSPEC_FXAM_MEM))]
19433   "TARGET_USE_FANCY_MATH_387
19434    && !(reload_completed || reload_in_progress)"
19435   "#"
19436   "&& 1"
19437   [(set (match_dup 2)(match_dup 1))
19438    (set (match_dup 0)
19439         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19440 {
19441   operands[2] = gen_reg_rtx (<MODE>mode);
19442
19443   MEM_VOLATILE_P (operands[1]) = 1;
19444 }
19445   [(set_attr "type" "multi")
19446    (set_attr "unit" "i387")
19447    (set_attr "mode" "<MODE>")])
19448
19449 (define_expand "isinfxf2"
19450   [(use (match_operand:SI 0 "register_operand" ""))
19451    (use (match_operand:XF 1 "register_operand" ""))]
19452   "TARGET_USE_FANCY_MATH_387
19453    && TARGET_C99_FUNCTIONS"
19454 {
19455   rtx mask = GEN_INT (0x45);
19456   rtx val = GEN_INT (0x05);
19457
19458   rtx cond;
19459
19460   rtx scratch = gen_reg_rtx (HImode);
19461   rtx res = gen_reg_rtx (QImode);
19462
19463   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19464
19465   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19466   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19467   cond = gen_rtx_fmt_ee (EQ, QImode,
19468                          gen_rtx_REG (CCmode, FLAGS_REG),
19469                          const0_rtx);
19470   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19471   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19472   DONE;
19473 })
19474
19475 (define_expand "isinf<mode>2"
19476   [(use (match_operand:SI 0 "register_operand" ""))
19477    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19478   "TARGET_USE_FANCY_MATH_387
19479    && TARGET_C99_FUNCTIONS
19480    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19481 {
19482   rtx mask = GEN_INT (0x45);
19483   rtx val = GEN_INT (0x05);
19484
19485   rtx cond;
19486
19487   rtx scratch = gen_reg_rtx (HImode);
19488   rtx res = gen_reg_rtx (QImode);
19489
19490   /* Remove excess precision by forcing value through memory. */
19491   if (memory_operand (operands[1], VOIDmode))
19492     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19493   else
19494     {
19495       enum ix86_stack_slot slot = (virtuals_instantiated
19496                                    ? SLOT_TEMP
19497                                    : SLOT_VIRTUAL);
19498       rtx temp = assign_386_stack_local (<MODE>mode, slot);
19499
19500       emit_move_insn (temp, operands[1]);
19501       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19502     }
19503
19504   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19505   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19506   cond = gen_rtx_fmt_ee (EQ, QImode,
19507                          gen_rtx_REG (CCmode, FLAGS_REG),
19508                          const0_rtx);
19509   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19510   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19511   DONE;
19512 })
19513
19514 (define_expand "signbit<mode>2"
19515   [(use (match_operand:SI 0 "register_operand" ""))
19516    (use (match_operand:X87MODEF 1 "register_operand" ""))]
19517   "TARGET_USE_FANCY_MATH_387
19518    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19519 {
19520   rtx mask = GEN_INT (0x0200);
19521
19522   rtx scratch = gen_reg_rtx (HImode);
19523
19524   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19525   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19526   DONE;
19527 })
19528 \f
19529 ;; Block operation instructions
19530
19531 (define_insn "cld"
19532   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19533   ""
19534   "cld"
19535   [(set_attr "length" "1")
19536    (set_attr "length_immediate" "0")
19537    (set_attr "modrm" "0")])
19538
19539 (define_expand "movmemsi"
19540   [(use (match_operand:BLK 0 "memory_operand" ""))
19541    (use (match_operand:BLK 1 "memory_operand" ""))
19542    (use (match_operand:SI 2 "nonmemory_operand" ""))
19543    (use (match_operand:SI 3 "const_int_operand" ""))
19544    (use (match_operand:SI 4 "const_int_operand" ""))
19545    (use (match_operand:SI 5 "const_int_operand" ""))]
19546   ""
19547 {
19548  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19549                          operands[4], operands[5]))
19550    DONE;
19551  else
19552    FAIL;
19553 })
19554
19555 (define_expand "movmemdi"
19556   [(use (match_operand:BLK 0 "memory_operand" ""))
19557    (use (match_operand:BLK 1 "memory_operand" ""))
19558    (use (match_operand:DI 2 "nonmemory_operand" ""))
19559    (use (match_operand:DI 3 "const_int_operand" ""))
19560    (use (match_operand:SI 4 "const_int_operand" ""))
19561    (use (match_operand:SI 5 "const_int_operand" ""))]
19562   "TARGET_64BIT"
19563 {
19564  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19565                          operands[4], operands[5]))
19566    DONE;
19567  else
19568    FAIL;
19569 })
19570
19571 ;; Most CPUs don't like single string operations
19572 ;; Handle this case here to simplify previous expander.
19573
19574 (define_expand "strmov"
19575   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19576    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19577    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19578               (clobber (reg:CC FLAGS_REG))])
19579    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19580               (clobber (reg:CC FLAGS_REG))])]
19581   ""
19582 {
19583   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19584
19585   /* If .md ever supports :P for Pmode, these can be directly
19586      in the pattern above.  */
19587   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19588   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19589
19590   /* Can't use this if the user has appropriated esi or edi.  */
19591   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19592       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19593     {
19594       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19595                                       operands[2], operands[3],
19596                                       operands[5], operands[6]));
19597       DONE;
19598     }
19599
19600   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19601 })
19602
19603 (define_expand "strmov_singleop"
19604   [(parallel [(set (match_operand 1 "memory_operand" "")
19605                    (match_operand 3 "memory_operand" ""))
19606               (set (match_operand 0 "register_operand" "")
19607                    (match_operand 4 "" ""))
19608               (set (match_operand 2 "register_operand" "")
19609                    (match_operand 5 "" ""))])]
19610   ""
19611   "ix86_current_function_needs_cld = 1;")
19612
19613 (define_insn "*strmovdi_rex_1"
19614   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19615         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19616    (set (match_operand:DI 0 "register_operand" "=D")
19617         (plus:DI (match_dup 2)
19618                  (const_int 8)))
19619    (set (match_operand:DI 1 "register_operand" "=S")
19620         (plus:DI (match_dup 3)
19621                  (const_int 8)))]
19622   "TARGET_64BIT"
19623   "movsq"
19624   [(set_attr "type" "str")
19625    (set_attr "mode" "DI")
19626    (set_attr "memory" "both")])
19627
19628 (define_insn "*strmovsi_1"
19629   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19630         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19631    (set (match_operand:SI 0 "register_operand" "=D")
19632         (plus:SI (match_dup 2)
19633                  (const_int 4)))
19634    (set (match_operand:SI 1 "register_operand" "=S")
19635         (plus:SI (match_dup 3)
19636                  (const_int 4)))]
19637   "!TARGET_64BIT"
19638   "movs{l|d}"
19639   [(set_attr "type" "str")
19640    (set_attr "mode" "SI")
19641    (set_attr "memory" "both")])
19642
19643 (define_insn "*strmovsi_rex_1"
19644   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19645         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19646    (set (match_operand:DI 0 "register_operand" "=D")
19647         (plus:DI (match_dup 2)
19648                  (const_int 4)))
19649    (set (match_operand:DI 1 "register_operand" "=S")
19650         (plus:DI (match_dup 3)
19651                  (const_int 4)))]
19652   "TARGET_64BIT"
19653   "movs{l|d}"
19654   [(set_attr "type" "str")
19655    (set_attr "mode" "SI")
19656    (set_attr "memory" "both")])
19657
19658 (define_insn "*strmovhi_1"
19659   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19660         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19661    (set (match_operand:SI 0 "register_operand" "=D")
19662         (plus:SI (match_dup 2)
19663                  (const_int 2)))
19664    (set (match_operand:SI 1 "register_operand" "=S")
19665         (plus:SI (match_dup 3)
19666                  (const_int 2)))]
19667   "!TARGET_64BIT"
19668   "movsw"
19669   [(set_attr "type" "str")
19670    (set_attr "memory" "both")
19671    (set_attr "mode" "HI")])
19672
19673 (define_insn "*strmovhi_rex_1"
19674   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19675         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19676    (set (match_operand:DI 0 "register_operand" "=D")
19677         (plus:DI (match_dup 2)
19678                  (const_int 2)))
19679    (set (match_operand:DI 1 "register_operand" "=S")
19680         (plus:DI (match_dup 3)
19681                  (const_int 2)))]
19682   "TARGET_64BIT"
19683   "movsw"
19684   [(set_attr "type" "str")
19685    (set_attr "memory" "both")
19686    (set_attr "mode" "HI")])
19687
19688 (define_insn "*strmovqi_1"
19689   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19690         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19691    (set (match_operand:SI 0 "register_operand" "=D")
19692         (plus:SI (match_dup 2)
19693                  (const_int 1)))
19694    (set (match_operand:SI 1 "register_operand" "=S")
19695         (plus:SI (match_dup 3)
19696                  (const_int 1)))]
19697   "!TARGET_64BIT"
19698   "movsb"
19699   [(set_attr "type" "str")
19700    (set_attr "memory" "both")
19701    (set_attr "mode" "QI")])
19702
19703 (define_insn "*strmovqi_rex_1"
19704   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19705         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19706    (set (match_operand:DI 0 "register_operand" "=D")
19707         (plus:DI (match_dup 2)
19708                  (const_int 1)))
19709    (set (match_operand:DI 1 "register_operand" "=S")
19710         (plus:DI (match_dup 3)
19711                  (const_int 1)))]
19712   "TARGET_64BIT"
19713   "movsb"
19714   [(set_attr "type" "str")
19715    (set_attr "memory" "both")
19716    (set_attr "prefix_rex" "0")
19717    (set_attr "mode" "QI")])
19718
19719 (define_expand "rep_mov"
19720   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19721               (set (match_operand 0 "register_operand" "")
19722                    (match_operand 5 "" ""))
19723               (set (match_operand 2 "register_operand" "")
19724                    (match_operand 6 "" ""))
19725               (set (match_operand 1 "memory_operand" "")
19726                    (match_operand 3 "memory_operand" ""))
19727               (use (match_dup 4))])]
19728   ""
19729   "ix86_current_function_needs_cld = 1;")
19730
19731 (define_insn "*rep_movdi_rex64"
19732   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19733    (set (match_operand:DI 0 "register_operand" "=D")
19734         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19735                             (const_int 3))
19736                  (match_operand:DI 3 "register_operand" "0")))
19737    (set (match_operand:DI 1 "register_operand" "=S")
19738         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19739                  (match_operand:DI 4 "register_operand" "1")))
19740    (set (mem:BLK (match_dup 3))
19741         (mem:BLK (match_dup 4)))
19742    (use (match_dup 5))]
19743   "TARGET_64BIT"
19744   "rep movsq"
19745   [(set_attr "type" "str")
19746    (set_attr "prefix_rep" "1")
19747    (set_attr "memory" "both")
19748    (set_attr "mode" "DI")])
19749
19750 (define_insn "*rep_movsi"
19751   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19752    (set (match_operand:SI 0 "register_operand" "=D")
19753         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19754                             (const_int 2))
19755                  (match_operand:SI 3 "register_operand" "0")))
19756    (set (match_operand:SI 1 "register_operand" "=S")
19757         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19758                  (match_operand:SI 4 "register_operand" "1")))
19759    (set (mem:BLK (match_dup 3))
19760         (mem:BLK (match_dup 4)))
19761    (use (match_dup 5))]
19762   "!TARGET_64BIT"
19763   "rep movs{l|d}"
19764   [(set_attr "type" "str")
19765    (set_attr "prefix_rep" "1")
19766    (set_attr "memory" "both")
19767    (set_attr "mode" "SI")])
19768
19769 (define_insn "*rep_movsi_rex64"
19770   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19771    (set (match_operand:DI 0 "register_operand" "=D")
19772         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19773                             (const_int 2))
19774                  (match_operand:DI 3 "register_operand" "0")))
19775    (set (match_operand:DI 1 "register_operand" "=S")
19776         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19777                  (match_operand:DI 4 "register_operand" "1")))
19778    (set (mem:BLK (match_dup 3))
19779         (mem:BLK (match_dup 4)))
19780    (use (match_dup 5))]
19781   "TARGET_64BIT"
19782   "rep movs{l|d}"
19783   [(set_attr "type" "str")
19784    (set_attr "prefix_rep" "1")
19785    (set_attr "memory" "both")
19786    (set_attr "mode" "SI")])
19787
19788 (define_insn "*rep_movqi"
19789   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19790    (set (match_operand:SI 0 "register_operand" "=D")
19791         (plus:SI (match_operand:SI 3 "register_operand" "0")
19792                  (match_operand:SI 5 "register_operand" "2")))
19793    (set (match_operand:SI 1 "register_operand" "=S")
19794         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19795    (set (mem:BLK (match_dup 3))
19796         (mem:BLK (match_dup 4)))
19797    (use (match_dup 5))]
19798   "!TARGET_64BIT"
19799   "rep movsb"
19800   [(set_attr "type" "str")
19801    (set_attr "prefix_rep" "1")
19802    (set_attr "memory" "both")
19803    (set_attr "mode" "SI")])
19804
19805 (define_insn "*rep_movqi_rex64"
19806   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19807    (set (match_operand:DI 0 "register_operand" "=D")
19808         (plus:DI (match_operand:DI 3 "register_operand" "0")
19809                  (match_operand:DI 5 "register_operand" "2")))
19810    (set (match_operand:DI 1 "register_operand" "=S")
19811         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19812    (set (mem:BLK (match_dup 3))
19813         (mem:BLK (match_dup 4)))
19814    (use (match_dup 5))]
19815   "TARGET_64BIT"
19816   "rep movsb"
19817   [(set_attr "type" "str")
19818    (set_attr "prefix_rep" "1")
19819    (set_attr "memory" "both")
19820    (set_attr "mode" "SI")])
19821
19822 (define_expand "setmemsi"
19823    [(use (match_operand:BLK 0 "memory_operand" ""))
19824     (use (match_operand:SI 1 "nonmemory_operand" ""))
19825     (use (match_operand 2 "const_int_operand" ""))
19826     (use (match_operand 3 "const_int_operand" ""))
19827     (use (match_operand:SI 4 "const_int_operand" ""))
19828     (use (match_operand:SI 5 "const_int_operand" ""))]
19829   ""
19830 {
19831  if (ix86_expand_setmem (operands[0], operands[1],
19832                          operands[2], operands[3],
19833                          operands[4], operands[5]))
19834    DONE;
19835  else
19836    FAIL;
19837 })
19838
19839 (define_expand "setmemdi"
19840    [(use (match_operand:BLK 0 "memory_operand" ""))
19841     (use (match_operand:DI 1 "nonmemory_operand" ""))
19842     (use (match_operand 2 "const_int_operand" ""))
19843     (use (match_operand 3 "const_int_operand" ""))
19844     (use (match_operand 4 "const_int_operand" ""))
19845     (use (match_operand 5 "const_int_operand" ""))]
19846   "TARGET_64BIT"
19847 {
19848  if (ix86_expand_setmem (operands[0], operands[1],
19849                          operands[2], operands[3],
19850                          operands[4], operands[5]))
19851    DONE;
19852  else
19853    FAIL;
19854 })
19855
19856 ;; Most CPUs don't like single string operations
19857 ;; Handle this case here to simplify previous expander.
19858
19859 (define_expand "strset"
19860   [(set (match_operand 1 "memory_operand" "")
19861         (match_operand 2 "register_operand" ""))
19862    (parallel [(set (match_operand 0 "register_operand" "")
19863                    (match_dup 3))
19864               (clobber (reg:CC FLAGS_REG))])]
19865   ""
19866 {
19867   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19868     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19869
19870   /* If .md ever supports :P for Pmode, this can be directly
19871      in the pattern above.  */
19872   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19873                               GEN_INT (GET_MODE_SIZE (GET_MODE
19874                                                       (operands[2]))));
19875   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19876     {
19877       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19878                                       operands[3]));
19879       DONE;
19880     }
19881 })
19882
19883 (define_expand "strset_singleop"
19884   [(parallel [(set (match_operand 1 "memory_operand" "")
19885                    (match_operand 2 "register_operand" ""))
19886               (set (match_operand 0 "register_operand" "")
19887                    (match_operand 3 "" ""))])]
19888   ""
19889   "ix86_current_function_needs_cld = 1;")
19890
19891 (define_insn "*strsetdi_rex_1"
19892   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19893         (match_operand:DI 2 "register_operand" "a"))
19894    (set (match_operand:DI 0 "register_operand" "=D")
19895         (plus:DI (match_dup 1)
19896                  (const_int 8)))]
19897   "TARGET_64BIT"
19898   "stosq"
19899   [(set_attr "type" "str")
19900    (set_attr "memory" "store")
19901    (set_attr "mode" "DI")])
19902
19903 (define_insn "*strsetsi_1"
19904   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19905         (match_operand:SI 2 "register_operand" "a"))
19906    (set (match_operand:SI 0 "register_operand" "=D")
19907         (plus:SI (match_dup 1)
19908                  (const_int 4)))]
19909   "!TARGET_64BIT"
19910   "stos{l|d}"
19911   [(set_attr "type" "str")
19912    (set_attr "memory" "store")
19913    (set_attr "mode" "SI")])
19914
19915 (define_insn "*strsetsi_rex_1"
19916   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19917         (match_operand:SI 2 "register_operand" "a"))
19918    (set (match_operand:DI 0 "register_operand" "=D")
19919         (plus:DI (match_dup 1)
19920                  (const_int 4)))]
19921   "TARGET_64BIT"
19922   "stos{l|d}"
19923   [(set_attr "type" "str")
19924    (set_attr "memory" "store")
19925    (set_attr "mode" "SI")])
19926
19927 (define_insn "*strsethi_1"
19928   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19929         (match_operand:HI 2 "register_operand" "a"))
19930    (set (match_operand:SI 0 "register_operand" "=D")
19931         (plus:SI (match_dup 1)
19932                  (const_int 2)))]
19933   "!TARGET_64BIT"
19934   "stosw"
19935   [(set_attr "type" "str")
19936    (set_attr "memory" "store")
19937    (set_attr "mode" "HI")])
19938
19939 (define_insn "*strsethi_rex_1"
19940   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19941         (match_operand:HI 2 "register_operand" "a"))
19942    (set (match_operand:DI 0 "register_operand" "=D")
19943         (plus:DI (match_dup 1)
19944                  (const_int 2)))]
19945   "TARGET_64BIT"
19946   "stosw"
19947   [(set_attr "type" "str")
19948    (set_attr "memory" "store")
19949    (set_attr "mode" "HI")])
19950
19951 (define_insn "*strsetqi_1"
19952   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19953         (match_operand:QI 2 "register_operand" "a"))
19954    (set (match_operand:SI 0 "register_operand" "=D")
19955         (plus:SI (match_dup 1)
19956                  (const_int 1)))]
19957   "!TARGET_64BIT"
19958   "stosb"
19959   [(set_attr "type" "str")
19960    (set_attr "memory" "store")
19961    (set_attr "mode" "QI")])
19962
19963 (define_insn "*strsetqi_rex_1"
19964   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19965         (match_operand:QI 2 "register_operand" "a"))
19966    (set (match_operand:DI 0 "register_operand" "=D")
19967         (plus:DI (match_dup 1)
19968                  (const_int 1)))]
19969   "TARGET_64BIT"
19970   "stosb"
19971   [(set_attr "type" "str")
19972    (set_attr "memory" "store")
19973    (set_attr "prefix_rex" "0")
19974    (set_attr "mode" "QI")])
19975
19976 (define_expand "rep_stos"
19977   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19978               (set (match_operand 0 "register_operand" "")
19979                    (match_operand 4 "" ""))
19980               (set (match_operand 2 "memory_operand" "") (const_int 0))
19981               (use (match_operand 3 "register_operand" ""))
19982               (use (match_dup 1))])]
19983   ""
19984   "ix86_current_function_needs_cld = 1;")
19985
19986 (define_insn "*rep_stosdi_rex64"
19987   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19988    (set (match_operand:DI 0 "register_operand" "=D")
19989         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19990                             (const_int 3))
19991                  (match_operand:DI 3 "register_operand" "0")))
19992    (set (mem:BLK (match_dup 3))
19993         (const_int 0))
19994    (use (match_operand:DI 2 "register_operand" "a"))
19995    (use (match_dup 4))]
19996   "TARGET_64BIT"
19997   "rep stosq"
19998   [(set_attr "type" "str")
19999    (set_attr "prefix_rep" "1")
20000    (set_attr "memory" "store")
20001    (set_attr "mode" "DI")])
20002
20003 (define_insn "*rep_stossi"
20004   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20005    (set (match_operand:SI 0 "register_operand" "=D")
20006         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
20007                             (const_int 2))
20008                  (match_operand:SI 3 "register_operand" "0")))
20009    (set (mem:BLK (match_dup 3))
20010         (const_int 0))
20011    (use (match_operand:SI 2 "register_operand" "a"))
20012    (use (match_dup 4))]
20013   "!TARGET_64BIT"
20014   "rep stos{l|d}"
20015   [(set_attr "type" "str")
20016    (set_attr "prefix_rep" "1")
20017    (set_attr "memory" "store")
20018    (set_attr "mode" "SI")])
20019
20020 (define_insn "*rep_stossi_rex64"
20021   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20022    (set (match_operand:DI 0 "register_operand" "=D")
20023         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20024                             (const_int 2))
20025                  (match_operand:DI 3 "register_operand" "0")))
20026    (set (mem:BLK (match_dup 3))
20027         (const_int 0))
20028    (use (match_operand:SI 2 "register_operand" "a"))
20029    (use (match_dup 4))]
20030   "TARGET_64BIT"
20031   "rep stos{l|d}"
20032   [(set_attr "type" "str")
20033    (set_attr "prefix_rep" "1")
20034    (set_attr "memory" "store")
20035    (set_attr "mode" "SI")])
20036
20037 (define_insn "*rep_stosqi"
20038   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20039    (set (match_operand:SI 0 "register_operand" "=D")
20040         (plus:SI (match_operand:SI 3 "register_operand" "0")
20041                  (match_operand:SI 4 "register_operand" "1")))
20042    (set (mem:BLK (match_dup 3))
20043         (const_int 0))
20044    (use (match_operand:QI 2 "register_operand" "a"))
20045    (use (match_dup 4))]
20046   "!TARGET_64BIT"
20047   "rep stosb"
20048   [(set_attr "type" "str")
20049    (set_attr "prefix_rep" "1")
20050    (set_attr "memory" "store")
20051    (set_attr "mode" "QI")])
20052
20053 (define_insn "*rep_stosqi_rex64"
20054   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20055    (set (match_operand:DI 0 "register_operand" "=D")
20056         (plus:DI (match_operand:DI 3 "register_operand" "0")
20057                  (match_operand:DI 4 "register_operand" "1")))
20058    (set (mem:BLK (match_dup 3))
20059         (const_int 0))
20060    (use (match_operand:QI 2 "register_operand" "a"))
20061    (use (match_dup 4))]
20062   "TARGET_64BIT"
20063   "rep stosb"
20064   [(set_attr "type" "str")
20065    (set_attr "prefix_rep" "1")
20066    (set_attr "memory" "store")
20067    (set_attr "prefix_rex" "0")
20068    (set_attr "mode" "QI")])
20069
20070 (define_expand "cmpstrnsi"
20071   [(set (match_operand:SI 0 "register_operand" "")
20072         (compare:SI (match_operand:BLK 1 "general_operand" "")
20073                     (match_operand:BLK 2 "general_operand" "")))
20074    (use (match_operand 3 "general_operand" ""))
20075    (use (match_operand 4 "immediate_operand" ""))]
20076   ""
20077 {
20078   rtx addr1, addr2, out, outlow, count, countreg, align;
20079
20080   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20081     FAIL;
20082
20083   /* Can't use this if the user has appropriated esi or edi.  */
20084   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20085     FAIL;
20086
20087   out = operands[0];
20088   if (!REG_P (out))
20089     out = gen_reg_rtx (SImode);
20090
20091   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20092   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20093   if (addr1 != XEXP (operands[1], 0))
20094     operands[1] = replace_equiv_address_nv (operands[1], addr1);
20095   if (addr2 != XEXP (operands[2], 0))
20096     operands[2] = replace_equiv_address_nv (operands[2], addr2);
20097
20098   count = operands[3];
20099   countreg = ix86_zero_extend_to_Pmode (count);
20100
20101   /* %%% Iff we are testing strict equality, we can use known alignment
20102      to good advantage.  This may be possible with combine, particularly
20103      once cc0 is dead.  */
20104   align = operands[4];
20105
20106   if (CONST_INT_P (count))
20107     {
20108       if (INTVAL (count) == 0)
20109         {
20110           emit_move_insn (operands[0], const0_rtx);
20111           DONE;
20112         }
20113       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20114                                      operands[1], operands[2]));
20115     }
20116   else
20117     {
20118       if (TARGET_64BIT)
20119         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20120       else
20121         emit_insn (gen_cmpsi_1 (countreg, countreg));
20122       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20123                                   operands[1], operands[2]));
20124     }
20125
20126   outlow = gen_lowpart (QImode, out);
20127   emit_insn (gen_cmpintqi (outlow));
20128   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20129
20130   if (operands[0] != out)
20131     emit_move_insn (operands[0], out);
20132
20133   DONE;
20134 })
20135
20136 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20137
20138 (define_expand "cmpintqi"
20139   [(set (match_dup 1)
20140         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20141    (set (match_dup 2)
20142         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20143    (parallel [(set (match_operand:QI 0 "register_operand" "")
20144                    (minus:QI (match_dup 1)
20145                              (match_dup 2)))
20146               (clobber (reg:CC FLAGS_REG))])]
20147   ""
20148   "operands[1] = gen_reg_rtx (QImode);
20149    operands[2] = gen_reg_rtx (QImode);")
20150
20151 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
20152 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
20153
20154 (define_expand "cmpstrnqi_nz_1"
20155   [(parallel [(set (reg:CC FLAGS_REG)
20156                    (compare:CC (match_operand 4 "memory_operand" "")
20157                                (match_operand 5 "memory_operand" "")))
20158               (use (match_operand 2 "register_operand" ""))
20159               (use (match_operand:SI 3 "immediate_operand" ""))
20160               (clobber (match_operand 0 "register_operand" ""))
20161               (clobber (match_operand 1 "register_operand" ""))
20162               (clobber (match_dup 2))])]
20163   ""
20164   "ix86_current_function_needs_cld = 1;")
20165
20166 (define_insn "*cmpstrnqi_nz_1"
20167   [(set (reg:CC FLAGS_REG)
20168         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20169                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20170    (use (match_operand:SI 6 "register_operand" "2"))
20171    (use (match_operand:SI 3 "immediate_operand" "i"))
20172    (clobber (match_operand:SI 0 "register_operand" "=S"))
20173    (clobber (match_operand:SI 1 "register_operand" "=D"))
20174    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20175   "!TARGET_64BIT"
20176   "repz cmpsb"
20177   [(set_attr "type" "str")
20178    (set_attr "mode" "QI")
20179    (set_attr "prefix_rep" "1")])
20180
20181 (define_insn "*cmpstrnqi_nz_rex_1"
20182   [(set (reg:CC FLAGS_REG)
20183         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20184                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20185    (use (match_operand:DI 6 "register_operand" "2"))
20186    (use (match_operand:SI 3 "immediate_operand" "i"))
20187    (clobber (match_operand:DI 0 "register_operand" "=S"))
20188    (clobber (match_operand:DI 1 "register_operand" "=D"))
20189    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20190   "TARGET_64BIT"
20191   "repz cmpsb"
20192   [(set_attr "type" "str")
20193    (set_attr "mode" "QI")
20194    (set_attr "prefix_rex" "0")
20195    (set_attr "prefix_rep" "1")])
20196
20197 ;; The same, but the count is not known to not be zero.
20198
20199 (define_expand "cmpstrnqi_1"
20200   [(parallel [(set (reg:CC FLAGS_REG)
20201                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20202                                      (const_int 0))
20203                   (compare:CC (match_operand 4 "memory_operand" "")
20204                               (match_operand 5 "memory_operand" ""))
20205                   (const_int 0)))
20206               (use (match_operand:SI 3 "immediate_operand" ""))
20207               (use (reg:CC FLAGS_REG))
20208               (clobber (match_operand 0 "register_operand" ""))
20209               (clobber (match_operand 1 "register_operand" ""))
20210               (clobber (match_dup 2))])]
20211   ""
20212   "ix86_current_function_needs_cld = 1;")
20213
20214 (define_insn "*cmpstrnqi_1"
20215   [(set (reg:CC FLAGS_REG)
20216         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20217                              (const_int 0))
20218           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20219                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20220           (const_int 0)))
20221    (use (match_operand:SI 3 "immediate_operand" "i"))
20222    (use (reg:CC FLAGS_REG))
20223    (clobber (match_operand:SI 0 "register_operand" "=S"))
20224    (clobber (match_operand:SI 1 "register_operand" "=D"))
20225    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20226   "!TARGET_64BIT"
20227   "repz cmpsb"
20228   [(set_attr "type" "str")
20229    (set_attr "mode" "QI")
20230    (set_attr "prefix_rep" "1")])
20231
20232 (define_insn "*cmpstrnqi_rex_1"
20233   [(set (reg:CC FLAGS_REG)
20234         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20235                              (const_int 0))
20236           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20237                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20238           (const_int 0)))
20239    (use (match_operand:SI 3 "immediate_operand" "i"))
20240    (use (reg:CC FLAGS_REG))
20241    (clobber (match_operand:DI 0 "register_operand" "=S"))
20242    (clobber (match_operand:DI 1 "register_operand" "=D"))
20243    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20244   "TARGET_64BIT"
20245   "repz cmpsb"
20246   [(set_attr "type" "str")
20247    (set_attr "mode" "QI")
20248    (set_attr "prefix_rex" "0")
20249    (set_attr "prefix_rep" "1")])
20250
20251 (define_expand "strlensi"
20252   [(set (match_operand:SI 0 "register_operand" "")
20253         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20254                     (match_operand:QI 2 "immediate_operand" "")
20255                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20256   ""
20257 {
20258  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20259    DONE;
20260  else
20261    FAIL;
20262 })
20263
20264 (define_expand "strlendi"
20265   [(set (match_operand:DI 0 "register_operand" "")
20266         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20267                     (match_operand:QI 2 "immediate_operand" "")
20268                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20269   ""
20270 {
20271  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20272    DONE;
20273  else
20274    FAIL;
20275 })
20276
20277 (define_expand "strlenqi_1"
20278   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20279               (clobber (match_operand 1 "register_operand" ""))
20280               (clobber (reg:CC FLAGS_REG))])]
20281   ""
20282   "ix86_current_function_needs_cld = 1;")
20283
20284 (define_insn "*strlenqi_1"
20285   [(set (match_operand:SI 0 "register_operand" "=&c")
20286         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20287                     (match_operand:QI 2 "register_operand" "a")
20288                     (match_operand:SI 3 "immediate_operand" "i")
20289                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20290    (clobber (match_operand:SI 1 "register_operand" "=D"))
20291    (clobber (reg:CC FLAGS_REG))]
20292   "!TARGET_64BIT"
20293   "repnz scasb"
20294   [(set_attr "type" "str")
20295    (set_attr "mode" "QI")
20296    (set_attr "prefix_rep" "1")])
20297
20298 (define_insn "*strlenqi_rex_1"
20299   [(set (match_operand:DI 0 "register_operand" "=&c")
20300         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20301                     (match_operand:QI 2 "register_operand" "a")
20302                     (match_operand:DI 3 "immediate_operand" "i")
20303                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20304    (clobber (match_operand:DI 1 "register_operand" "=D"))
20305    (clobber (reg:CC FLAGS_REG))]
20306   "TARGET_64BIT"
20307   "repnz scasb"
20308   [(set_attr "type" "str")
20309    (set_attr "mode" "QI")
20310    (set_attr "prefix_rex" "0")
20311    (set_attr "prefix_rep" "1")])
20312
20313 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
20314 ;; handled in combine, but it is not currently up to the task.
20315 ;; When used for their truth value, the cmpstrn* expanders generate
20316 ;; code like this:
20317 ;;
20318 ;;   repz cmpsb
20319 ;;   seta       %al
20320 ;;   setb       %dl
20321 ;;   cmpb       %al, %dl
20322 ;;   jcc        label
20323 ;;
20324 ;; The intermediate three instructions are unnecessary.
20325
20326 ;; This one handles cmpstrn*_nz_1...
20327 (define_peephole2
20328   [(parallel[
20329      (set (reg:CC FLAGS_REG)
20330           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20331                       (mem:BLK (match_operand 5 "register_operand" ""))))
20332      (use (match_operand 6 "register_operand" ""))
20333      (use (match_operand:SI 3 "immediate_operand" ""))
20334      (clobber (match_operand 0 "register_operand" ""))
20335      (clobber (match_operand 1 "register_operand" ""))
20336      (clobber (match_operand 2 "register_operand" ""))])
20337    (set (match_operand:QI 7 "register_operand" "")
20338         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20339    (set (match_operand:QI 8 "register_operand" "")
20340         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20341    (set (reg FLAGS_REG)
20342         (compare (match_dup 7) (match_dup 8)))
20343   ]
20344   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20345   [(parallel[
20346      (set (reg:CC FLAGS_REG)
20347           (compare:CC (mem:BLK (match_dup 4))
20348                       (mem:BLK (match_dup 5))))
20349      (use (match_dup 6))
20350      (use (match_dup 3))
20351      (clobber (match_dup 0))
20352      (clobber (match_dup 1))
20353      (clobber (match_dup 2))])]
20354   "")
20355
20356 ;; ...and this one handles cmpstrn*_1.
20357 (define_peephole2
20358   [(parallel[
20359      (set (reg:CC FLAGS_REG)
20360           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20361                                (const_int 0))
20362             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20363                         (mem:BLK (match_operand 5 "register_operand" "")))
20364             (const_int 0)))
20365      (use (match_operand:SI 3 "immediate_operand" ""))
20366      (use (reg:CC FLAGS_REG))
20367      (clobber (match_operand 0 "register_operand" ""))
20368      (clobber (match_operand 1 "register_operand" ""))
20369      (clobber (match_operand 2 "register_operand" ""))])
20370    (set (match_operand:QI 7 "register_operand" "")
20371         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20372    (set (match_operand:QI 8 "register_operand" "")
20373         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20374    (set (reg FLAGS_REG)
20375         (compare (match_dup 7) (match_dup 8)))
20376   ]
20377   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20378   [(parallel[
20379      (set (reg:CC FLAGS_REG)
20380           (if_then_else:CC (ne (match_dup 6)
20381                                (const_int 0))
20382             (compare:CC (mem:BLK (match_dup 4))
20383                         (mem:BLK (match_dup 5)))
20384             (const_int 0)))
20385      (use (match_dup 3))
20386      (use (reg:CC FLAGS_REG))
20387      (clobber (match_dup 0))
20388      (clobber (match_dup 1))
20389      (clobber (match_dup 2))])]
20390   "")
20391
20392
20393 \f
20394 ;; Conditional move instructions.
20395
20396 (define_expand "movdicc"
20397   [(set (match_operand:DI 0 "register_operand" "")
20398         (if_then_else:DI (match_operand 1 "comparison_operator" "")
20399                          (match_operand:DI 2 "general_operand" "")
20400                          (match_operand:DI 3 "general_operand" "")))]
20401   "TARGET_64BIT"
20402   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20403
20404 (define_insn "x86_movdicc_0_m1_rex64"
20405   [(set (match_operand:DI 0 "register_operand" "=r")
20406         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20407           (const_int -1)
20408           (const_int 0)))
20409    (clobber (reg:CC FLAGS_REG))]
20410   "TARGET_64BIT"
20411   "sbb{q}\t%0, %0"
20412   ; Since we don't have the proper number of operands for an alu insn,
20413   ; fill in all the blanks.
20414   [(set_attr "type" "alu")
20415    (set_attr "use_carry" "1")
20416    (set_attr "pent_pair" "pu")
20417    (set_attr "memory" "none")
20418    (set_attr "imm_disp" "false")
20419    (set_attr "mode" "DI")
20420    (set_attr "length_immediate" "0")])
20421
20422 (define_insn "*x86_movdicc_0_m1_se"
20423   [(set (match_operand:DI 0 "register_operand" "=r")
20424         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20425                          (const_int 1)
20426                          (const_int 0)))
20427    (clobber (reg:CC FLAGS_REG))]
20428   ""
20429   "sbb{q}\t%0, %0"
20430   [(set_attr "type" "alu")
20431    (set_attr "use_carry" "1")
20432    (set_attr "pent_pair" "pu")
20433    (set_attr "memory" "none")
20434    (set_attr "imm_disp" "false")
20435    (set_attr "mode" "DI")
20436    (set_attr "length_immediate" "0")])
20437
20438 (define_insn "*movdicc_c_rex64"
20439   [(set (match_operand:DI 0 "register_operand" "=r,r")
20440         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20441                                 [(reg FLAGS_REG) (const_int 0)])
20442                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20443                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20444   "TARGET_64BIT && TARGET_CMOVE
20445    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20446   "@
20447    cmov%O2%C1\t{%2, %0|%0, %2}
20448    cmov%O2%c1\t{%3, %0|%0, %3}"
20449   [(set_attr "type" "icmov")
20450    (set_attr "mode" "DI")])
20451
20452 (define_expand "movsicc"
20453   [(set (match_operand:SI 0 "register_operand" "")
20454         (if_then_else:SI (match_operand 1 "comparison_operator" "")
20455                          (match_operand:SI 2 "general_operand" "")
20456                          (match_operand:SI 3 "general_operand" "")))]
20457   ""
20458   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20459
20460 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20461 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20462 ;; So just document what we're doing explicitly.
20463
20464 (define_insn "x86_movsicc_0_m1"
20465   [(set (match_operand:SI 0 "register_operand" "=r")
20466         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20467           (const_int -1)
20468           (const_int 0)))
20469    (clobber (reg:CC FLAGS_REG))]
20470   ""
20471   "sbb{l}\t%0, %0"
20472   ; Since we don't have the proper number of operands for an alu insn,
20473   ; fill in all the blanks.
20474   [(set_attr "type" "alu")
20475    (set_attr "use_carry" "1")
20476    (set_attr "pent_pair" "pu")
20477    (set_attr "memory" "none")
20478    (set_attr "imm_disp" "false")
20479    (set_attr "mode" "SI")
20480    (set_attr "length_immediate" "0")])
20481
20482 (define_insn "*x86_movsicc_0_m1_se"
20483   [(set (match_operand:SI 0 "register_operand" "=r")
20484         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20485                          (const_int 1)
20486                          (const_int 0)))
20487    (clobber (reg:CC FLAGS_REG))]
20488   ""
20489   "sbb{l}\t%0, %0"
20490   [(set_attr "type" "alu")
20491    (set_attr "use_carry" "1")
20492    (set_attr "pent_pair" "pu")
20493    (set_attr "memory" "none")
20494    (set_attr "imm_disp" "false")
20495    (set_attr "mode" "SI")
20496    (set_attr "length_immediate" "0")])
20497
20498 (define_insn "*movsicc_noc"
20499   [(set (match_operand:SI 0 "register_operand" "=r,r")
20500         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20501                                 [(reg FLAGS_REG) (const_int 0)])
20502                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20503                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20504   "TARGET_CMOVE
20505    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20506   "@
20507    cmov%O2%C1\t{%2, %0|%0, %2}
20508    cmov%O2%c1\t{%3, %0|%0, %3}"
20509   [(set_attr "type" "icmov")
20510    (set_attr "mode" "SI")])
20511
20512 (define_expand "movhicc"
20513   [(set (match_operand:HI 0 "register_operand" "")
20514         (if_then_else:HI (match_operand 1 "comparison_operator" "")
20515                          (match_operand:HI 2 "general_operand" "")
20516                          (match_operand:HI 3 "general_operand" "")))]
20517   "TARGET_HIMODE_MATH"
20518   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20519
20520 (define_insn "*movhicc_noc"
20521   [(set (match_operand:HI 0 "register_operand" "=r,r")
20522         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20523                                 [(reg FLAGS_REG) (const_int 0)])
20524                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20525                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20526   "TARGET_CMOVE
20527    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20528   "@
20529    cmov%O2%C1\t{%2, %0|%0, %2}
20530    cmov%O2%c1\t{%3, %0|%0, %3}"
20531   [(set_attr "type" "icmov")
20532    (set_attr "mode" "HI")])
20533
20534 (define_expand "movqicc"
20535   [(set (match_operand:QI 0 "register_operand" "")
20536         (if_then_else:QI (match_operand 1 "comparison_operator" "")
20537                          (match_operand:QI 2 "general_operand" "")
20538                          (match_operand:QI 3 "general_operand" "")))]
20539   "TARGET_QIMODE_MATH"
20540   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20541
20542 (define_insn_and_split "*movqicc_noc"
20543   [(set (match_operand:QI 0 "register_operand" "=r,r")
20544         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20545                                 [(match_operand 4 "flags_reg_operand" "")
20546                                  (const_int 0)])
20547                       (match_operand:QI 2 "register_operand" "r,0")
20548                       (match_operand:QI 3 "register_operand" "0,r")))]
20549   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20550   "#"
20551   "&& reload_completed"
20552   [(set (match_dup 0)
20553         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20554                       (match_dup 2)
20555                       (match_dup 3)))]
20556   "operands[0] = gen_lowpart (SImode, operands[0]);
20557    operands[2] = gen_lowpart (SImode, operands[2]);
20558    operands[3] = gen_lowpart (SImode, operands[3]);"
20559   [(set_attr "type" "icmov")
20560    (set_attr "mode" "SI")])
20561
20562 (define_expand "mov<mode>cc"
20563   [(set (match_operand:X87MODEF 0 "register_operand" "")
20564         (if_then_else:X87MODEF
20565           (match_operand 1 "ix86_fp_comparison_operator" "")
20566           (match_operand:X87MODEF 2 "register_operand" "")
20567           (match_operand:X87MODEF 3 "register_operand" "")))]
20568   "(TARGET_80387 && TARGET_CMOVE)
20569    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20570   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20571
20572 (define_insn "*movsfcc_1_387"
20573   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20574         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20575                                 [(reg FLAGS_REG) (const_int 0)])
20576                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20577                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20578   "TARGET_80387 && TARGET_CMOVE
20579    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20580   "@
20581    fcmov%F1\t{%2, %0|%0, %2}
20582    fcmov%f1\t{%3, %0|%0, %3}
20583    cmov%O2%C1\t{%2, %0|%0, %2}
20584    cmov%O2%c1\t{%3, %0|%0, %3}"
20585   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20586    (set_attr "mode" "SF,SF,SI,SI")])
20587
20588 (define_insn "*movdfcc_1"
20589   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20590         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20591                                 [(reg FLAGS_REG) (const_int 0)])
20592                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20593                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20594   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20595    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20596   "@
20597    fcmov%F1\t{%2, %0|%0, %2}
20598    fcmov%f1\t{%3, %0|%0, %3}
20599    #
20600    #"
20601   [(set_attr "type" "fcmov,fcmov,multi,multi")
20602    (set_attr "mode" "DF")])
20603
20604 (define_insn "*movdfcc_1_rex64"
20605   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20606         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20607                                 [(reg FLAGS_REG) (const_int 0)])
20608                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20609                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20610   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20611    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20612   "@
20613    fcmov%F1\t{%2, %0|%0, %2}
20614    fcmov%f1\t{%3, %0|%0, %3}
20615    cmov%O2%C1\t{%2, %0|%0, %2}
20616    cmov%O2%c1\t{%3, %0|%0, %3}"
20617   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20618    (set_attr "mode" "DF")])
20619
20620 (define_split
20621   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20622         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20623                                 [(match_operand 4 "flags_reg_operand" "")
20624                                  (const_int 0)])
20625                       (match_operand:DF 2 "nonimmediate_operand" "")
20626                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20627   "!TARGET_64BIT && reload_completed"
20628   [(set (match_dup 2)
20629         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20630                       (match_dup 5)
20631                       (match_dup 6)))
20632    (set (match_dup 3)
20633         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20634                       (match_dup 7)
20635                       (match_dup 8)))]
20636   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20637    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20638
20639 (define_insn "*movxfcc_1"
20640   [(set (match_operand:XF 0 "register_operand" "=f,f")
20641         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20642                                 [(reg FLAGS_REG) (const_int 0)])
20643                       (match_operand:XF 2 "register_operand" "f,0")
20644                       (match_operand:XF 3 "register_operand" "0,f")))]
20645   "TARGET_80387 && TARGET_CMOVE"
20646   "@
20647    fcmov%F1\t{%2, %0|%0, %2}
20648    fcmov%f1\t{%3, %0|%0, %3}"
20649   [(set_attr "type" "fcmov")
20650    (set_attr "mode" "XF")])
20651
20652 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20653 ;; the scalar versions to have only XMM registers as operands.
20654
20655 ;; SSE5 conditional move
20656 (define_insn "*sse5_pcmov_<mode>"
20657   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20658         (if_then_else:MODEF
20659           (match_operand:MODEF 1 "register_operand" "x,0")
20660           (match_operand:MODEF 2 "register_operand" "0,x")
20661           (match_operand:MODEF 3 "register_operand" "x,x")))]
20662   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20663   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20664   [(set_attr "type" "sse4arg")])
20665
20666 ;; These versions of the min/max patterns are intentionally ignorant of
20667 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20668 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20669 ;; are undefined in this condition, we're certain this is correct.
20670
20671 (define_insn "*avx_<code><mode>3"
20672   [(set (match_operand:MODEF 0 "register_operand" "=x")
20673         (smaxmin:MODEF
20674           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20675           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20676   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20677   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20678   [(set_attr "type" "sseadd")
20679    (set_attr "prefix" "vex")
20680    (set_attr "mode" "<MODE>")])
20681
20682 (define_insn "<code><mode>3"
20683   [(set (match_operand:MODEF 0 "register_operand" "=x")
20684         (smaxmin:MODEF
20685           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20686           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20687   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20688   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20689   [(set_attr "type" "sseadd")
20690    (set_attr "mode" "<MODE>")])
20691
20692 ;; These versions of the min/max patterns implement exactly the operations
20693 ;;   min = (op1 < op2 ? op1 : op2)
20694 ;;   max = (!(op1 < op2) ? op1 : op2)
20695 ;; Their operands are not commutative, and thus they may be used in the
20696 ;; presence of -0.0 and NaN.
20697
20698 (define_insn "*avx_ieee_smin<mode>3"
20699   [(set (match_operand:MODEF 0 "register_operand" "=x")
20700         (unspec:MODEF
20701           [(match_operand:MODEF 1 "register_operand" "x")
20702            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20703          UNSPEC_IEEE_MIN))]
20704   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20705   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20706   [(set_attr "type" "sseadd")
20707    (set_attr "prefix" "vex")
20708    (set_attr "mode" "<MODE>")])
20709
20710 (define_insn "*ieee_smin<mode>3"
20711   [(set (match_operand:MODEF 0 "register_operand" "=x")
20712         (unspec:MODEF
20713           [(match_operand:MODEF 1 "register_operand" "0")
20714            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20715          UNSPEC_IEEE_MIN))]
20716   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20717   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20718   [(set_attr "type" "sseadd")
20719    (set_attr "mode" "<MODE>")])
20720
20721 (define_insn "*avx_ieee_smax<mode>3"
20722   [(set (match_operand:MODEF 0 "register_operand" "=x")
20723         (unspec:MODEF
20724           [(match_operand:MODEF 1 "register_operand" "0")
20725            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20726          UNSPEC_IEEE_MAX))]
20727   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20728   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20729   [(set_attr "type" "sseadd")
20730    (set_attr "prefix" "vex")
20731    (set_attr "mode" "<MODE>")])
20732
20733 (define_insn "*ieee_smax<mode>3"
20734   [(set (match_operand:MODEF 0 "register_operand" "=x")
20735         (unspec:MODEF
20736           [(match_operand:MODEF 1 "register_operand" "0")
20737            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20738          UNSPEC_IEEE_MAX))]
20739   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20740   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20741   [(set_attr "type" "sseadd")
20742    (set_attr "mode" "<MODE>")])
20743
20744 ;; Make two stack loads independent:
20745 ;;   fld aa              fld aa
20746 ;;   fld %st(0)     ->   fld bb
20747 ;;   fmul bb             fmul %st(1), %st
20748 ;;
20749 ;; Actually we only match the last two instructions for simplicity.
20750 (define_peephole2
20751   [(set (match_operand 0 "fp_register_operand" "")
20752         (match_operand 1 "fp_register_operand" ""))
20753    (set (match_dup 0)
20754         (match_operator 2 "binary_fp_operator"
20755            [(match_dup 0)
20756             (match_operand 3 "memory_operand" "")]))]
20757   "REGNO (operands[0]) != REGNO (operands[1])"
20758   [(set (match_dup 0) (match_dup 3))
20759    (set (match_dup 0) (match_dup 4))]
20760
20761   ;; The % modifier is not operational anymore in peephole2's, so we have to
20762   ;; swap the operands manually in the case of addition and multiplication.
20763   "if (COMMUTATIVE_ARITH_P (operands[2]))
20764      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20765                                  operands[0], operands[1]);
20766    else
20767      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20768                                  operands[1], operands[0]);")
20769
20770 ;; Conditional addition patterns
20771 (define_expand "add<mode>cc"
20772   [(match_operand:SWI 0 "register_operand" "")
20773    (match_operand 1 "comparison_operator" "")
20774    (match_operand:SWI 2 "register_operand" "")
20775    (match_operand:SWI 3 "const_int_operand" "")]
20776   ""
20777   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20778
20779 \f
20780 ;; Misc patterns (?)
20781
20782 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20783 ;; Otherwise there will be nothing to keep
20784 ;;
20785 ;; [(set (reg ebp) (reg esp))]
20786 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20787 ;;  (clobber (eflags)]
20788 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20789 ;;
20790 ;; in proper program order.
20791 (define_insn "pro_epilogue_adjust_stack_1"
20792   [(set (match_operand:SI 0 "register_operand" "=r,r")
20793         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20794                  (match_operand:SI 2 "immediate_operand" "i,i")))
20795    (clobber (reg:CC FLAGS_REG))
20796    (clobber (mem:BLK (scratch)))]
20797   "!TARGET_64BIT"
20798 {
20799   switch (get_attr_type (insn))
20800     {
20801     case TYPE_IMOV:
20802       return "mov{l}\t{%1, %0|%0, %1}";
20803
20804     case TYPE_ALU:
20805       if (CONST_INT_P (operands[2])
20806           && (INTVAL (operands[2]) == 128
20807               || (INTVAL (operands[2]) < 0
20808                   && INTVAL (operands[2]) != -128)))
20809         {
20810           operands[2] = GEN_INT (-INTVAL (operands[2]));
20811           return "sub{l}\t{%2, %0|%0, %2}";
20812         }
20813       return "add{l}\t{%2, %0|%0, %2}";
20814
20815     case TYPE_LEA:
20816       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20817       return "lea{l}\t{%a2, %0|%0, %a2}";
20818
20819     default:
20820       gcc_unreachable ();
20821     }
20822 }
20823   [(set (attr "type")
20824         (cond [(and (eq_attr "alternative" "0") 
20825                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20826                  (const_string "alu")
20827                (match_operand:SI 2 "const0_operand" "")
20828                  (const_string "imov")
20829               ]
20830               (const_string "lea")))
20831    (set (attr "length_immediate")
20832         (cond [(eq_attr "type" "imov")
20833                  (const_string "0")
20834                (and (eq_attr "type" "alu")
20835                     (match_operand 2 "const128_operand" ""))
20836                  (const_string "1")
20837               ]
20838               (const_string "*")))
20839    (set_attr "mode" "SI")])
20840
20841 (define_insn "pro_epilogue_adjust_stack_rex64"
20842   [(set (match_operand:DI 0 "register_operand" "=r,r")
20843         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20844                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20845    (clobber (reg:CC FLAGS_REG))
20846    (clobber (mem:BLK (scratch)))]
20847   "TARGET_64BIT"
20848 {
20849   switch (get_attr_type (insn))
20850     {
20851     case TYPE_IMOV:
20852       return "mov{q}\t{%1, %0|%0, %1}";
20853
20854     case TYPE_ALU:
20855       if (CONST_INT_P (operands[2])
20856           /* Avoid overflows.  */
20857           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20858           && (INTVAL (operands[2]) == 128
20859               || (INTVAL (operands[2]) < 0
20860                   && INTVAL (operands[2]) != -128)))
20861         {
20862           operands[2] = GEN_INT (-INTVAL (operands[2]));
20863           return "sub{q}\t{%2, %0|%0, %2}";
20864         }
20865       return "add{q}\t{%2, %0|%0, %2}";
20866
20867     case TYPE_LEA:
20868       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20869       return "lea{q}\t{%a2, %0|%0, %a2}";
20870
20871     default:
20872       gcc_unreachable ();
20873     }
20874 }
20875   [(set (attr "type")
20876         (cond [(and (eq_attr "alternative" "0")
20877                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20878                  (const_string "alu")
20879                (match_operand:DI 2 "const0_operand" "")
20880                  (const_string "imov")
20881               ]
20882               (const_string "lea")))
20883    (set (attr "length_immediate")
20884         (cond [(eq_attr "type" "imov")
20885                  (const_string "0")
20886                (and (eq_attr "type" "alu")
20887                     (match_operand 2 "const128_operand" ""))
20888                  (const_string "1")
20889               ]
20890               (const_string "*")))
20891    (set_attr "mode" "DI")])
20892
20893 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20894   [(set (match_operand:DI 0 "register_operand" "=r,r")
20895         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20896                  (match_operand:DI 3 "immediate_operand" "i,i")))
20897    (use (match_operand:DI 2 "register_operand" "r,r"))
20898    (clobber (reg:CC FLAGS_REG))
20899    (clobber (mem:BLK (scratch)))]
20900   "TARGET_64BIT"
20901 {
20902   switch (get_attr_type (insn))
20903     {
20904     case TYPE_ALU:
20905       return "add{q}\t{%2, %0|%0, %2}";
20906
20907     case TYPE_LEA:
20908       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20909       return "lea{q}\t{%a2, %0|%0, %a2}";
20910
20911     default:
20912       gcc_unreachable ();
20913     }
20914 }
20915   [(set_attr "type" "alu,lea")
20916    (set_attr "mode" "DI")])
20917
20918 (define_insn "allocate_stack_worker_32"
20919   [(set (match_operand:SI 0 "register_operand" "=a")
20920         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20921                             UNSPECV_STACK_PROBE))
20922    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20923    (clobber (reg:CC FLAGS_REG))]
20924   "!TARGET_64BIT && TARGET_STACK_PROBE"
20925   "call\t___chkstk"
20926   [(set_attr "type" "multi")
20927    (set_attr "length" "5")])
20928
20929 (define_insn "allocate_stack_worker_64"
20930   [(set (match_operand:DI 0 "register_operand" "=a")
20931         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20932                             UNSPECV_STACK_PROBE))
20933    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20934    (clobber (reg:DI R10_REG))
20935    (clobber (reg:DI R11_REG))
20936    (clobber (reg:CC FLAGS_REG))]
20937   "TARGET_64BIT && TARGET_STACK_PROBE"
20938   "call\t___chkstk"
20939   [(set_attr "type" "multi")
20940    (set_attr "length" "5")])
20941
20942 (define_expand "allocate_stack"
20943   [(match_operand 0 "register_operand" "")
20944    (match_operand 1 "general_operand" "")]
20945   "TARGET_STACK_PROBE"
20946 {
20947   rtx x;
20948
20949 #ifndef CHECK_STACK_LIMIT
20950 #define CHECK_STACK_LIMIT 0
20951 #endif
20952
20953   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20954       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20955     {
20956       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20957                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20958       if (x != stack_pointer_rtx)
20959         emit_move_insn (stack_pointer_rtx, x);
20960     }
20961   else
20962     {
20963       x = copy_to_mode_reg (Pmode, operands[1]);
20964       if (TARGET_64BIT)
20965         x = gen_allocate_stack_worker_64 (x, x);
20966       else
20967         x = gen_allocate_stack_worker_32 (x, x);
20968       emit_insn (x);
20969     }
20970
20971   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20972   DONE;
20973 })
20974
20975 (define_expand "builtin_setjmp_receiver"
20976   [(label_ref (match_operand 0 "" ""))]
20977   "!TARGET_64BIT && flag_pic"
20978 {
20979 #if TARGET_MACHO
20980   if (TARGET_MACHO)
20981     {
20982       rtx xops[3];
20983       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20984       rtx label_rtx = gen_label_rtx ();
20985       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20986       xops[0] = xops[1] = picreg;
20987       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20988       ix86_expand_binary_operator (MINUS, SImode, xops);
20989     }
20990   else
20991 #endif
20992     emit_insn (gen_set_got (pic_offset_table_rtx));
20993   DONE;
20994 })
20995 \f
20996 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20997
20998 (define_split
20999   [(set (match_operand 0 "register_operand" "")
21000         (match_operator 3 "promotable_binary_operator"
21001            [(match_operand 1 "register_operand" "")
21002             (match_operand 2 "aligned_operand" "")]))
21003    (clobber (reg:CC FLAGS_REG))]
21004   "! TARGET_PARTIAL_REG_STALL && reload_completed
21005    && ((GET_MODE (operands[0]) == HImode
21006         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
21007             /* ??? next two lines just !satisfies_constraint_K (...) */
21008             || !CONST_INT_P (operands[2])
21009             || satisfies_constraint_K (operands[2])))
21010        || (GET_MODE (operands[0]) == QImode
21011            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21012   [(parallel [(set (match_dup 0)
21013                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21014               (clobber (reg:CC FLAGS_REG))])]
21015   "operands[0] = gen_lowpart (SImode, operands[0]);
21016    operands[1] = gen_lowpart (SImode, operands[1]);
21017    if (GET_CODE (operands[3]) != ASHIFT)
21018      operands[2] = gen_lowpart (SImode, operands[2]);
21019    PUT_MODE (operands[3], SImode);")
21020
21021 ; Promote the QImode tests, as i386 has encoding of the AND
21022 ; instruction with 32-bit sign-extended immediate and thus the
21023 ; instruction size is unchanged, except in the %eax case for
21024 ; which it is increased by one byte, hence the ! optimize_size.
21025 (define_split
21026   [(set (match_operand 0 "flags_reg_operand" "")
21027         (match_operator 2 "compare_operator"
21028           [(and (match_operand 3 "aligned_operand" "")
21029                 (match_operand 4 "const_int_operand" ""))
21030            (const_int 0)]))
21031    (set (match_operand 1 "register_operand" "")
21032         (and (match_dup 3) (match_dup 4)))]
21033   "! TARGET_PARTIAL_REG_STALL && reload_completed
21034    && optimize_insn_for_speed_p ()
21035    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21036        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21037    /* Ensure that the operand will remain sign-extended immediate.  */
21038    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21039   [(parallel [(set (match_dup 0)
21040                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21041                                     (const_int 0)]))
21042               (set (match_dup 1)
21043                    (and:SI (match_dup 3) (match_dup 4)))])]
21044 {
21045   operands[4]
21046     = gen_int_mode (INTVAL (operands[4])
21047                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21048   operands[1] = gen_lowpart (SImode, operands[1]);
21049   operands[3] = gen_lowpart (SImode, operands[3]);
21050 })
21051
21052 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21053 ; the TEST instruction with 32-bit sign-extended immediate and thus
21054 ; the instruction size would at least double, which is not what we
21055 ; want even with ! optimize_size.
21056 (define_split
21057   [(set (match_operand 0 "flags_reg_operand" "")
21058         (match_operator 1 "compare_operator"
21059           [(and (match_operand:HI 2 "aligned_operand" "")
21060                 (match_operand:HI 3 "const_int_operand" ""))
21061            (const_int 0)]))]
21062   "! TARGET_PARTIAL_REG_STALL && reload_completed
21063    && ! TARGET_FAST_PREFIX
21064    && optimize_insn_for_speed_p ()
21065    /* Ensure that the operand will remain sign-extended immediate.  */
21066    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21067   [(set (match_dup 0)
21068         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21069                          (const_int 0)]))]
21070 {
21071   operands[3]
21072     = gen_int_mode (INTVAL (operands[3])
21073                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21074   operands[2] = gen_lowpart (SImode, operands[2]);
21075 })
21076
21077 (define_split
21078   [(set (match_operand 0 "register_operand" "")
21079         (neg (match_operand 1 "register_operand" "")))
21080    (clobber (reg:CC FLAGS_REG))]
21081   "! TARGET_PARTIAL_REG_STALL && reload_completed
21082    && (GET_MODE (operands[0]) == HImode
21083        || (GET_MODE (operands[0]) == QImode
21084            && (TARGET_PROMOTE_QImode
21085                || optimize_insn_for_size_p ())))"
21086   [(parallel [(set (match_dup 0)
21087                    (neg:SI (match_dup 1)))
21088               (clobber (reg:CC FLAGS_REG))])]
21089   "operands[0] = gen_lowpart (SImode, operands[0]);
21090    operands[1] = gen_lowpart (SImode, operands[1]);")
21091
21092 (define_split
21093   [(set (match_operand 0 "register_operand" "")
21094         (not (match_operand 1 "register_operand" "")))]
21095   "! TARGET_PARTIAL_REG_STALL && reload_completed
21096    && (GET_MODE (operands[0]) == HImode
21097        || (GET_MODE (operands[0]) == QImode
21098            && (TARGET_PROMOTE_QImode
21099                || optimize_insn_for_size_p ())))"
21100   [(set (match_dup 0)
21101         (not:SI (match_dup 1)))]
21102   "operands[0] = gen_lowpart (SImode, operands[0]);
21103    operands[1] = gen_lowpart (SImode, operands[1]);")
21104
21105 (define_split
21106   [(set (match_operand 0 "register_operand" "")
21107         (if_then_else (match_operator 1 "comparison_operator"
21108                                 [(reg FLAGS_REG) (const_int 0)])
21109                       (match_operand 2 "register_operand" "")
21110                       (match_operand 3 "register_operand" "")))]
21111   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21112    && (GET_MODE (operands[0]) == HImode
21113        || (GET_MODE (operands[0]) == QImode
21114            && (TARGET_PROMOTE_QImode
21115                || optimize_insn_for_size_p ())))"
21116   [(set (match_dup 0)
21117         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21118   "operands[0] = gen_lowpart (SImode, operands[0]);
21119    operands[2] = gen_lowpart (SImode, operands[2]);
21120    operands[3] = gen_lowpart (SImode, operands[3]);")
21121
21122 \f
21123 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
21124 ;; transform a complex memory operation into two memory to register operations.
21125
21126 ;; Don't push memory operands
21127 (define_peephole2
21128   [(set (match_operand:SI 0 "push_operand" "")
21129         (match_operand:SI 1 "memory_operand" ""))
21130    (match_scratch:SI 2 "r")]
21131   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21132    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21133   [(set (match_dup 2) (match_dup 1))
21134    (set (match_dup 0) (match_dup 2))]
21135   "")
21136
21137 (define_peephole2
21138   [(set (match_operand:DI 0 "push_operand" "")
21139         (match_operand:DI 1 "memory_operand" ""))
21140    (match_scratch:DI 2 "r")]
21141   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21142    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21143   [(set (match_dup 2) (match_dup 1))
21144    (set (match_dup 0) (match_dup 2))]
21145   "")
21146
21147 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21148 ;; SImode pushes.
21149 (define_peephole2
21150   [(set (match_operand:SF 0 "push_operand" "")
21151         (match_operand:SF 1 "memory_operand" ""))
21152    (match_scratch:SF 2 "r")]
21153   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21154    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21155   [(set (match_dup 2) (match_dup 1))
21156    (set (match_dup 0) (match_dup 2))]
21157   "")
21158
21159 (define_peephole2
21160   [(set (match_operand:HI 0 "push_operand" "")
21161         (match_operand:HI 1 "memory_operand" ""))
21162    (match_scratch:HI 2 "r")]
21163   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21164    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21165   [(set (match_dup 2) (match_dup 1))
21166    (set (match_dup 0) (match_dup 2))]
21167   "")
21168
21169 (define_peephole2
21170   [(set (match_operand:QI 0 "push_operand" "")
21171         (match_operand:QI 1 "memory_operand" ""))
21172    (match_scratch:QI 2 "q")]
21173   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21174    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21175   [(set (match_dup 2) (match_dup 1))
21176    (set (match_dup 0) (match_dup 2))]
21177   "")
21178
21179 ;; Don't move an immediate directly to memory when the instruction
21180 ;; gets too big.
21181 (define_peephole2
21182   [(match_scratch:SI 1 "r")
21183    (set (match_operand:SI 0 "memory_operand" "")
21184         (const_int 0))]
21185   "optimize_insn_for_speed_p ()
21186    && ! TARGET_USE_MOV0
21187    && TARGET_SPLIT_LONG_MOVES
21188    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21189    && peep2_regno_dead_p (0, FLAGS_REG)"
21190   [(parallel [(set (match_dup 1) (const_int 0))
21191               (clobber (reg:CC FLAGS_REG))])
21192    (set (match_dup 0) (match_dup 1))]
21193   "")
21194
21195 (define_peephole2
21196   [(match_scratch:HI 1 "r")
21197    (set (match_operand:HI 0 "memory_operand" "")
21198         (const_int 0))]
21199   "optimize_insn_for_speed_p ()
21200    && ! TARGET_USE_MOV0
21201    && TARGET_SPLIT_LONG_MOVES
21202    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21203    && peep2_regno_dead_p (0, FLAGS_REG)"
21204   [(parallel [(set (match_dup 2) (const_int 0))
21205               (clobber (reg:CC FLAGS_REG))])
21206    (set (match_dup 0) (match_dup 1))]
21207   "operands[2] = gen_lowpart (SImode, operands[1]);")
21208
21209 (define_peephole2
21210   [(match_scratch:QI 1 "q")
21211    (set (match_operand:QI 0 "memory_operand" "")
21212         (const_int 0))]
21213   "optimize_insn_for_speed_p ()
21214    && ! TARGET_USE_MOV0
21215    && TARGET_SPLIT_LONG_MOVES
21216    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21217    && peep2_regno_dead_p (0, FLAGS_REG)"
21218   [(parallel [(set (match_dup 2) (const_int 0))
21219               (clobber (reg:CC FLAGS_REG))])
21220    (set (match_dup 0) (match_dup 1))]
21221   "operands[2] = gen_lowpart (SImode, operands[1]);")
21222
21223 (define_peephole2
21224   [(match_scratch:SI 2 "r")
21225    (set (match_operand:SI 0 "memory_operand" "")
21226         (match_operand:SI 1 "immediate_operand" ""))]
21227   "optimize_insn_for_speed_p ()
21228    && TARGET_SPLIT_LONG_MOVES
21229    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21230   [(set (match_dup 2) (match_dup 1))
21231    (set (match_dup 0) (match_dup 2))]
21232   "")
21233
21234 (define_peephole2
21235   [(match_scratch:HI 2 "r")
21236    (set (match_operand:HI 0 "memory_operand" "")
21237         (match_operand:HI 1 "immediate_operand" ""))]
21238   "optimize_insn_for_speed_p ()
21239    && TARGET_SPLIT_LONG_MOVES
21240    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21241   [(set (match_dup 2) (match_dup 1))
21242    (set (match_dup 0) (match_dup 2))]
21243   "")
21244
21245 (define_peephole2
21246   [(match_scratch:QI 2 "q")
21247    (set (match_operand:QI 0 "memory_operand" "")
21248         (match_operand:QI 1 "immediate_operand" ""))]
21249   "optimize_insn_for_speed_p ()
21250    && TARGET_SPLIT_LONG_MOVES
21251    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21252   [(set (match_dup 2) (match_dup 1))
21253    (set (match_dup 0) (match_dup 2))]
21254   "")
21255
21256 ;; Don't compare memory with zero, load and use a test instead.
21257 (define_peephole2
21258   [(set (match_operand 0 "flags_reg_operand" "")
21259         (match_operator 1 "compare_operator"
21260           [(match_operand:SI 2 "memory_operand" "")
21261            (const_int 0)]))
21262    (match_scratch:SI 3 "r")]
21263   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21264   [(set (match_dup 3) (match_dup 2))
21265    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21266   "")
21267
21268 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21269 ;; Don't split NOTs with a displacement operand, because resulting XOR
21270 ;; will not be pairable anyway.
21271 ;;
21272 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21273 ;; represented using a modRM byte.  The XOR replacement is long decoded,
21274 ;; so this split helps here as well.
21275 ;;
21276 ;; Note: Can't do this as a regular split because we can't get proper
21277 ;; lifetime information then.
21278
21279 (define_peephole2
21280   [(set (match_operand:SI 0 "nonimmediate_operand" "")
21281         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21282   "optimize_insn_for_speed_p ()
21283    && ((TARGET_NOT_UNPAIRABLE
21284         && (!MEM_P (operands[0])
21285             || !memory_displacement_operand (operands[0], SImode)))
21286        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21287    && peep2_regno_dead_p (0, FLAGS_REG)"
21288   [(parallel [(set (match_dup 0)
21289                    (xor:SI (match_dup 1) (const_int -1)))
21290               (clobber (reg:CC FLAGS_REG))])]
21291   "")
21292
21293 (define_peephole2
21294   [(set (match_operand:HI 0 "nonimmediate_operand" "")
21295         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21296   "optimize_insn_for_speed_p ()
21297    && ((TARGET_NOT_UNPAIRABLE
21298         && (!MEM_P (operands[0])
21299             || !memory_displacement_operand (operands[0], HImode)))
21300        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21301    && peep2_regno_dead_p (0, FLAGS_REG)"
21302   [(parallel [(set (match_dup 0)
21303                    (xor:HI (match_dup 1) (const_int -1)))
21304               (clobber (reg:CC FLAGS_REG))])]
21305   "")
21306
21307 (define_peephole2
21308   [(set (match_operand:QI 0 "nonimmediate_operand" "")
21309         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21310   "optimize_insn_for_speed_p ()
21311    && ((TARGET_NOT_UNPAIRABLE
21312         && (!MEM_P (operands[0])
21313             || !memory_displacement_operand (operands[0], QImode)))
21314        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21315    && peep2_regno_dead_p (0, FLAGS_REG)"
21316   [(parallel [(set (match_dup 0)
21317                    (xor:QI (match_dup 1) (const_int -1)))
21318               (clobber (reg:CC FLAGS_REG))])]
21319   "")
21320
21321 ;; Non pairable "test imm, reg" instructions can be translated to
21322 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
21323 ;; byte opcode instead of two, have a short form for byte operands),
21324 ;; so do it for other CPUs as well.  Given that the value was dead,
21325 ;; this should not create any new dependencies.  Pass on the sub-word
21326 ;; versions if we're concerned about partial register stalls.
21327
21328 (define_peephole2
21329   [(set (match_operand 0 "flags_reg_operand" "")
21330         (match_operator 1 "compare_operator"
21331           [(and:SI (match_operand:SI 2 "register_operand" "")
21332                    (match_operand:SI 3 "immediate_operand" ""))
21333            (const_int 0)]))]
21334   "ix86_match_ccmode (insn, CCNOmode)
21335    && (true_regnum (operands[2]) != AX_REG
21336        || satisfies_constraint_K (operands[3]))
21337    && peep2_reg_dead_p (1, operands[2])"
21338   [(parallel
21339      [(set (match_dup 0)
21340            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21341                             (const_int 0)]))
21342       (set (match_dup 2)
21343            (and:SI (match_dup 2) (match_dup 3)))])]
21344   "")
21345
21346 ;; We don't need to handle HImode case, because it will be promoted to SImode
21347 ;; on ! TARGET_PARTIAL_REG_STALL
21348
21349 (define_peephole2
21350   [(set (match_operand 0 "flags_reg_operand" "")
21351         (match_operator 1 "compare_operator"
21352           [(and:QI (match_operand:QI 2 "register_operand" "")
21353                    (match_operand:QI 3 "immediate_operand" ""))
21354            (const_int 0)]))]
21355   "! TARGET_PARTIAL_REG_STALL
21356    && ix86_match_ccmode (insn, CCNOmode)
21357    && true_regnum (operands[2]) != AX_REG
21358    && peep2_reg_dead_p (1, operands[2])"
21359   [(parallel
21360      [(set (match_dup 0)
21361            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21362                             (const_int 0)]))
21363       (set (match_dup 2)
21364            (and:QI (match_dup 2) (match_dup 3)))])]
21365   "")
21366
21367 (define_peephole2
21368   [(set (match_operand 0 "flags_reg_operand" "")
21369         (match_operator 1 "compare_operator"
21370           [(and:SI
21371              (zero_extract:SI
21372                (match_operand 2 "ext_register_operand" "")
21373                (const_int 8)
21374                (const_int 8))
21375              (match_operand 3 "const_int_operand" ""))
21376            (const_int 0)]))]
21377   "! TARGET_PARTIAL_REG_STALL
21378    && ix86_match_ccmode (insn, CCNOmode)
21379    && true_regnum (operands[2]) != AX_REG
21380    && peep2_reg_dead_p (1, operands[2])"
21381   [(parallel [(set (match_dup 0)
21382                    (match_op_dup 1
21383                      [(and:SI
21384                         (zero_extract:SI
21385                           (match_dup 2)
21386                           (const_int 8)
21387                           (const_int 8))
21388                         (match_dup 3))
21389                       (const_int 0)]))
21390               (set (zero_extract:SI (match_dup 2)
21391                                     (const_int 8)
21392                                     (const_int 8))
21393                    (and:SI
21394                      (zero_extract:SI
21395                        (match_dup 2)
21396                        (const_int 8)
21397                        (const_int 8))
21398                      (match_dup 3)))])]
21399   "")
21400
21401 ;; Don't do logical operations with memory inputs.
21402 (define_peephole2
21403   [(match_scratch:SI 2 "r")
21404    (parallel [(set (match_operand:SI 0 "register_operand" "")
21405                    (match_operator:SI 3 "arith_or_logical_operator"
21406                      [(match_dup 0)
21407                       (match_operand:SI 1 "memory_operand" "")]))
21408               (clobber (reg:CC FLAGS_REG))])]
21409   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21410   [(set (match_dup 2) (match_dup 1))
21411    (parallel [(set (match_dup 0)
21412                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21413               (clobber (reg:CC FLAGS_REG))])]
21414   "")
21415
21416 (define_peephole2
21417   [(match_scratch:SI 2 "r")
21418    (parallel [(set (match_operand:SI 0 "register_operand" "")
21419                    (match_operator:SI 3 "arith_or_logical_operator"
21420                      [(match_operand:SI 1 "memory_operand" "")
21421                       (match_dup 0)]))
21422               (clobber (reg:CC FLAGS_REG))])]
21423   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21424   [(set (match_dup 2) (match_dup 1))
21425    (parallel [(set (match_dup 0)
21426                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21427               (clobber (reg:CC FLAGS_REG))])]
21428   "")
21429
21430 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
21431 ;; refers to the destination of the load!
21432
21433 (define_peephole2
21434   [(set (match_operand:SI 0 "register_operand" "")
21435         (match_operand:SI 1 "register_operand" ""))
21436    (parallel [(set (match_dup 0)
21437                    (match_operator:SI 3 "commutative_operator"
21438                      [(match_dup 0)
21439                       (match_operand:SI 2 "memory_operand" "")]))
21440               (clobber (reg:CC FLAGS_REG))])]
21441   "REGNO (operands[0]) != REGNO (operands[1])
21442    && GENERAL_REGNO_P (REGNO (operands[0]))
21443    && GENERAL_REGNO_P (REGNO (operands[1]))"
21444   [(set (match_dup 0) (match_dup 4))
21445    (parallel [(set (match_dup 0)
21446                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21447               (clobber (reg:CC FLAGS_REG))])]
21448   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21449
21450 (define_peephole2
21451   [(set (match_operand 0 "register_operand" "")
21452         (match_operand 1 "register_operand" ""))
21453    (set (match_dup 0)
21454                    (match_operator 3 "commutative_operator"
21455                      [(match_dup 0)
21456                       (match_operand 2 "memory_operand" "")]))]
21457   "REGNO (operands[0]) != REGNO (operands[1])
21458    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
21459        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21460   [(set (match_dup 0) (match_dup 2))
21461    (set (match_dup 0)
21462         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21463   "")
21464
21465 ; Don't do logical operations with memory outputs
21466 ;
21467 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21468 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
21469 ; the same decoder scheduling characteristics as the original.
21470
21471 (define_peephole2
21472   [(match_scratch:SI 2 "r")
21473    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21474                    (match_operator:SI 3 "arith_or_logical_operator"
21475                      [(match_dup 0)
21476                       (match_operand:SI 1 "nonmemory_operand" "")]))
21477               (clobber (reg:CC FLAGS_REG))])]
21478   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21479   [(set (match_dup 2) (match_dup 0))
21480    (parallel [(set (match_dup 2)
21481                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21482               (clobber (reg:CC FLAGS_REG))])
21483    (set (match_dup 0) (match_dup 2))]
21484   "")
21485
21486 (define_peephole2
21487   [(match_scratch:SI 2 "r")
21488    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21489                    (match_operator:SI 3 "arith_or_logical_operator"
21490                      [(match_operand:SI 1 "nonmemory_operand" "")
21491                       (match_dup 0)]))
21492               (clobber (reg:CC FLAGS_REG))])]
21493   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21494   [(set (match_dup 2) (match_dup 0))
21495    (parallel [(set (match_dup 2)
21496                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21497               (clobber (reg:CC FLAGS_REG))])
21498    (set (match_dup 0) (match_dup 2))]
21499   "")
21500
21501 ;; Attempt to always use XOR for zeroing registers.
21502 (define_peephole2
21503   [(set (match_operand 0 "register_operand" "")
21504         (match_operand 1 "const0_operand" ""))]
21505   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21506    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21507    && GENERAL_REG_P (operands[0])
21508    && peep2_regno_dead_p (0, FLAGS_REG)"
21509   [(parallel [(set (match_dup 0) (const_int 0))
21510               (clobber (reg:CC FLAGS_REG))])]
21511 {
21512   operands[0] = gen_lowpart (word_mode, operands[0]);
21513 })
21514
21515 (define_peephole2
21516   [(set (strict_low_part (match_operand 0 "register_operand" ""))
21517         (const_int 0))]
21518   "(GET_MODE (operands[0]) == QImode
21519     || GET_MODE (operands[0]) == HImode)
21520    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21521    && peep2_regno_dead_p (0, FLAGS_REG)"
21522   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21523               (clobber (reg:CC FLAGS_REG))])])
21524
21525 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21526 (define_peephole2
21527   [(set (match_operand 0 "register_operand" "")
21528         (const_int -1))]
21529   "(GET_MODE (operands[0]) == HImode
21530     || GET_MODE (operands[0]) == SImode
21531     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21532    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21533    && peep2_regno_dead_p (0, FLAGS_REG)"
21534   [(parallel [(set (match_dup 0) (const_int -1))
21535               (clobber (reg:CC FLAGS_REG))])]
21536   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21537                               operands[0]);")
21538
21539 ;; Attempt to convert simple leas to adds. These can be created by
21540 ;; move expanders.
21541 (define_peephole2
21542   [(set (match_operand:SI 0 "register_operand" "")
21543         (plus:SI (match_dup 0)
21544                  (match_operand:SI 1 "nonmemory_operand" "")))]
21545   "peep2_regno_dead_p (0, FLAGS_REG)"
21546   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21547               (clobber (reg:CC FLAGS_REG))])]
21548   "")
21549
21550 (define_peephole2
21551   [(set (match_operand:SI 0 "register_operand" "")
21552         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21553                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21554   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21555   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21556               (clobber (reg:CC FLAGS_REG))])]
21557   "operands[2] = gen_lowpart (SImode, operands[2]);")
21558
21559 (define_peephole2
21560   [(set (match_operand:DI 0 "register_operand" "")
21561         (plus:DI (match_dup 0)
21562                  (match_operand:DI 1 "x86_64_general_operand" "")))]
21563   "peep2_regno_dead_p (0, FLAGS_REG)"
21564   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21565               (clobber (reg:CC FLAGS_REG))])]
21566   "")
21567
21568 (define_peephole2
21569   [(set (match_operand:SI 0 "register_operand" "")
21570         (mult:SI (match_dup 0)
21571                  (match_operand:SI 1 "const_int_operand" "")))]
21572   "exact_log2 (INTVAL (operands[1])) >= 0
21573    && peep2_regno_dead_p (0, FLAGS_REG)"
21574   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21575               (clobber (reg:CC FLAGS_REG))])]
21576   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21577
21578 (define_peephole2
21579   [(set (match_operand:DI 0 "register_operand" "")
21580         (mult:DI (match_dup 0)
21581                  (match_operand:DI 1 "const_int_operand" "")))]
21582   "exact_log2 (INTVAL (operands[1])) >= 0
21583    && peep2_regno_dead_p (0, FLAGS_REG)"
21584   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21585               (clobber (reg:CC FLAGS_REG))])]
21586   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21587
21588 (define_peephole2
21589   [(set (match_operand:SI 0 "register_operand" "")
21590         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21591                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21592   "exact_log2 (INTVAL (operands[2])) >= 0
21593    && REGNO (operands[0]) == REGNO (operands[1])
21594    && peep2_regno_dead_p (0, FLAGS_REG)"
21595   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21596               (clobber (reg:CC FLAGS_REG))])]
21597   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21598
21599 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21600 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21601 ;; many CPUs it is also faster, since special hardware to avoid esp
21602 ;; dependencies is present.
21603
21604 ;; While some of these conversions may be done using splitters, we use peepholes
21605 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21606
21607 ;; Convert prologue esp subtractions to push.
21608 ;; We need register to push.  In order to keep verify_flow_info happy we have
21609 ;; two choices
21610 ;; - use scratch and clobber it in order to avoid dependencies
21611 ;; - use already live register
21612 ;; We can't use the second way right now, since there is no reliable way how to
21613 ;; verify that given register is live.  First choice will also most likely in
21614 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21615 ;; call clobbered registers are dead.  We may want to use base pointer as an
21616 ;; alternative when no register is available later.
21617
21618 (define_peephole2
21619   [(match_scratch:SI 0 "r")
21620    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21621               (clobber (reg:CC FLAGS_REG))
21622               (clobber (mem:BLK (scratch)))])]
21623   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21624   [(clobber (match_dup 0))
21625    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21626               (clobber (mem:BLK (scratch)))])])
21627
21628 (define_peephole2
21629   [(match_scratch:SI 0 "r")
21630    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21631               (clobber (reg:CC FLAGS_REG))
21632               (clobber (mem:BLK (scratch)))])]
21633   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21634   [(clobber (match_dup 0))
21635    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21636    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21637               (clobber (mem:BLK (scratch)))])])
21638
21639 ;; Convert esp subtractions to push.
21640 (define_peephole2
21641   [(match_scratch:SI 0 "r")
21642    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21643               (clobber (reg:CC FLAGS_REG))])]
21644   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21645   [(clobber (match_dup 0))
21646    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21647
21648 (define_peephole2
21649   [(match_scratch:SI 0 "r")
21650    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21651               (clobber (reg:CC FLAGS_REG))])]
21652   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21653   [(clobber (match_dup 0))
21654    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21655    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21656
21657 ;; Convert epilogue deallocator to pop.
21658 (define_peephole2
21659   [(match_scratch:SI 0 "r")
21660    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21661               (clobber (reg:CC FLAGS_REG))
21662               (clobber (mem:BLK (scratch)))])]
21663   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21664   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21665               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21666               (clobber (mem:BLK (scratch)))])]
21667   "")
21668
21669 ;; Two pops case is tricky, since pop causes dependency on destination register.
21670 ;; We use two registers if available.
21671 (define_peephole2
21672   [(match_scratch:SI 0 "r")
21673    (match_scratch:SI 1 "r")
21674    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21675               (clobber (reg:CC FLAGS_REG))
21676               (clobber (mem:BLK (scratch)))])]
21677   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21678   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21679               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21680               (clobber (mem:BLK (scratch)))])
21681    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21682               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21683   "")
21684
21685 (define_peephole2
21686   [(match_scratch:SI 0 "r")
21687    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21688               (clobber (reg:CC FLAGS_REG))
21689               (clobber (mem:BLK (scratch)))])]
21690   "optimize_insn_for_size_p ()"
21691   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21692               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21693               (clobber (mem:BLK (scratch)))])
21694    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21695               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21696   "")
21697
21698 ;; Convert esp additions to pop.
21699 (define_peephole2
21700   [(match_scratch:SI 0 "r")
21701    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21702               (clobber (reg:CC FLAGS_REG))])]
21703   ""
21704   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21705               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21706   "")
21707
21708 ;; Two pops case is tricky, since pop causes dependency on destination register.
21709 ;; We use two registers if available.
21710 (define_peephole2
21711   [(match_scratch:SI 0 "r")
21712    (match_scratch:SI 1 "r")
21713    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21714               (clobber (reg:CC FLAGS_REG))])]
21715   ""
21716   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21717               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21718    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21719               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21720   "")
21721
21722 (define_peephole2
21723   [(match_scratch:SI 0 "r")
21724    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21725               (clobber (reg:CC FLAGS_REG))])]
21726   "optimize_insn_for_size_p ()"
21727   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21728               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21729    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21730               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21731   "")
21732 \f
21733 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21734 ;; required and register dies.  Similarly for 128 to -128.
21735 (define_peephole2
21736   [(set (match_operand 0 "flags_reg_operand" "")
21737         (match_operator 1 "compare_operator"
21738           [(match_operand 2 "register_operand" "")
21739            (match_operand 3 "const_int_operand" "")]))]
21740   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21741      && incdec_operand (operands[3], GET_MODE (operands[3])))
21742     || (!TARGET_FUSE_CMP_AND_BRANCH
21743         && INTVAL (operands[3]) == 128))
21744    && ix86_match_ccmode (insn, CCGCmode)
21745    && peep2_reg_dead_p (1, operands[2])"
21746   [(parallel [(set (match_dup 0)
21747                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21748               (clobber (match_dup 2))])]
21749   "")
21750 \f
21751 (define_peephole2
21752   [(match_scratch:DI 0 "r")
21753    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21754               (clobber (reg:CC FLAGS_REG))
21755               (clobber (mem:BLK (scratch)))])]
21756   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21757   [(clobber (match_dup 0))
21758    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21759               (clobber (mem:BLK (scratch)))])])
21760
21761 (define_peephole2
21762   [(match_scratch:DI 0 "r")
21763    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21764               (clobber (reg:CC FLAGS_REG))
21765               (clobber (mem:BLK (scratch)))])]
21766   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21767   [(clobber (match_dup 0))
21768    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21769    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21770               (clobber (mem:BLK (scratch)))])])
21771
21772 ;; Convert esp subtractions to push.
21773 (define_peephole2
21774   [(match_scratch:DI 0 "r")
21775    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21776               (clobber (reg:CC FLAGS_REG))])]
21777   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21778   [(clobber (match_dup 0))
21779    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21780
21781 (define_peephole2
21782   [(match_scratch:DI 0 "r")
21783    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21784               (clobber (reg:CC FLAGS_REG))])]
21785   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21786   [(clobber (match_dup 0))
21787    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21788    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21789
21790 ;; Convert epilogue deallocator to pop.
21791 (define_peephole2
21792   [(match_scratch:DI 0 "r")
21793    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21794               (clobber (reg:CC FLAGS_REG))
21795               (clobber (mem:BLK (scratch)))])]
21796   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21797   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21798               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21799               (clobber (mem:BLK (scratch)))])]
21800   "")
21801
21802 ;; Two pops case is tricky, since pop causes dependency on destination register.
21803 ;; We use two registers if available.
21804 (define_peephole2
21805   [(match_scratch:DI 0 "r")
21806    (match_scratch:DI 1 "r")
21807    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21808               (clobber (reg:CC FLAGS_REG))
21809               (clobber (mem:BLK (scratch)))])]
21810   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21811   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21812               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21813               (clobber (mem:BLK (scratch)))])
21814    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21815               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21816   "")
21817
21818 (define_peephole2
21819   [(match_scratch:DI 0 "r")
21820    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21821               (clobber (reg:CC FLAGS_REG))
21822               (clobber (mem:BLK (scratch)))])]
21823   "optimize_insn_for_size_p ()"
21824   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21825               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21826               (clobber (mem:BLK (scratch)))])
21827    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21828               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21829   "")
21830
21831 ;; Convert esp additions to pop.
21832 (define_peephole2
21833   [(match_scratch:DI 0 "r")
21834    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21835               (clobber (reg:CC FLAGS_REG))])]
21836   ""
21837   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21838               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21839   "")
21840
21841 ;; Two pops case is tricky, since pop causes dependency on destination register.
21842 ;; We use two registers if available.
21843 (define_peephole2
21844   [(match_scratch:DI 0 "r")
21845    (match_scratch:DI 1 "r")
21846    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21847               (clobber (reg:CC FLAGS_REG))])]
21848   ""
21849   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21850               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21851    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21852               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21853   "")
21854
21855 (define_peephole2
21856   [(match_scratch:DI 0 "r")
21857    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21858               (clobber (reg:CC FLAGS_REG))])]
21859   "optimize_insn_for_size_p ()"
21860   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21861               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21862    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21863               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21864   "")
21865 \f
21866 ;; Convert imul by three, five and nine into lea
21867 (define_peephole2
21868   [(parallel
21869     [(set (match_operand:SI 0 "register_operand" "")
21870           (mult:SI (match_operand:SI 1 "register_operand" "")
21871                    (match_operand:SI 2 "const_int_operand" "")))
21872      (clobber (reg:CC FLAGS_REG))])]
21873   "INTVAL (operands[2]) == 3
21874    || INTVAL (operands[2]) == 5
21875    || INTVAL (operands[2]) == 9"
21876   [(set (match_dup 0)
21877         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21878                  (match_dup 1)))]
21879   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21880
21881 (define_peephole2
21882   [(parallel
21883     [(set (match_operand:SI 0 "register_operand" "")
21884           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21885                    (match_operand:SI 2 "const_int_operand" "")))
21886      (clobber (reg:CC FLAGS_REG))])]
21887   "optimize_insn_for_speed_p ()
21888    && (INTVAL (operands[2]) == 3
21889        || INTVAL (operands[2]) == 5
21890        || INTVAL (operands[2]) == 9)"
21891   [(set (match_dup 0) (match_dup 1))
21892    (set (match_dup 0)
21893         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21894                  (match_dup 0)))]
21895   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21896
21897 (define_peephole2
21898   [(parallel
21899     [(set (match_operand:DI 0 "register_operand" "")
21900           (mult:DI (match_operand:DI 1 "register_operand" "")
21901                    (match_operand:DI 2 "const_int_operand" "")))
21902      (clobber (reg:CC FLAGS_REG))])]
21903   "TARGET_64BIT
21904    && (INTVAL (operands[2]) == 3
21905        || INTVAL (operands[2]) == 5
21906        || INTVAL (operands[2]) == 9)"
21907   [(set (match_dup 0)
21908         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21909                  (match_dup 1)))]
21910   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21911
21912 (define_peephole2
21913   [(parallel
21914     [(set (match_operand:DI 0 "register_operand" "")
21915           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21916                    (match_operand:DI 2 "const_int_operand" "")))
21917      (clobber (reg:CC FLAGS_REG))])]
21918   "TARGET_64BIT
21919    && optimize_insn_for_speed_p ()
21920    && (INTVAL (operands[2]) == 3
21921        || INTVAL (operands[2]) == 5
21922        || INTVAL (operands[2]) == 9)"
21923   [(set (match_dup 0) (match_dup 1))
21924    (set (match_dup 0)
21925         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21926                  (match_dup 0)))]
21927   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21928
21929 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21930 ;; imul $32bit_imm, reg, reg is direct decoded.
21931 (define_peephole2
21932   [(match_scratch:DI 3 "r")
21933    (parallel [(set (match_operand:DI 0 "register_operand" "")
21934                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21935                             (match_operand:DI 2 "immediate_operand" "")))
21936               (clobber (reg:CC FLAGS_REG))])]
21937   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21938    && !satisfies_constraint_K (operands[2])"
21939   [(set (match_dup 3) (match_dup 1))
21940    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21941               (clobber (reg:CC FLAGS_REG))])]
21942 "")
21943
21944 (define_peephole2
21945   [(match_scratch:SI 3 "r")
21946    (parallel [(set (match_operand:SI 0 "register_operand" "")
21947                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21948                             (match_operand:SI 2 "immediate_operand" "")))
21949               (clobber (reg:CC FLAGS_REG))])]
21950   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21951    && !satisfies_constraint_K (operands[2])"
21952   [(set (match_dup 3) (match_dup 1))
21953    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21954               (clobber (reg:CC FLAGS_REG))])]
21955 "")
21956
21957 (define_peephole2
21958   [(match_scratch:SI 3 "r")
21959    (parallel [(set (match_operand:DI 0 "register_operand" "")
21960                    (zero_extend:DI
21961                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21962                               (match_operand:SI 2 "immediate_operand" ""))))
21963               (clobber (reg:CC FLAGS_REG))])]
21964   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21965    && !satisfies_constraint_K (operands[2])"
21966   [(set (match_dup 3) (match_dup 1))
21967    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21968               (clobber (reg:CC FLAGS_REG))])]
21969 "")
21970
21971 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21972 ;; Convert it into imul reg, reg
21973 ;; It would be better to force assembler to encode instruction using long
21974 ;; immediate, but there is apparently no way to do so.
21975 (define_peephole2
21976   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21977                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21978                             (match_operand:DI 2 "const_int_operand" "")))
21979               (clobber (reg:CC FLAGS_REG))])
21980    (match_scratch:DI 3 "r")]
21981   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21982    && satisfies_constraint_K (operands[2])"
21983   [(set (match_dup 3) (match_dup 2))
21984    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21985               (clobber (reg:CC FLAGS_REG))])]
21986 {
21987   if (!rtx_equal_p (operands[0], operands[1]))
21988     emit_move_insn (operands[0], operands[1]);
21989 })
21990
21991 (define_peephole2
21992   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21993                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21994                             (match_operand:SI 2 "const_int_operand" "")))
21995               (clobber (reg:CC FLAGS_REG))])
21996    (match_scratch:SI 3 "r")]
21997   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21998    && satisfies_constraint_K (operands[2])"
21999   [(set (match_dup 3) (match_dup 2))
22000    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
22001               (clobber (reg:CC FLAGS_REG))])]
22002 {
22003   if (!rtx_equal_p (operands[0], operands[1]))
22004     emit_move_insn (operands[0], operands[1]);
22005 })
22006
22007 (define_peephole2
22008   [(parallel [(set (match_operand:HI 0 "register_operand" "")
22009                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22010                             (match_operand:HI 2 "immediate_operand" "")))
22011               (clobber (reg:CC FLAGS_REG))])
22012    (match_scratch:HI 3 "r")]
22013   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22014   [(set (match_dup 3) (match_dup 2))
22015    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22016               (clobber (reg:CC FLAGS_REG))])]
22017 {
22018   if (!rtx_equal_p (operands[0], operands[1]))
22019     emit_move_insn (operands[0], operands[1]);
22020 })
22021
22022 ;; After splitting up read-modify operations, array accesses with memory
22023 ;; operands might end up in form:
22024 ;;  sall    $2, %eax
22025 ;;  movl    4(%esp), %edx
22026 ;;  addl    %edx, %eax
22027 ;; instead of pre-splitting:
22028 ;;  sall    $2, %eax
22029 ;;  addl    4(%esp), %eax
22030 ;; Turn it into:
22031 ;;  movl    4(%esp), %edx
22032 ;;  leal    (%edx,%eax,4), %eax
22033
22034 (define_peephole2
22035   [(parallel [(set (match_operand 0 "register_operand" "")
22036                    (ashift (match_operand 1 "register_operand" "")
22037                            (match_operand 2 "const_int_operand" "")))
22038                (clobber (reg:CC FLAGS_REG))])
22039    (set (match_operand 3 "register_operand")
22040         (match_operand 4 "x86_64_general_operand" ""))
22041    (parallel [(set (match_operand 5 "register_operand" "")
22042                    (plus (match_operand 6 "register_operand" "")
22043                          (match_operand 7 "register_operand" "")))
22044                    (clobber (reg:CC FLAGS_REG))])]
22045   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22046    /* Validate MODE for lea.  */
22047    && ((!TARGET_PARTIAL_REG_STALL
22048         && (GET_MODE (operands[0]) == QImode
22049             || GET_MODE (operands[0]) == HImode))
22050        || GET_MODE (operands[0]) == SImode
22051        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22052    /* We reorder load and the shift.  */
22053    && !rtx_equal_p (operands[1], operands[3])
22054    && !reg_overlap_mentioned_p (operands[0], operands[4])
22055    /* Last PLUS must consist of operand 0 and 3.  */
22056    && !rtx_equal_p (operands[0], operands[3])
22057    && (rtx_equal_p (operands[3], operands[6])
22058        || rtx_equal_p (operands[3], operands[7]))
22059    && (rtx_equal_p (operands[0], operands[6])
22060        || rtx_equal_p (operands[0], operands[7]))
22061    /* The intermediate operand 0 must die or be same as output.  */
22062    && (rtx_equal_p (operands[0], operands[5])
22063        || peep2_reg_dead_p (3, operands[0]))"
22064   [(set (match_dup 3) (match_dup 4))
22065    (set (match_dup 0) (match_dup 1))]
22066 {
22067   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22068   int scale = 1 << INTVAL (operands[2]);
22069   rtx index = gen_lowpart (Pmode, operands[1]);
22070   rtx base = gen_lowpart (Pmode, operands[3]);
22071   rtx dest = gen_lowpart (mode, operands[5]);
22072
22073   operands[1] = gen_rtx_PLUS (Pmode, base,
22074                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22075   if (mode != Pmode)
22076     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22077   operands[0] = dest;
22078 })
22079 \f
22080 ;; Call-value patterns last so that the wildcard operand does not
22081 ;; disrupt insn-recog's switch tables.
22082
22083 (define_insn "*call_value_pop_0"
22084   [(set (match_operand 0 "" "")
22085         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22086               (match_operand:SI 2 "" "")))
22087    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22088                             (match_operand:SI 3 "immediate_operand" "")))]
22089   "!TARGET_64BIT"
22090 {
22091   if (SIBLING_CALL_P (insn))
22092     return "jmp\t%P1";
22093   else
22094     return "call\t%P1";
22095 }
22096   [(set_attr "type" "callv")])
22097
22098 (define_insn "*call_value_pop_1"
22099   [(set (match_operand 0 "" "")
22100         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22101               (match_operand:SI 2 "" "")))
22102    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22103                             (match_operand:SI 3 "immediate_operand" "i")))]
22104   "!TARGET_64BIT"
22105 {
22106   if (constant_call_address_operand (operands[1], Pmode))
22107     {
22108       if (SIBLING_CALL_P (insn))
22109         return "jmp\t%P1";
22110       else
22111         return "call\t%P1";
22112     }
22113   if (SIBLING_CALL_P (insn))
22114     return "jmp\t%A1";
22115   else
22116     return "call\t%A1";
22117 }
22118   [(set_attr "type" "callv")])
22119
22120 (define_insn "*call_value_0"
22121   [(set (match_operand 0 "" "")
22122         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22123               (match_operand:SI 2 "" "")))]
22124   "!TARGET_64BIT"
22125 {
22126   if (SIBLING_CALL_P (insn))
22127     return "jmp\t%P1";
22128   else
22129     return "call\t%P1";
22130 }
22131   [(set_attr "type" "callv")])
22132
22133 (define_insn "*call_value_0_rex64"
22134   [(set (match_operand 0 "" "")
22135         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22136               (match_operand:DI 2 "const_int_operand" "")))]
22137   "TARGET_64BIT"
22138 {
22139   if (SIBLING_CALL_P (insn))
22140     return "jmp\t%P1";
22141   else
22142     return "call\t%P1";
22143 }
22144   [(set_attr "type" "callv")])
22145
22146 (define_insn "*call_value_0_rex64_ms_sysv"
22147   [(set (match_operand 0 "" "")
22148         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22149               (match_operand:DI 2 "const_int_operand" "")))
22150    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22151    (clobber (reg:TI XMM6_REG))
22152    (clobber (reg:TI XMM7_REG))
22153    (clobber (reg:TI XMM8_REG))
22154    (clobber (reg:TI XMM9_REG))
22155    (clobber (reg:TI XMM10_REG))
22156    (clobber (reg:TI XMM11_REG))
22157    (clobber (reg:TI XMM12_REG))
22158    (clobber (reg:TI XMM13_REG))
22159    (clobber (reg:TI XMM14_REG))
22160    (clobber (reg:TI XMM15_REG))
22161    (clobber (reg:DI SI_REG))
22162    (clobber (reg:DI DI_REG))]
22163   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22164 {
22165   if (SIBLING_CALL_P (insn))
22166     return "jmp\t%P1";
22167   else
22168     return "call\t%P1";
22169 }
22170   [(set_attr "type" "callv")])
22171
22172 (define_insn "*call_value_1"
22173   [(set (match_operand 0 "" "")
22174         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22175               (match_operand:SI 2 "" "")))]
22176   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22177 {
22178   if (constant_call_address_operand (operands[1], Pmode))
22179     return "call\t%P1";
22180   return "call\t%A1";
22181 }
22182   [(set_attr "type" "callv")])
22183
22184 (define_insn "*sibcall_value_1"
22185   [(set (match_operand 0 "" "")
22186         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
22187               (match_operand:SI 2 "" "")))]
22188   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22189 {
22190   if (constant_call_address_operand (operands[1], Pmode))
22191     return "jmp\t%P1";
22192   return "jmp\t%A1";
22193 }
22194   [(set_attr "type" "callv")])
22195
22196 (define_insn "*call_value_1_rex64"
22197   [(set (match_operand 0 "" "")
22198         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22199               (match_operand:DI 2 "" "")))]
22200   "!SIBLING_CALL_P (insn) && TARGET_64BIT
22201    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22202 {
22203   if (constant_call_address_operand (operands[1], Pmode))
22204     return "call\t%P1";
22205   return "call\t%A1";
22206 }
22207   [(set_attr "type" "callv")])
22208
22209 (define_insn "*call_value_1_rex64_ms_sysv"
22210   [(set (match_operand 0 "" "")
22211         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22212               (match_operand:DI 2 "" "")))
22213    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22214    (clobber (reg:TI 27))
22215    (clobber (reg:TI 28))
22216    (clobber (reg:TI 45))
22217    (clobber (reg:TI 46))
22218    (clobber (reg:TI 47))
22219    (clobber (reg:TI 48))
22220    (clobber (reg:TI 49))
22221    (clobber (reg:TI 50))
22222    (clobber (reg:TI 51))
22223    (clobber (reg:TI 52))
22224    (clobber (reg:DI SI_REG))
22225    (clobber (reg:DI DI_REG))]
22226   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22227 {
22228   if (constant_call_address_operand (operands[1], Pmode))
22229     return "call\t%P1";
22230   return "call\t%A1";
22231 }
22232   [(set_attr "type" "callv")])
22233
22234 (define_insn "*call_value_1_rex64_large"
22235   [(set (match_operand 0 "" "")
22236         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22237               (match_operand:DI 2 "" "")))]
22238   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22239   "call\t%A1"
22240   [(set_attr "type" "callv")])
22241
22242 (define_insn "*sibcall_value_1_rex64"
22243   [(set (match_operand 0 "" "")
22244         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22245               (match_operand:DI 2 "" "")))]
22246   "SIBLING_CALL_P (insn) && TARGET_64BIT"
22247   "jmp\t%P1"
22248   [(set_attr "type" "callv")])
22249
22250 (define_insn "*sibcall_value_1_rex64_v"
22251   [(set (match_operand 0 "" "")
22252         (call (mem:QI (reg:DI R11_REG))
22253               (match_operand:DI 1 "" "")))]
22254   "SIBLING_CALL_P (insn) && TARGET_64BIT"
22255   "jmp\t{*%%}r11"
22256   [(set_attr "type" "callv")])
22257 \f
22258 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22259 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22260 ;; caught for use by garbage collectors and the like.  Using an insn that
22261 ;; maps to SIGILL makes it more likely the program will rightfully die.
22262 ;; Keeping with tradition, "6" is in honor of #UD.
22263 (define_insn "trap"
22264   [(trap_if (const_int 1) (const_int 6))]
22265   ""
22266   { return ASM_SHORT "0x0b0f"; }
22267   [(set_attr "length" "2")])
22268
22269 (define_expand "sse_prologue_save"
22270   [(parallel [(set (match_operand:BLK 0 "" "")
22271                    (unspec:BLK [(reg:DI 21)
22272                                 (reg:DI 22)
22273                                 (reg:DI 23)
22274                                 (reg:DI 24)
22275                                 (reg:DI 25)
22276                                 (reg:DI 26)
22277                                 (reg:DI 27)
22278                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22279               (use (match_operand:DI 1 "register_operand" ""))
22280               (use (match_operand:DI 2 "immediate_operand" ""))
22281               (use (label_ref:DI (match_operand 3 "" "")))])]
22282   "TARGET_64BIT"
22283   "")
22284
22285 (define_insn "*sse_prologue_save_insn"
22286   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22287                           (match_operand:DI 4 "const_int_operand" "n")))
22288         (unspec:BLK [(reg:DI 21)
22289                      (reg:DI 22)
22290                      (reg:DI 23)
22291                      (reg:DI 24)
22292                      (reg:DI 25)
22293                      (reg:DI 26)
22294                      (reg:DI 27)
22295                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22296    (use (match_operand:DI 1 "register_operand" "r"))
22297    (use (match_operand:DI 2 "const_int_operand" "i"))
22298    (use (label_ref:DI (match_operand 3 "" "X")))]
22299   "TARGET_64BIT
22300    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22301    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22302 {
22303   int i;
22304   operands[0] = gen_rtx_MEM (Pmode,
22305                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22306   /* VEX instruction with a REX prefix will #UD.  */
22307   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22308     gcc_unreachable ();
22309
22310   output_asm_insn ("jmp\t%A1", operands);
22311   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22312     {
22313       operands[4] = adjust_address (operands[0], DImode, i*16);
22314       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22315       PUT_MODE (operands[4], TImode);
22316       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22317         output_asm_insn ("rex", operands);
22318       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22319     }
22320   (*targetm.asm_out.internal_label) (asm_out_file, "L",
22321                                      CODE_LABEL_NUMBER (operands[3]));
22322   return "";
22323 }
22324   [(set_attr "type" "other")
22325    (set_attr "length_immediate" "0")
22326    (set_attr "length_address" "0")
22327    (set (attr "length")
22328      (if_then_else
22329        (eq (symbol_ref "TARGET_AVX") (const_int 0))
22330        (const_string "34")
22331        (const_string "42")))
22332    (set_attr "memory" "store")
22333    (set_attr "modrm" "0")
22334    (set_attr "prefix" "maybe_vex")
22335    (set_attr "mode" "DI")])
22336
22337 (define_expand "prefetch"
22338   [(prefetch (match_operand 0 "address_operand" "")
22339              (match_operand:SI 1 "const_int_operand" "")
22340              (match_operand:SI 2 "const_int_operand" ""))]
22341   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22342 {
22343   int rw = INTVAL (operands[1]);
22344   int locality = INTVAL (operands[2]);
22345
22346   gcc_assert (rw == 0 || rw == 1);
22347   gcc_assert (locality >= 0 && locality <= 3);
22348   gcc_assert (GET_MODE (operands[0]) == Pmode
22349               || GET_MODE (operands[0]) == VOIDmode);
22350
22351   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22352      supported by SSE counterpart or the SSE prefetch is not available
22353      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22354      of locality.  */
22355   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22356     operands[2] = GEN_INT (3);
22357   else
22358     operands[1] = const0_rtx;
22359 })
22360
22361 (define_insn "*prefetch_sse"
22362   [(prefetch (match_operand:SI 0 "address_operand" "p")
22363              (const_int 0)
22364              (match_operand:SI 1 "const_int_operand" ""))]
22365   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22366 {
22367   static const char * const patterns[4] = {
22368    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22369   };
22370
22371   int locality = INTVAL (operands[1]);
22372   gcc_assert (locality >= 0 && locality <= 3);
22373
22374   return patterns[locality];
22375 }
22376   [(set_attr "type" "sse")
22377    (set_attr "atom_sse_attr" "prefetch")
22378    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22379    (set_attr "memory" "none")])
22380
22381 (define_insn "*prefetch_sse_rex"
22382   [(prefetch (match_operand:DI 0 "address_operand" "p")
22383              (const_int 0)
22384              (match_operand:SI 1 "const_int_operand" ""))]
22385   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22386 {
22387   static const char * const patterns[4] = {
22388    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22389   };
22390
22391   int locality = INTVAL (operands[1]);
22392   gcc_assert (locality >= 0 && locality <= 3);
22393
22394   return patterns[locality];
22395 }
22396   [(set_attr "type" "sse")
22397    (set_attr "atom_sse_attr" "prefetch")
22398    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22399    (set_attr "memory" "none")])
22400
22401 (define_insn "*prefetch_3dnow"
22402   [(prefetch (match_operand:SI 0 "address_operand" "p")
22403              (match_operand:SI 1 "const_int_operand" "n")
22404              (const_int 3))]
22405   "TARGET_3DNOW && !TARGET_64BIT"
22406 {
22407   if (INTVAL (operands[1]) == 0)
22408     return "prefetch\t%a0";
22409   else
22410     return "prefetchw\t%a0";
22411 }
22412   [(set_attr "type" "mmx")
22413    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22414    (set_attr "memory" "none")])
22415
22416 (define_insn "*prefetch_3dnow_rex"
22417   [(prefetch (match_operand:DI 0 "address_operand" "p")
22418              (match_operand:SI 1 "const_int_operand" "n")
22419              (const_int 3))]
22420   "TARGET_3DNOW && TARGET_64BIT"
22421 {
22422   if (INTVAL (operands[1]) == 0)
22423     return "prefetch\t%a0";
22424   else
22425     return "prefetchw\t%a0";
22426 }
22427   [(set_attr "type" "mmx")
22428    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22429    (set_attr "memory" "none")])
22430
22431 (define_expand "stack_protect_set"
22432   [(match_operand 0 "memory_operand" "")
22433    (match_operand 1 "memory_operand" "")]
22434   ""
22435 {
22436 #ifdef TARGET_THREAD_SSP_OFFSET
22437   if (TARGET_64BIT)
22438     emit_insn (gen_stack_tls_protect_set_di (operands[0],
22439                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22440   else
22441     emit_insn (gen_stack_tls_protect_set_si (operands[0],
22442                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22443 #else
22444   if (TARGET_64BIT)
22445     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22446   else
22447     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22448 #endif
22449   DONE;
22450 })
22451
22452 (define_insn "stack_protect_set_si"
22453   [(set (match_operand:SI 0 "memory_operand" "=m")
22454         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22455    (set (match_scratch:SI 2 "=&r") (const_int 0))
22456    (clobber (reg:CC FLAGS_REG))]
22457   ""
22458   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22459   [(set_attr "type" "multi")])
22460
22461 (define_insn "stack_protect_set_di"
22462   [(set (match_operand:DI 0 "memory_operand" "=m")
22463         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22464    (set (match_scratch:DI 2 "=&r") (const_int 0))
22465    (clobber (reg:CC FLAGS_REG))]
22466   "TARGET_64BIT"
22467   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22468   [(set_attr "type" "multi")])
22469
22470 (define_insn "stack_tls_protect_set_si"
22471   [(set (match_operand:SI 0 "memory_operand" "=m")
22472         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22473    (set (match_scratch:SI 2 "=&r") (const_int 0))
22474    (clobber (reg:CC FLAGS_REG))]
22475   ""
22476   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22477   [(set_attr "type" "multi")])
22478
22479 (define_insn "stack_tls_protect_set_di"
22480   [(set (match_operand:DI 0 "memory_operand" "=m")
22481         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22482    (set (match_scratch:DI 2 "=&r") (const_int 0))
22483    (clobber (reg:CC FLAGS_REG))]
22484   "TARGET_64BIT"
22485   {
22486      /* The kernel uses a different segment register for performance reasons; a
22487         system call would not have to trash the userspace segment register,
22488         which would be expensive */
22489      if (ix86_cmodel != CM_KERNEL)
22490         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22491      else
22492         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22493   }
22494   [(set_attr "type" "multi")])
22495
22496 (define_expand "stack_protect_test"
22497   [(match_operand 0 "memory_operand" "")
22498    (match_operand 1 "memory_operand" "")
22499    (match_operand 2 "" "")]
22500   ""
22501 {
22502   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22503
22504 #ifdef TARGET_THREAD_SSP_OFFSET
22505   if (TARGET_64BIT)
22506     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22507                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22508   else
22509     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22510                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22511 #else
22512   if (TARGET_64BIT)
22513     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22514   else
22515     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22516 #endif
22517
22518   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22519                                   flags, const0_rtx, operands[2]));
22520   DONE;
22521 })
22522
22523 (define_insn "stack_protect_test_si"
22524   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22525         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22526                      (match_operand:SI 2 "memory_operand" "m")]
22527                     UNSPEC_SP_TEST))
22528    (clobber (match_scratch:SI 3 "=&r"))]
22529   ""
22530   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22531   [(set_attr "type" "multi")])
22532
22533 (define_insn "stack_protect_test_di"
22534   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22535         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22536                      (match_operand:DI 2 "memory_operand" "m")]
22537                     UNSPEC_SP_TEST))
22538    (clobber (match_scratch:DI 3 "=&r"))]
22539   "TARGET_64BIT"
22540   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22541   [(set_attr "type" "multi")])
22542
22543 (define_insn "stack_tls_protect_test_si"
22544   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22545         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22546                      (match_operand:SI 2 "const_int_operand" "i")]
22547                     UNSPEC_SP_TLS_TEST))
22548    (clobber (match_scratch:SI 3 "=r"))]
22549   ""
22550   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22551   [(set_attr "type" "multi")])
22552
22553 (define_insn "stack_tls_protect_test_di"
22554   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22555         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22556                      (match_operand:DI 2 "const_int_operand" "i")]
22557                     UNSPEC_SP_TLS_TEST))
22558    (clobber (match_scratch:DI 3 "=r"))]
22559   "TARGET_64BIT"
22560   {
22561      /* The kernel uses a different segment register for performance reasons; a
22562         system call would not have to trash the userspace segment register,
22563         which would be expensive */
22564      if (ix86_cmodel != CM_KERNEL)
22565         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22566      else
22567         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22568   }
22569   [(set_attr "type" "multi")])
22570
22571 (define_mode_iterator CRC32MODE [QI HI SI])
22572 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22573 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22574
22575 (define_insn "sse4_2_crc32<mode>"
22576   [(set (match_operand:SI 0 "register_operand" "=r")
22577         (unspec:SI
22578           [(match_operand:SI 1 "register_operand" "0")
22579            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22580           UNSPEC_CRC32))]
22581   "TARGET_SSE4_2 || TARGET_CRC32"
22582   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22583   [(set_attr "type" "sselog1")
22584    (set_attr "prefix_rep" "1")
22585    (set_attr "prefix_extra" "1")
22586    (set (attr "prefix_data16")
22587      (if_then_else (match_operand:HI 2 "" "")
22588        (const_string "1")
22589        (const_string "*")))
22590    (set (attr "prefix_rex")
22591      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22592        (const_string "1")
22593        (const_string "*")))
22594    (set_attr "mode" "SI")])
22595
22596 (define_insn "sse4_2_crc32di"
22597   [(set (match_operand:DI 0 "register_operand" "=r")
22598         (unspec:DI
22599           [(match_operand:DI 1 "register_operand" "0")
22600            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22601           UNSPEC_CRC32))]
22602   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22603   "crc32q\t{%2, %0|%0, %2}"
22604   [(set_attr "type" "sselog1")
22605    (set_attr "prefix_rep" "1")
22606    (set_attr "prefix_extra" "1")
22607    (set_attr "mode" "DI")])
22608
22609 (define_expand "rdpmc"
22610   [(match_operand:DI 0 "register_operand" "")
22611    (match_operand:SI 1 "register_operand" "")]
22612   ""
22613 {
22614   rtx reg = gen_reg_rtx (DImode);
22615   rtx si;
22616
22617   /* Force operand 1 into ECX.  */
22618   rtx ecx = gen_rtx_REG (SImode, CX_REG);
22619   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
22620   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
22621                                 UNSPECV_RDPMC);
22622
22623   if (TARGET_64BIT)
22624     {
22625       rtvec vec = rtvec_alloc (2);
22626       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22627       rtx upper = gen_reg_rtx (DImode);
22628       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22629                                         gen_rtvec (1, const0_rtx),
22630                                         UNSPECV_RDPMC);
22631       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
22632       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22633       emit_insn (load);
22634       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22635                                    NULL, 1, OPTAB_DIRECT);
22636       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22637                                  OPTAB_DIRECT);
22638     }
22639   else
22640     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
22641   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22642   DONE;
22643 })
22644
22645 (define_insn "*rdpmc"
22646   [(set (match_operand:DI 0 "register_operand" "=A")
22647         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
22648                             UNSPECV_RDPMC))]
22649   "!TARGET_64BIT"
22650   "rdpmc"
22651   [(set_attr "type" "other")
22652    (set_attr "length" "2")])
22653
22654 (define_insn "*rdpmc_rex64"
22655   [(set (match_operand:DI 0 "register_operand" "=a")
22656         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
22657                             UNSPECV_RDPMC))
22658   (set (match_operand:DI 1 "register_operand" "=d")
22659        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
22660   "TARGET_64BIT"
22661   "rdpmc"
22662   [(set_attr "type" "other")
22663    (set_attr "length" "2")])
22664
22665 (define_expand "rdtsc"
22666   [(set (match_operand:DI 0 "register_operand" "")
22667         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22668   ""
22669 {
22670   if (TARGET_64BIT)
22671     {
22672       rtvec vec = rtvec_alloc (2);
22673       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22674       rtx upper = gen_reg_rtx (DImode);
22675       rtx lower = gen_reg_rtx (DImode);
22676       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
22677                                          gen_rtvec (1, const0_rtx),
22678                                          UNSPECV_RDTSC);
22679       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
22680       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
22681       emit_insn (load);
22682       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22683                                    NULL, 1, OPTAB_DIRECT);
22684       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
22685                                    OPTAB_DIRECT);
22686       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
22687       DONE;
22688     }
22689 })
22690
22691 (define_insn "*rdtsc"
22692   [(set (match_operand:DI 0 "register_operand" "=A")
22693         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22694   "!TARGET_64BIT"
22695   "rdtsc"
22696   [(set_attr "type" "other")
22697    (set_attr "length" "2")])
22698
22699 (define_insn "*rdtsc_rex64"
22700   [(set (match_operand:DI 0 "register_operand" "=a")
22701         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
22702    (set (match_operand:DI 1 "register_operand" "=d")
22703         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22704   "TARGET_64BIT"
22705   "rdtsc"
22706   [(set_attr "type" "other")
22707    (set_attr "length" "2")])
22708
22709 (define_expand "rdtscp"
22710   [(match_operand:DI 0 "register_operand" "")
22711    (match_operand:SI 1 "memory_operand" "")]
22712   ""
22713 {
22714   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22715                                     gen_rtvec (1, const0_rtx),
22716                                     UNSPECV_RDTSCP);
22717   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
22718                                     gen_rtvec (1, const0_rtx),
22719                                     UNSPECV_RDTSCP);
22720   rtx reg = gen_reg_rtx (DImode);
22721   rtx tmp = gen_reg_rtx (SImode);
22722
22723   if (TARGET_64BIT)
22724     {
22725       rtvec vec = rtvec_alloc (3);
22726       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22727       rtx upper = gen_reg_rtx (DImode);
22728       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22729       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22730       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22731       emit_insn (load);
22732       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22733                                    NULL, 1, OPTAB_DIRECT);
22734       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22735                                  OPTAB_DIRECT);
22736     }
22737   else
22738     {
22739       rtvec vec = rtvec_alloc (2);
22740       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22741       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22742       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22743       emit_insn (load);
22744     }
22745   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22746   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22747   DONE;
22748 })
22749
22750 (define_insn "*rdtscp"
22751   [(set (match_operand:DI 0 "register_operand" "=A")
22752         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22753    (set (match_operand:SI 1 "register_operand" "=c")
22754         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22755   "!TARGET_64BIT"
22756   "rdtscp"
22757   [(set_attr "type" "other")
22758    (set_attr "length" "3")])
22759
22760 (define_insn "*rdtscp_rex64"
22761   [(set (match_operand:DI 0 "register_operand" "=a")
22762         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22763    (set (match_operand:DI 1 "register_operand" "=d")
22764         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22765    (set (match_operand:SI 2 "register_operand" "=c")
22766         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22767   "TARGET_64BIT"
22768   "rdtscp"
22769   [(set_attr "type" "other")
22770    (set_attr "length" "3")])
22771
22772 (include "mmx.md")
22773 (include "sse.md")
22774 (include "sync.md")