OSDN Git Service

PR target/38900
[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    && can_create_pseudo_p ()"
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    && can_create_pseudo_p ()"
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    && can_create_pseudo_p ()"
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    && can_create_pseudo_p ()"
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,U"))
15540          (match_operand 1 "" ""))]
15541   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15542   "@
15543    jmp\t%P0
15544    jmp\t%A0"
15545   [(set_attr "type" "call")])
15546
15547 (define_insn "*call_1_rex64"
15548   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15549          (match_operand 1 "" ""))]
15550   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15551    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15552 {
15553   if (constant_call_address_operand (operands[0], Pmode))
15554     return "call\t%P0";
15555   return "call\t%A0";
15556 }
15557   [(set_attr "type" "call")])
15558
15559 (define_insn "*call_1_rex64_ms_sysv"
15560   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15561          (match_operand 1 "" ""))
15562    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15563    (clobber (reg:TI XMM6_REG))
15564    (clobber (reg:TI XMM7_REG))
15565    (clobber (reg:TI XMM8_REG))
15566    (clobber (reg:TI XMM9_REG))
15567    (clobber (reg:TI XMM10_REG))
15568    (clobber (reg:TI XMM11_REG))
15569    (clobber (reg:TI XMM12_REG))
15570    (clobber (reg:TI XMM13_REG))
15571    (clobber (reg:TI XMM14_REG))
15572    (clobber (reg:TI XMM15_REG))
15573    (clobber (reg:DI SI_REG))
15574    (clobber (reg:DI DI_REG))]
15575   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15576 {
15577   if (constant_call_address_operand (operands[0], Pmode))
15578     return "call\t%P0";
15579   return "call\t%A0";
15580 }
15581   [(set_attr "type" "call")])
15582
15583 (define_insn "*call_1_rex64_large"
15584   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15585          (match_operand 1 "" ""))]
15586   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15587   "call\t%A0"
15588   [(set_attr "type" "call")])
15589
15590 (define_insn "*sibcall_1_rex64"
15591   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15592          (match_operand 1 "" ""))]
15593   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15594   "@
15595    jmp\t%P0
15596    jmp\t%A0"
15597   [(set_attr "type" "call")])
15598
15599 ;; Call subroutine, returning value in operand 0
15600 (define_expand "call_value_pop"
15601   [(parallel [(set (match_operand 0 "" "")
15602                    (call (match_operand:QI 1 "" "")
15603                          (match_operand:SI 2 "" "")))
15604               (set (reg:SI SP_REG)
15605                    (plus:SI (reg:SI SP_REG)
15606                             (match_operand:SI 4 "" "")))])]
15607   "!TARGET_64BIT"
15608 {
15609   ix86_expand_call (operands[0], operands[1], operands[2],
15610                     operands[3], operands[4], 0);
15611   DONE;
15612 })
15613
15614 (define_expand "call_value"
15615   [(set (match_operand 0 "" "")
15616         (call (match_operand:QI 1 "" "")
15617               (match_operand:SI 2 "" "")))
15618    (use (match_operand:SI 3 "" ""))]
15619   ;; Operand 2 not used on the i386.
15620   ""
15621 {
15622   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15623   DONE;
15624 })
15625
15626 (define_expand "sibcall_value"
15627   [(set (match_operand 0 "" "")
15628         (call (match_operand:QI 1 "" "")
15629               (match_operand:SI 2 "" "")))
15630    (use (match_operand:SI 3 "" ""))]
15631   ;; Operand 2 not used on the i386.
15632   ""
15633 {
15634   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15635   DONE;
15636 })
15637
15638 ;; Call subroutine returning any type.
15639
15640 (define_expand "untyped_call"
15641   [(parallel [(call (match_operand 0 "" "")
15642                     (const_int 0))
15643               (match_operand 1 "" "")
15644               (match_operand 2 "" "")])]
15645   ""
15646 {
15647   int i;
15648
15649   /* In order to give reg-stack an easier job in validating two
15650      coprocessor registers as containing a possible return value,
15651      simply pretend the untyped call returns a complex long double
15652      value. 
15653
15654      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15655      and should have the default ABI.  */
15656
15657   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15658                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15659                     operands[0], const0_rtx,
15660                     GEN_INT ((TARGET_64BIT
15661                               ? (ix86_abi == SYSV_ABI
15662                                  ? X86_64_SSE_REGPARM_MAX
15663                                  : X86_64_MS_SSE_REGPARM_MAX)
15664                               : X86_32_SSE_REGPARM_MAX)
15665                              - 1),
15666                     NULL, 0);
15667
15668   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15669     {
15670       rtx set = XVECEXP (operands[2], 0, i);
15671       emit_move_insn (SET_DEST (set), SET_SRC (set));
15672     }
15673
15674   /* The optimizer does not know that the call sets the function value
15675      registers we stored in the result block.  We avoid problems by
15676      claiming that all hard registers are used and clobbered at this
15677      point.  */
15678   emit_insn (gen_blockage ());
15679
15680   DONE;
15681 })
15682 \f
15683 ;; Prologue and epilogue instructions
15684
15685 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15686 ;; all of memory.  This blocks insns from being moved across this point.
15687
15688 (define_insn "blockage"
15689   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15690   ""
15691   ""
15692   [(set_attr "length" "0")])
15693
15694 ;; Do not schedule instructions accessing memory across this point.
15695
15696 (define_expand "memory_blockage"
15697   [(set (match_dup 0)
15698         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15699   ""
15700 {
15701   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15702   MEM_VOLATILE_P (operands[0]) = 1;
15703 })
15704
15705 (define_insn "*memory_blockage"
15706   [(set (match_operand:BLK 0 "" "")
15707         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15708   ""
15709   ""
15710   [(set_attr "length" "0")])
15711
15712 ;; As USE insns aren't meaningful after reload, this is used instead
15713 ;; to prevent deleting instructions setting registers for PIC code
15714 (define_insn "prologue_use"
15715   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15716   ""
15717   ""
15718   [(set_attr "length" "0")])
15719
15720 ;; Insn emitted into the body of a function to return from a function.
15721 ;; This is only done if the function's epilogue is known to be simple.
15722 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15723
15724 (define_expand "return"
15725   [(return)]
15726   "ix86_can_use_return_insn_p ()"
15727 {
15728   if (crtl->args.pops_args)
15729     {
15730       rtx popc = GEN_INT (crtl->args.pops_args);
15731       emit_jump_insn (gen_return_pop_internal (popc));
15732       DONE;
15733     }
15734 })
15735
15736 (define_insn "return_internal"
15737   [(return)]
15738   "reload_completed"
15739   "ret"
15740   [(set_attr "length" "1")
15741    (set_attr "atom_unit" "jeu")
15742    (set_attr "length_immediate" "0")
15743    (set_attr "modrm" "0")])
15744
15745 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15746 ;; instruction Athlon and K8 have.
15747
15748 (define_insn "return_internal_long"
15749   [(return)
15750    (unspec [(const_int 0)] UNSPEC_REP)]
15751   "reload_completed"
15752   "rep\;ret"
15753   [(set_attr "length" "2")
15754    (set_attr "atom_unit" "jeu")
15755    (set_attr "length_immediate" "0")
15756    (set_attr "prefix_rep" "1")
15757    (set_attr "modrm" "0")])
15758
15759 (define_insn "return_pop_internal"
15760   [(return)
15761    (use (match_operand:SI 0 "const_int_operand" ""))]
15762   "reload_completed"
15763   "ret\t%0"
15764   [(set_attr "length" "3")
15765    (set_attr "atom_unit" "jeu")
15766    (set_attr "length_immediate" "2")
15767    (set_attr "modrm" "0")])
15768
15769 (define_insn "return_indirect_internal"
15770   [(return)
15771    (use (match_operand:SI 0 "register_operand" "r"))]
15772   "reload_completed"
15773   "jmp\t%A0"
15774   [(set_attr "type" "ibr")
15775    (set_attr "length_immediate" "0")])
15776
15777 (define_insn "nop"
15778   [(const_int 0)]
15779   ""
15780   "nop"
15781   [(set_attr "length" "1")
15782    (set_attr "length_immediate" "0")
15783    (set_attr "modrm" "0")])
15784
15785 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
15786 ;; branch prediction penalty for the third jump in a 16-byte
15787 ;; block on K8.
15788
15789 (define_insn "pad"
15790   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15791   ""
15792 {
15793 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15794   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15795 #else
15796   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15797      The align insn is used to avoid 3 jump instructions in the row to improve
15798      branch prediction and the benefits hardly outweigh the cost of extra 8
15799      nops on the average inserted by full alignment pseudo operation.  */
15800 #endif
15801   return "";
15802 }
15803   [(set_attr "length" "16")])
15804
15805 (define_expand "prologue"
15806   [(const_int 0)]
15807   ""
15808   "ix86_expand_prologue (); DONE;")
15809
15810 (define_insn "set_got"
15811   [(set (match_operand:SI 0 "register_operand" "=r")
15812         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15813    (clobber (reg:CC FLAGS_REG))]
15814   "!TARGET_64BIT"
15815   { return output_set_got (operands[0], NULL_RTX); }
15816   [(set_attr "type" "multi")
15817    (set_attr "length" "12")])
15818
15819 (define_insn "set_got_labelled"
15820   [(set (match_operand:SI 0 "register_operand" "=r")
15821         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15822          UNSPEC_SET_GOT))
15823    (clobber (reg:CC FLAGS_REG))]
15824   "!TARGET_64BIT"
15825   { return output_set_got (operands[0], operands[1]); }
15826   [(set_attr "type" "multi")
15827    (set_attr "length" "12")])
15828
15829 (define_insn "set_got_rex64"
15830   [(set (match_operand:DI 0 "register_operand" "=r")
15831         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15832   "TARGET_64BIT"
15833   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15834   [(set_attr "type" "lea")
15835    (set_attr "length_address" "4")
15836    (set_attr "mode" "DI")])
15837
15838 (define_insn "set_rip_rex64"
15839   [(set (match_operand:DI 0 "register_operand" "=r")
15840         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15841   "TARGET_64BIT"
15842   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15843   [(set_attr "type" "lea")
15844    (set_attr "length_address" "4")
15845    (set_attr "mode" "DI")])
15846
15847 (define_insn "set_got_offset_rex64"
15848   [(set (match_operand:DI 0 "register_operand" "=r")
15849         (unspec:DI
15850           [(label_ref (match_operand 1 "" ""))]
15851           UNSPEC_SET_GOT_OFFSET))]
15852   "TARGET_64BIT"
15853   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15854   [(set_attr "type" "imov")
15855    (set_attr "length_immediate" "0")
15856    (set_attr "length_address" "8")
15857    (set_attr "mode" "DI")])
15858
15859 (define_expand "epilogue"
15860   [(const_int 0)]
15861   ""
15862   "ix86_expand_epilogue (1); DONE;")
15863
15864 (define_expand "sibcall_epilogue"
15865   [(const_int 0)]
15866   ""
15867   "ix86_expand_epilogue (0); DONE;")
15868
15869 (define_expand "eh_return"
15870   [(use (match_operand 0 "register_operand" ""))]
15871   ""
15872 {
15873   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15874
15875   /* Tricky bit: we write the address of the handler to which we will
15876      be returning into someone else's stack frame, one word below the
15877      stack address we wish to restore.  */
15878   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15879   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15880   tmp = gen_rtx_MEM (Pmode, tmp);
15881   emit_move_insn (tmp, ra);
15882
15883   emit_jump_insn (gen_eh_return_internal ());
15884   emit_barrier ();
15885   DONE;
15886 })
15887
15888 (define_insn_and_split "eh_return_internal"
15889   [(eh_return)]
15890   ""
15891   "#"
15892   "epilogue_completed"
15893   [(const_int 0)]
15894   "ix86_expand_epilogue (2); DONE;")
15895
15896 (define_insn "leave"
15897   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15898    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15899    (clobber (mem:BLK (scratch)))]
15900   "!TARGET_64BIT"
15901   "leave"
15902   [(set_attr "type" "leave")])
15903
15904 (define_insn "leave_rex64"
15905   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15906    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15907    (clobber (mem:BLK (scratch)))]
15908   "TARGET_64BIT"
15909   "leave"
15910   [(set_attr "type" "leave")])
15911 \f
15912 (define_expand "ffssi2"
15913   [(parallel
15914      [(set (match_operand:SI 0 "register_operand" "")
15915            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15916       (clobber (match_scratch:SI 2 ""))
15917       (clobber (reg:CC FLAGS_REG))])]
15918   ""
15919 {
15920   if (TARGET_CMOVE)
15921     {
15922       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15923       DONE;
15924     }
15925 })
15926
15927 (define_expand "ffs_cmove"
15928   [(set (match_dup 2) (const_int -1))
15929    (parallel [(set (reg:CCZ FLAGS_REG)
15930                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15931                                 (const_int 0)))
15932               (set (match_operand:SI 0 "register_operand" "")
15933                    (ctz:SI (match_dup 1)))])
15934    (set (match_dup 0) (if_then_else:SI
15935                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15936                         (match_dup 2)
15937                         (match_dup 0)))
15938    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15939               (clobber (reg:CC FLAGS_REG))])]
15940   "TARGET_CMOVE"
15941   "operands[2] = gen_reg_rtx (SImode);")
15942
15943 (define_insn_and_split "*ffs_no_cmove"
15944   [(set (match_operand:SI 0 "register_operand" "=r")
15945         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15946    (clobber (match_scratch:SI 2 "=&q"))
15947    (clobber (reg:CC FLAGS_REG))]
15948   "!TARGET_CMOVE"
15949   "#"
15950   "&& reload_completed"
15951   [(parallel [(set (reg:CCZ FLAGS_REG)
15952                    (compare:CCZ (match_dup 1) (const_int 0)))
15953               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15954    (set (strict_low_part (match_dup 3))
15955         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15956    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15957               (clobber (reg:CC FLAGS_REG))])
15958    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15959               (clobber (reg:CC FLAGS_REG))])
15960    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15961               (clobber (reg:CC FLAGS_REG))])]
15962 {
15963   operands[3] = gen_lowpart (QImode, operands[2]);
15964   ix86_expand_clear (operands[2]);
15965 })
15966
15967 (define_insn "*ffssi_1"
15968   [(set (reg:CCZ FLAGS_REG)
15969         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15970                      (const_int 0)))
15971    (set (match_operand:SI 0 "register_operand" "=r")
15972         (ctz:SI (match_dup 1)))]
15973   ""
15974   "bsf{l}\t{%1, %0|%0, %1}"
15975   [(set_attr "type" "alu1")
15976    (set_attr "prefix_0f" "1")
15977    (set_attr "mode" "SI")])
15978
15979 (define_expand "ffsdi2"
15980   [(set (match_dup 2) (const_int -1))
15981    (parallel [(set (reg:CCZ FLAGS_REG)
15982                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15983                                 (const_int 0)))
15984               (set (match_operand:DI 0 "register_operand" "")
15985                    (ctz:DI (match_dup 1)))])
15986    (set (match_dup 0) (if_then_else:DI
15987                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15988                         (match_dup 2)
15989                         (match_dup 0)))
15990    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15991               (clobber (reg:CC FLAGS_REG))])]
15992   "TARGET_64BIT"
15993   "operands[2] = gen_reg_rtx (DImode);")
15994
15995 (define_insn "*ffsdi_1"
15996   [(set (reg:CCZ FLAGS_REG)
15997         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15998                      (const_int 0)))
15999    (set (match_operand:DI 0 "register_operand" "=r")
16000         (ctz:DI (match_dup 1)))]
16001   "TARGET_64BIT"
16002   "bsf{q}\t{%1, %0|%0, %1}"
16003   [(set_attr "type" "alu1")
16004    (set_attr "prefix_0f" "1")
16005    (set_attr "mode" "DI")])
16006
16007 (define_insn "ctzsi2"
16008   [(set (match_operand:SI 0 "register_operand" "=r")
16009         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16010    (clobber (reg:CC FLAGS_REG))]
16011   ""
16012   "bsf{l}\t{%1, %0|%0, %1}"
16013   [(set_attr "type" "alu1")
16014    (set_attr "prefix_0f" "1")
16015    (set_attr "mode" "SI")])
16016
16017 (define_insn "ctzdi2"
16018   [(set (match_operand:DI 0 "register_operand" "=r")
16019         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16020    (clobber (reg:CC FLAGS_REG))]
16021   "TARGET_64BIT"
16022   "bsf{q}\t{%1, %0|%0, %1}"
16023   [(set_attr "type" "alu1")
16024    (set_attr "prefix_0f" "1")
16025    (set_attr "mode" "DI")])
16026
16027 (define_expand "clzsi2"
16028   [(parallel
16029      [(set (match_operand:SI 0 "register_operand" "")
16030            (minus:SI (const_int 31)
16031                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16032       (clobber (reg:CC FLAGS_REG))])
16033    (parallel
16034      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16035       (clobber (reg:CC FLAGS_REG))])]
16036   ""
16037 {
16038   if (TARGET_ABM)
16039     {
16040       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16041       DONE;
16042     }
16043 })
16044
16045 (define_insn "clzsi2_abm"
16046   [(set (match_operand:SI 0 "register_operand" "=r")
16047         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16048    (clobber (reg:CC FLAGS_REG))]
16049   "TARGET_ABM"
16050   "lzcnt{l}\t{%1, %0|%0, %1}"
16051   [(set_attr "prefix_rep" "1")
16052    (set_attr "type" "bitmanip")
16053    (set_attr "mode" "SI")])
16054
16055 (define_insn "bsr"
16056   [(set (match_operand:SI 0 "register_operand" "=r")
16057         (minus:SI (const_int 31)
16058                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16059    (clobber (reg:CC FLAGS_REG))]
16060   ""
16061   "bsr{l}\t{%1, %0|%0, %1}"
16062   [(set_attr "type" "alu1")
16063    (set_attr "prefix_0f" "1")
16064    (set_attr "mode" "SI")])
16065
16066 (define_insn "popcount<mode>2"
16067   [(set (match_operand:SWI248 0 "register_operand" "=r")
16068         (popcount:SWI248
16069           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16070    (clobber (reg:CC FLAGS_REG))]
16071   "TARGET_POPCNT"
16072 {
16073 #if TARGET_MACHO
16074   return "popcnt\t{%1, %0|%0, %1}";
16075 #else
16076   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16077 #endif
16078 }
16079   [(set_attr "prefix_rep" "1")
16080    (set_attr "type" "bitmanip")
16081    (set_attr "mode" "<MODE>")])
16082
16083 (define_insn "*popcount<mode>2_cmp"
16084   [(set (reg FLAGS_REG)
16085         (compare
16086           (popcount:SWI248
16087             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16088           (const_int 0)))
16089    (set (match_operand:SWI248 0 "register_operand" "=r")
16090         (popcount:SWI248 (match_dup 1)))]
16091   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16092 {
16093 #if TARGET_MACHO
16094   return "popcnt\t{%1, %0|%0, %1}";
16095 #else
16096   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16097 #endif
16098 }
16099   [(set_attr "prefix_rep" "1")
16100    (set_attr "type" "bitmanip")
16101    (set_attr "mode" "<MODE>")])
16102
16103 (define_insn "*popcountsi2_cmp_zext"
16104   [(set (reg FLAGS_REG)
16105         (compare
16106           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16107           (const_int 0)))
16108    (set (match_operand:DI 0 "register_operand" "=r")
16109         (zero_extend:DI(popcount:SI (match_dup 1))))]
16110   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16111 {
16112 #if TARGET_MACHO
16113   return "popcnt\t{%1, %0|%0, %1}";
16114 #else
16115   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16116 #endif
16117 }
16118   [(set_attr "prefix_rep" "1")
16119    (set_attr "type" "bitmanip")
16120    (set_attr "mode" "SI")])
16121
16122 (define_expand "bswapsi2"
16123   [(set (match_operand:SI 0 "register_operand" "")
16124         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16125   ""
16126 {
16127   if (!(TARGET_BSWAP || TARGET_MOVBE))
16128     {
16129       rtx x = operands[0];
16130
16131       emit_move_insn (x, operands[1]);
16132       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16133       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16134       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16135       DONE;
16136     }
16137 })
16138
16139 (define_insn "*bswapsi_movbe"
16140   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16141         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16142   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16143   "@
16144     bswap\t%0
16145     movbe\t{%1, %0|%0, %1}
16146     movbe\t{%1, %0|%0, %1}"
16147   [(set_attr "type" "*,imov,imov")
16148    (set_attr "modrm" "*,1,1")
16149    (set_attr "prefix_0f" "1")
16150    (set_attr "prefix_extra" "*,1,1")
16151    (set_attr "length" "2,*,*")
16152    (set_attr "mode" "SI")])
16153
16154 (define_insn "*bswapsi_1"
16155   [(set (match_operand:SI 0 "register_operand" "=r")
16156         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16157   "TARGET_BSWAP"
16158   "bswap\t%0"
16159   [(set_attr "prefix_0f" "1")
16160    (set_attr "length" "2")])
16161
16162 (define_insn "*bswaphi_lowpart_1"
16163   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16164         (bswap:HI (match_dup 0)))
16165    (clobber (reg:CC FLAGS_REG))]
16166   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16167   "@
16168     xchg{b}\t{%h0, %b0|%b0, %h0}
16169     rol{w}\t{$8, %0|%0, 8}"
16170   [(set_attr "length" "2,4")
16171    (set_attr "mode" "QI,HI")])
16172
16173 (define_insn "bswaphi_lowpart"
16174   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16175         (bswap:HI (match_dup 0)))
16176    (clobber (reg:CC FLAGS_REG))]
16177   ""
16178   "rol{w}\t{$8, %0|%0, 8}"
16179   [(set_attr "length" "4")
16180    (set_attr "mode" "HI")])
16181
16182 (define_expand "bswapdi2"
16183   [(set (match_operand:DI 0 "register_operand" "")
16184         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16185   "TARGET_64BIT"
16186   "")
16187
16188 (define_insn "*bswapdi_movbe"
16189   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16190         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16191   "TARGET_64BIT && TARGET_MOVBE
16192    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16193   "@
16194     bswap\t%0
16195     movbe\t{%1, %0|%0, %1}
16196     movbe\t{%1, %0|%0, %1}"
16197   [(set_attr "type" "*,imov,imov")
16198    (set_attr "modrm" "*,1,1")
16199    (set_attr "prefix_0f" "1")
16200    (set_attr "prefix_extra" "*,1,1")
16201    (set_attr "length" "3,*,*")
16202    (set_attr "mode" "DI")])
16203
16204 (define_insn "*bswapdi_1"
16205   [(set (match_operand:DI 0 "register_operand" "=r")
16206         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16207   "TARGET_64BIT"
16208   "bswap\t%0"
16209   [(set_attr "prefix_0f" "1")
16210    (set_attr "length" "3")])
16211
16212 (define_expand "clzdi2"
16213   [(parallel
16214      [(set (match_operand:DI 0 "register_operand" "")
16215            (minus:DI (const_int 63)
16216                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16217       (clobber (reg:CC FLAGS_REG))])
16218    (parallel
16219      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16220       (clobber (reg:CC FLAGS_REG))])]
16221   "TARGET_64BIT"
16222 {
16223   if (TARGET_ABM)
16224     {
16225       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16226       DONE;
16227     }
16228 })
16229
16230 (define_insn "clzdi2_abm"
16231   [(set (match_operand:DI 0 "register_operand" "=r")
16232         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16233    (clobber (reg:CC FLAGS_REG))]
16234   "TARGET_64BIT && TARGET_ABM"
16235   "lzcnt{q}\t{%1, %0|%0, %1}"
16236   [(set_attr "prefix_rep" "1")
16237    (set_attr "type" "bitmanip")
16238    (set_attr "mode" "DI")])
16239
16240 (define_insn "bsr_rex64"
16241   [(set (match_operand:DI 0 "register_operand" "=r")
16242         (minus:DI (const_int 63)
16243                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16244    (clobber (reg:CC FLAGS_REG))]
16245   "TARGET_64BIT"
16246   "bsr{q}\t{%1, %0|%0, %1}"
16247   [(set_attr "type" "alu1")
16248    (set_attr "prefix_0f" "1")
16249    (set_attr "mode" "DI")])
16250
16251 (define_expand "clzhi2"
16252   [(parallel
16253      [(set (match_operand:HI 0 "register_operand" "")
16254            (minus:HI (const_int 15)
16255                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16256       (clobber (reg:CC FLAGS_REG))])
16257    (parallel
16258      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16259       (clobber (reg:CC FLAGS_REG))])]
16260   ""
16261 {
16262   if (TARGET_ABM)
16263     {
16264       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16265       DONE;
16266     }
16267 })
16268
16269 (define_insn "clzhi2_abm"
16270   [(set (match_operand:HI 0 "register_operand" "=r")
16271         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16272    (clobber (reg:CC FLAGS_REG))]
16273   "TARGET_ABM"
16274   "lzcnt{w}\t{%1, %0|%0, %1}"
16275   [(set_attr "prefix_rep" "1")
16276    (set_attr "type" "bitmanip")
16277    (set_attr "mode" "HI")])
16278
16279 (define_insn "*bsrhi"
16280   [(set (match_operand:HI 0 "register_operand" "=r")
16281         (minus:HI (const_int 15)
16282                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16283    (clobber (reg:CC FLAGS_REG))]
16284   ""
16285   "bsr{w}\t{%1, %0|%0, %1}"
16286   [(set_attr "type" "alu1")
16287    (set_attr "prefix_0f" "1")
16288    (set_attr "mode" "HI")])
16289
16290 (define_expand "paritydi2"
16291   [(set (match_operand:DI 0 "register_operand" "")
16292         (parity:DI (match_operand:DI 1 "register_operand" "")))]
16293   "! TARGET_POPCNT"
16294 {
16295   rtx scratch = gen_reg_rtx (QImode);
16296   rtx cond;
16297
16298   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16299                                 NULL_RTX, operands[1]));
16300
16301   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16302                          gen_rtx_REG (CCmode, FLAGS_REG),
16303                          const0_rtx);
16304   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16305
16306   if (TARGET_64BIT)
16307     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16308   else
16309     {
16310       rtx tmp = gen_reg_rtx (SImode);
16311
16312       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16313       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16314     }
16315   DONE;
16316 })
16317
16318 (define_insn_and_split "paritydi2_cmp"
16319   [(set (reg:CC FLAGS_REG)
16320         (parity:CC (match_operand:DI 3 "register_operand" "0")))
16321    (clobber (match_scratch:DI 0 "=r"))
16322    (clobber (match_scratch:SI 1 "=&r"))
16323    (clobber (match_scratch:HI 2 "=Q"))]
16324   "! TARGET_POPCNT"
16325   "#"
16326   "&& reload_completed"
16327   [(parallel
16328      [(set (match_dup 1)
16329            (xor:SI (match_dup 1) (match_dup 4)))
16330       (clobber (reg:CC FLAGS_REG))])
16331    (parallel
16332      [(set (reg:CC FLAGS_REG)
16333            (parity:CC (match_dup 1)))
16334       (clobber (match_dup 1))
16335       (clobber (match_dup 2))])]
16336 {
16337   operands[4] = gen_lowpart (SImode, operands[3]);
16338
16339   if (TARGET_64BIT)
16340     {
16341       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16342       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16343     }
16344   else
16345     operands[1] = gen_highpart (SImode, operands[3]);
16346 })
16347
16348 (define_expand "paritysi2"
16349   [(set (match_operand:SI 0 "register_operand" "")
16350         (parity:SI (match_operand:SI 1 "register_operand" "")))]
16351   "! TARGET_POPCNT"
16352 {
16353   rtx scratch = gen_reg_rtx (QImode);
16354   rtx cond;
16355
16356   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16357
16358   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16359                          gen_rtx_REG (CCmode, FLAGS_REG),
16360                          const0_rtx);
16361   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16362
16363   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16364   DONE;
16365 })
16366
16367 (define_insn_and_split "paritysi2_cmp"
16368   [(set (reg:CC FLAGS_REG)
16369         (parity:CC (match_operand:SI 2 "register_operand" "0")))
16370    (clobber (match_scratch:SI 0 "=r"))
16371    (clobber (match_scratch:HI 1 "=&Q"))]
16372   "! TARGET_POPCNT"
16373   "#"
16374   "&& reload_completed"
16375   [(parallel
16376      [(set (match_dup 1)
16377            (xor:HI (match_dup 1) (match_dup 3)))
16378       (clobber (reg:CC FLAGS_REG))])
16379    (parallel
16380      [(set (reg:CC FLAGS_REG)
16381            (parity:CC (match_dup 1)))
16382       (clobber (match_dup 1))])]
16383 {
16384   operands[3] = gen_lowpart (HImode, operands[2]);
16385
16386   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16387   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16388 })
16389
16390 (define_insn "*parityhi2_cmp"
16391   [(set (reg:CC FLAGS_REG)
16392         (parity:CC (match_operand:HI 1 "register_operand" "0")))
16393    (clobber (match_scratch:HI 0 "=Q"))]
16394   "! TARGET_POPCNT"
16395   "xor{b}\t{%h0, %b0|%b0, %h0}"
16396   [(set_attr "length" "2")
16397    (set_attr "mode" "HI")])
16398
16399 (define_insn "*parityqi2_cmp"
16400   [(set (reg:CC FLAGS_REG)
16401         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16402   "! TARGET_POPCNT"
16403   "test{b}\t%0, %0"
16404   [(set_attr "length" "2")
16405    (set_attr "mode" "QI")])
16406 \f
16407 ;; Thread-local storage patterns for ELF.
16408 ;;
16409 ;; Note that these code sequences must appear exactly as shown
16410 ;; in order to allow linker relaxation.
16411
16412 (define_insn "*tls_global_dynamic_32_gnu"
16413   [(set (match_operand:SI 0 "register_operand" "=a")
16414         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16415                     (match_operand:SI 2 "tls_symbolic_operand" "")
16416                     (match_operand:SI 3 "call_insn_operand" "")]
16417                     UNSPEC_TLS_GD))
16418    (clobber (match_scratch:SI 4 "=d"))
16419    (clobber (match_scratch:SI 5 "=c"))
16420    (clobber (reg:CC FLAGS_REG))]
16421   "!TARGET_64BIT && TARGET_GNU_TLS"
16422   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16423   [(set_attr "type" "multi")
16424    (set_attr "length" "12")])
16425
16426 (define_insn "*tls_global_dynamic_32_sun"
16427   [(set (match_operand:SI 0 "register_operand" "=a")
16428         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16429                     (match_operand:SI 2 "tls_symbolic_operand" "")
16430                     (match_operand:SI 3 "call_insn_operand" "")]
16431                     UNSPEC_TLS_GD))
16432    (clobber (match_scratch:SI 4 "=d"))
16433    (clobber (match_scratch:SI 5 "=c"))
16434    (clobber (reg:CC FLAGS_REG))]
16435   "!TARGET_64BIT && TARGET_SUN_TLS"
16436   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16437         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16438   [(set_attr "type" "multi")
16439    (set_attr "length" "14")])
16440
16441 (define_expand "tls_global_dynamic_32"
16442   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16443                    (unspec:SI
16444                     [(match_dup 2)
16445                      (match_operand:SI 1 "tls_symbolic_operand" "")
16446                      (match_dup 3)]
16447                     UNSPEC_TLS_GD))
16448               (clobber (match_scratch:SI 4 ""))
16449               (clobber (match_scratch:SI 5 ""))
16450               (clobber (reg:CC FLAGS_REG))])]
16451   ""
16452 {
16453   if (flag_pic)
16454     operands[2] = pic_offset_table_rtx;
16455   else
16456     {
16457       operands[2] = gen_reg_rtx (Pmode);
16458       emit_insn (gen_set_got (operands[2]));
16459     }
16460   if (TARGET_GNU2_TLS)
16461     {
16462        emit_insn (gen_tls_dynamic_gnu2_32
16463                   (operands[0], operands[1], operands[2]));
16464        DONE;
16465     }
16466   operands[3] = ix86_tls_get_addr ();
16467 })
16468
16469 (define_insn "*tls_global_dynamic_64"
16470   [(set (match_operand:DI 0 "register_operand" "=a")
16471         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16472                  (match_operand:DI 3 "" "")))
16473    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16474               UNSPEC_TLS_GD)]
16475   "TARGET_64BIT"
16476   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16477   [(set_attr "type" "multi")
16478    (set_attr "length" "16")])
16479
16480 (define_expand "tls_global_dynamic_64"
16481   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16482                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16483               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16484                          UNSPEC_TLS_GD)])]
16485   ""
16486 {
16487   if (TARGET_GNU2_TLS)
16488     {
16489        emit_insn (gen_tls_dynamic_gnu2_64
16490                   (operands[0], operands[1]));
16491        DONE;
16492     }
16493   operands[2] = ix86_tls_get_addr ();
16494 })
16495
16496 (define_insn "*tls_local_dynamic_base_32_gnu"
16497   [(set (match_operand:SI 0 "register_operand" "=a")
16498         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16499                     (match_operand:SI 2 "call_insn_operand" "")]
16500                    UNSPEC_TLS_LD_BASE))
16501    (clobber (match_scratch:SI 3 "=d"))
16502    (clobber (match_scratch:SI 4 "=c"))
16503    (clobber (reg:CC FLAGS_REG))]
16504   "!TARGET_64BIT && TARGET_GNU_TLS"
16505   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16506   [(set_attr "type" "multi")
16507    (set_attr "length" "11")])
16508
16509 (define_insn "*tls_local_dynamic_base_32_sun"
16510   [(set (match_operand:SI 0 "register_operand" "=a")
16511         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16512                     (match_operand:SI 2 "call_insn_operand" "")]
16513                    UNSPEC_TLS_LD_BASE))
16514    (clobber (match_scratch:SI 3 "=d"))
16515    (clobber (match_scratch:SI 4 "=c"))
16516    (clobber (reg:CC FLAGS_REG))]
16517   "!TARGET_64BIT && TARGET_SUN_TLS"
16518   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16519         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16520   [(set_attr "type" "multi")
16521    (set_attr "length" "13")])
16522
16523 (define_expand "tls_local_dynamic_base_32"
16524   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16525                    (unspec:SI [(match_dup 1) (match_dup 2)]
16526                               UNSPEC_TLS_LD_BASE))
16527               (clobber (match_scratch:SI 3 ""))
16528               (clobber (match_scratch:SI 4 ""))
16529               (clobber (reg:CC FLAGS_REG))])]
16530   ""
16531 {
16532   if (flag_pic)
16533     operands[1] = pic_offset_table_rtx;
16534   else
16535     {
16536       operands[1] = gen_reg_rtx (Pmode);
16537       emit_insn (gen_set_got (operands[1]));
16538     }
16539   if (TARGET_GNU2_TLS)
16540     {
16541        emit_insn (gen_tls_dynamic_gnu2_32
16542                   (operands[0], ix86_tls_module_base (), operands[1]));
16543        DONE;
16544     }
16545   operands[2] = ix86_tls_get_addr ();
16546 })
16547
16548 (define_insn "*tls_local_dynamic_base_64"
16549   [(set (match_operand:DI 0 "register_operand" "=a")
16550         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16551                  (match_operand:DI 2 "" "")))
16552    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16553   "TARGET_64BIT"
16554   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16555   [(set_attr "type" "multi")
16556    (set_attr "length" "12")])
16557
16558 (define_expand "tls_local_dynamic_base_64"
16559   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16560                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16561               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16562   ""
16563 {
16564   if (TARGET_GNU2_TLS)
16565     {
16566        emit_insn (gen_tls_dynamic_gnu2_64
16567                   (operands[0], ix86_tls_module_base ()));
16568        DONE;
16569     }
16570   operands[1] = ix86_tls_get_addr ();
16571 })
16572
16573 ;; Local dynamic of a single variable is a lose.  Show combine how
16574 ;; to convert that back to global dynamic.
16575
16576 (define_insn_and_split "*tls_local_dynamic_32_once"
16577   [(set (match_operand:SI 0 "register_operand" "=a")
16578         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16579                              (match_operand:SI 2 "call_insn_operand" "")]
16580                             UNSPEC_TLS_LD_BASE)
16581                  (const:SI (unspec:SI
16582                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16583                             UNSPEC_DTPOFF))))
16584    (clobber (match_scratch:SI 4 "=d"))
16585    (clobber (match_scratch:SI 5 "=c"))
16586    (clobber (reg:CC FLAGS_REG))]
16587   ""
16588   "#"
16589   ""
16590   [(parallel [(set (match_dup 0)
16591                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16592                               UNSPEC_TLS_GD))
16593               (clobber (match_dup 4))
16594               (clobber (match_dup 5))
16595               (clobber (reg:CC FLAGS_REG))])]
16596   "")
16597
16598 ;; Load and add the thread base pointer from %gs:0.
16599
16600 (define_insn "*load_tp_si"
16601   [(set (match_operand:SI 0 "register_operand" "=r")
16602         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16603   "!TARGET_64BIT"
16604   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16605   [(set_attr "type" "imov")
16606    (set_attr "modrm" "0")
16607    (set_attr "length" "7")
16608    (set_attr "memory" "load")
16609    (set_attr "imm_disp" "false")])
16610
16611 (define_insn "*add_tp_si"
16612   [(set (match_operand:SI 0 "register_operand" "=r")
16613         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16614                  (match_operand:SI 1 "register_operand" "0")))
16615    (clobber (reg:CC FLAGS_REG))]
16616   "!TARGET_64BIT"
16617   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16618   [(set_attr "type" "alu")
16619    (set_attr "modrm" "0")
16620    (set_attr "length" "7")
16621    (set_attr "memory" "load")
16622    (set_attr "imm_disp" "false")])
16623
16624 (define_insn "*load_tp_di"
16625   [(set (match_operand:DI 0 "register_operand" "=r")
16626         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16627   "TARGET_64BIT"
16628   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16629   [(set_attr "type" "imov")
16630    (set_attr "modrm" "0")
16631    (set_attr "length" "7")
16632    (set_attr "memory" "load")
16633    (set_attr "imm_disp" "false")])
16634
16635 (define_insn "*add_tp_di"
16636   [(set (match_operand:DI 0 "register_operand" "=r")
16637         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16638                  (match_operand:DI 1 "register_operand" "0")))
16639    (clobber (reg:CC FLAGS_REG))]
16640   "TARGET_64BIT"
16641   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16642   [(set_attr "type" "alu")
16643    (set_attr "modrm" "0")
16644    (set_attr "length" "7")
16645    (set_attr "memory" "load")
16646    (set_attr "imm_disp" "false")])
16647
16648 ;; GNU2 TLS patterns can be split.
16649
16650 (define_expand "tls_dynamic_gnu2_32"
16651   [(set (match_dup 3)
16652         (plus:SI (match_operand:SI 2 "register_operand" "")
16653                  (const:SI
16654                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16655                              UNSPEC_TLSDESC))))
16656    (parallel
16657     [(set (match_operand:SI 0 "register_operand" "")
16658           (unspec:SI [(match_dup 1) (match_dup 3)
16659                       (match_dup 2) (reg:SI SP_REG)]
16660                       UNSPEC_TLSDESC))
16661      (clobber (reg:CC FLAGS_REG))])]
16662   "!TARGET_64BIT && TARGET_GNU2_TLS"
16663 {
16664   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16665   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16666 })
16667
16668 (define_insn "*tls_dynamic_lea_32"
16669   [(set (match_operand:SI 0 "register_operand" "=r")
16670         (plus:SI (match_operand:SI 1 "register_operand" "b")
16671                  (const:SI
16672                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16673                               UNSPEC_TLSDESC))))]
16674   "!TARGET_64BIT && TARGET_GNU2_TLS"
16675   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16676   [(set_attr "type" "lea")
16677    (set_attr "mode" "SI")
16678    (set_attr "length" "6")
16679    (set_attr "length_address" "4")])
16680
16681 (define_insn "*tls_dynamic_call_32"
16682   [(set (match_operand:SI 0 "register_operand" "=a")
16683         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16684                     (match_operand:SI 2 "register_operand" "0")
16685                     ;; we have to make sure %ebx still points to the GOT
16686                     (match_operand:SI 3 "register_operand" "b")
16687                     (reg:SI SP_REG)]
16688                    UNSPEC_TLSDESC))
16689    (clobber (reg:CC FLAGS_REG))]
16690   "!TARGET_64BIT && TARGET_GNU2_TLS"
16691   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16692   [(set_attr "type" "call")
16693    (set_attr "length" "2")
16694    (set_attr "length_address" "0")])
16695
16696 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16697   [(set (match_operand:SI 0 "register_operand" "=&a")
16698         (plus:SI
16699          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16700                      (match_operand:SI 4 "" "")
16701                      (match_operand:SI 2 "register_operand" "b")
16702                      (reg:SI SP_REG)]
16703                     UNSPEC_TLSDESC)
16704          (const:SI (unspec:SI
16705                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16706                     UNSPEC_DTPOFF))))
16707    (clobber (reg:CC FLAGS_REG))]
16708   "!TARGET_64BIT && TARGET_GNU2_TLS"
16709   "#"
16710   ""
16711   [(set (match_dup 0) (match_dup 5))]
16712 {
16713   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16714   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16715 })
16716
16717 (define_expand "tls_dynamic_gnu2_64"
16718   [(set (match_dup 2)
16719         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16720                    UNSPEC_TLSDESC))
16721    (parallel
16722     [(set (match_operand:DI 0 "register_operand" "")
16723           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16724                      UNSPEC_TLSDESC))
16725      (clobber (reg:CC FLAGS_REG))])]
16726   "TARGET_64BIT && TARGET_GNU2_TLS"
16727 {
16728   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16729   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16730 })
16731
16732 (define_insn "*tls_dynamic_lea_64"
16733   [(set (match_operand:DI 0 "register_operand" "=r")
16734         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16735                    UNSPEC_TLSDESC))]
16736   "TARGET_64BIT && TARGET_GNU2_TLS"
16737   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16738   [(set_attr "type" "lea")
16739    (set_attr "mode" "DI")
16740    (set_attr "length" "7")
16741    (set_attr "length_address" "4")])
16742
16743 (define_insn "*tls_dynamic_call_64"
16744   [(set (match_operand:DI 0 "register_operand" "=a")
16745         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16746                     (match_operand:DI 2 "register_operand" "0")
16747                     (reg:DI SP_REG)]
16748                    UNSPEC_TLSDESC))
16749    (clobber (reg:CC FLAGS_REG))]
16750   "TARGET_64BIT && TARGET_GNU2_TLS"
16751   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16752   [(set_attr "type" "call")
16753    (set_attr "length" "2")
16754    (set_attr "length_address" "0")])
16755
16756 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16757   [(set (match_operand:DI 0 "register_operand" "=&a")
16758         (plus:DI
16759          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16760                      (match_operand:DI 3 "" "")
16761                      (reg:DI SP_REG)]
16762                     UNSPEC_TLSDESC)
16763          (const:DI (unspec:DI
16764                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16765                     UNSPEC_DTPOFF))))
16766    (clobber (reg:CC FLAGS_REG))]
16767   "TARGET_64BIT && TARGET_GNU2_TLS"
16768   "#"
16769   ""
16770   [(set (match_dup 0) (match_dup 4))]
16771 {
16772   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16773   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16774 })
16775
16776 ;;
16777 \f
16778 ;; These patterns match the binary 387 instructions for addM3, subM3,
16779 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16780 ;; SFmode.  The first is the normal insn, the second the same insn but
16781 ;; with one operand a conversion, and the third the same insn but with
16782 ;; the other operand a conversion.  The conversion may be SFmode or
16783 ;; SImode if the target mode DFmode, but only SImode if the target mode
16784 ;; is SFmode.
16785
16786 ;; Gcc is slightly more smart about handling normal two address instructions
16787 ;; so use special patterns for add and mull.
16788
16789 (define_insn "*fop_<mode>_comm_mixed_avx"
16790   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16791         (match_operator:MODEF 3 "binary_fp_operator"
16792           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16793            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16794   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16795    && COMMUTATIVE_ARITH_P (operands[3])
16796    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16797   "* return output_387_binary_op (insn, operands);"
16798   [(set (attr "type")
16799         (if_then_else (eq_attr "alternative" "1")
16800            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16801               (const_string "ssemul")
16802               (const_string "sseadd"))
16803            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16804               (const_string "fmul")
16805               (const_string "fop"))))
16806    (set_attr "prefix" "orig,maybe_vex")
16807    (set_attr "mode" "<MODE>")])
16808
16809 (define_insn "*fop_<mode>_comm_mixed"
16810   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16811         (match_operator:MODEF 3 "binary_fp_operator"
16812           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16813            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16814   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16815    && COMMUTATIVE_ARITH_P (operands[3])
16816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16817   "* return output_387_binary_op (insn, operands);"
16818   [(set (attr "type")
16819         (if_then_else (eq_attr "alternative" "1")
16820            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16821               (const_string "ssemul")
16822               (const_string "sseadd"))
16823            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16824               (const_string "fmul")
16825               (const_string "fop"))))
16826    (set_attr "mode" "<MODE>")])
16827
16828 (define_insn "*fop_<mode>_comm_avx"
16829   [(set (match_operand:MODEF 0 "register_operand" "=x")
16830         (match_operator:MODEF 3 "binary_fp_operator"
16831           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16832            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16833   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834    && COMMUTATIVE_ARITH_P (operands[3])
16835    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16836   "* return output_387_binary_op (insn, operands);"
16837   [(set (attr "type")
16838         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16839            (const_string "ssemul")
16840            (const_string "sseadd")))
16841    (set_attr "prefix" "vex")
16842    (set_attr "mode" "<MODE>")])
16843
16844 (define_insn "*fop_<mode>_comm_sse"
16845   [(set (match_operand:MODEF 0 "register_operand" "=x")
16846         (match_operator:MODEF 3 "binary_fp_operator"
16847           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16848            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16849   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16850    && COMMUTATIVE_ARITH_P (operands[3])
16851    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16852   "* return output_387_binary_op (insn, operands);"
16853   [(set (attr "type")
16854         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16855            (const_string "ssemul")
16856            (const_string "sseadd")))
16857    (set_attr "mode" "<MODE>")])
16858
16859 (define_insn "*fop_<mode>_comm_i387"
16860   [(set (match_operand:MODEF 0 "register_operand" "=f")
16861         (match_operator:MODEF 3 "binary_fp_operator"
16862           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16863            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16864   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16865    && COMMUTATIVE_ARITH_P (operands[3])
16866    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16867   "* return output_387_binary_op (insn, operands);"
16868   [(set (attr "type")
16869         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16870            (const_string "fmul")
16871            (const_string "fop")))
16872    (set_attr "mode" "<MODE>")])
16873
16874 (define_insn "*fop_<mode>_1_mixed_avx"
16875   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16876         (match_operator:MODEF 3 "binary_fp_operator"
16877           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16878            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16879   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16880    && !COMMUTATIVE_ARITH_P (operands[3])
16881    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16882   "* return output_387_binary_op (insn, operands);"
16883   [(set (attr "type")
16884         (cond [(and (eq_attr "alternative" "2")
16885                     (match_operand:MODEF 3 "mult_operator" ""))
16886                  (const_string "ssemul")
16887                (and (eq_attr "alternative" "2")
16888                     (match_operand:MODEF 3 "div_operator" ""))
16889                  (const_string "ssediv")
16890                (eq_attr "alternative" "2")
16891                  (const_string "sseadd")
16892                (match_operand:MODEF 3 "mult_operator" "")
16893                  (const_string "fmul")
16894                (match_operand:MODEF 3 "div_operator" "")
16895                  (const_string "fdiv")
16896               ]
16897               (const_string "fop")))
16898    (set_attr "prefix" "orig,orig,maybe_vex")
16899    (set_attr "mode" "<MODE>")])
16900
16901 (define_insn "*fop_<mode>_1_mixed"
16902   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16903         (match_operator:MODEF 3 "binary_fp_operator"
16904           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16905            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16906   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16907    && !COMMUTATIVE_ARITH_P (operands[3])
16908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16909   "* return output_387_binary_op (insn, operands);"
16910   [(set (attr "type")
16911         (cond [(and (eq_attr "alternative" "2")
16912                     (match_operand:MODEF 3 "mult_operator" ""))
16913                  (const_string "ssemul")
16914                (and (eq_attr "alternative" "2")
16915                     (match_operand:MODEF 3 "div_operator" ""))
16916                  (const_string "ssediv")
16917                (eq_attr "alternative" "2")
16918                  (const_string "sseadd")
16919                (match_operand:MODEF 3 "mult_operator" "")
16920                  (const_string "fmul")
16921                (match_operand:MODEF 3 "div_operator" "")
16922                  (const_string "fdiv")
16923               ]
16924               (const_string "fop")))
16925    (set_attr "mode" "<MODE>")])
16926
16927 (define_insn "*rcpsf2_sse"
16928   [(set (match_operand:SF 0 "register_operand" "=x")
16929         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16930                    UNSPEC_RCP))]
16931   "TARGET_SSE_MATH"
16932   "%vrcpss\t{%1, %d0|%d0, %1}"
16933   [(set_attr "type" "sse")
16934    (set_attr "atom_sse_attr" "rcp")
16935    (set_attr "prefix" "maybe_vex")
16936    (set_attr "mode" "SF")])
16937
16938 (define_insn "*fop_<mode>_1_avx"
16939   [(set (match_operand:MODEF 0 "register_operand" "=x")
16940         (match_operator:MODEF 3 "binary_fp_operator"
16941           [(match_operand:MODEF 1 "register_operand" "x")
16942            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16943   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16944    && !COMMUTATIVE_ARITH_P (operands[3])"
16945   "* return output_387_binary_op (insn, operands);"
16946   [(set (attr "type")
16947         (cond [(match_operand:MODEF 3 "mult_operator" "")
16948                  (const_string "ssemul")
16949                (match_operand:MODEF 3 "div_operator" "")
16950                  (const_string "ssediv")
16951               ]
16952               (const_string "sseadd")))
16953    (set_attr "prefix" "vex")
16954    (set_attr "mode" "<MODE>")])
16955
16956 (define_insn "*fop_<mode>_1_sse"
16957   [(set (match_operand:MODEF 0 "register_operand" "=x")
16958         (match_operator:MODEF 3 "binary_fp_operator"
16959           [(match_operand:MODEF 1 "register_operand" "0")
16960            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16961   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16962    && !COMMUTATIVE_ARITH_P (operands[3])"
16963   "* return output_387_binary_op (insn, operands);"
16964   [(set (attr "type")
16965         (cond [(match_operand:MODEF 3 "mult_operator" "")
16966                  (const_string "ssemul")
16967                (match_operand:MODEF 3 "div_operator" "")
16968                  (const_string "ssediv")
16969               ]
16970               (const_string "sseadd")))
16971    (set_attr "mode" "<MODE>")])
16972
16973 ;; This pattern is not fully shadowed by the pattern above.
16974 (define_insn "*fop_<mode>_1_i387"
16975   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16976         (match_operator:MODEF 3 "binary_fp_operator"
16977           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16978            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16979   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16980    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16981    && !COMMUTATIVE_ARITH_P (operands[3])
16982    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16983   "* return output_387_binary_op (insn, operands);"
16984   [(set (attr "type")
16985         (cond [(match_operand:MODEF 3 "mult_operator" "")
16986                  (const_string "fmul")
16987                (match_operand:MODEF 3 "div_operator" "")
16988                  (const_string "fdiv")
16989               ]
16990               (const_string "fop")))
16991    (set_attr "mode" "<MODE>")])
16992
16993 ;; ??? Add SSE splitters for these!
16994 (define_insn "*fop_<MODEF:mode>_2_i387"
16995   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16996         (match_operator:MODEF 3 "binary_fp_operator"
16997           [(float:MODEF
16998              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16999            (match_operand:MODEF 2 "register_operand" "0,0")]))]
17000   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17001    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17002    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17003   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17004   [(set (attr "type")
17005         (cond [(match_operand:MODEF 3 "mult_operator" "")
17006                  (const_string "fmul")
17007                (match_operand:MODEF 3 "div_operator" "")
17008                  (const_string "fdiv")
17009               ]
17010               (const_string "fop")))
17011    (set_attr "fp_int_src" "true")
17012    (set_attr "mode" "<X87MODEI12:MODE>")])
17013
17014 (define_insn "*fop_<MODEF:mode>_3_i387"
17015   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17016         (match_operator:MODEF 3 "binary_fp_operator"
17017           [(match_operand:MODEF 1 "register_operand" "0,0")
17018            (float:MODEF
17019              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17020   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17021    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17022    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17023   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17024   [(set (attr "type")
17025         (cond [(match_operand:MODEF 3 "mult_operator" "")
17026                  (const_string "fmul")
17027                (match_operand:MODEF 3 "div_operator" "")
17028                  (const_string "fdiv")
17029               ]
17030               (const_string "fop")))
17031    (set_attr "fp_int_src" "true")
17032    (set_attr "mode" "<MODE>")])
17033
17034 (define_insn "*fop_df_4_i387"
17035   [(set (match_operand:DF 0 "register_operand" "=f,f")
17036         (match_operator:DF 3 "binary_fp_operator"
17037            [(float_extend:DF
17038              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17039             (match_operand:DF 2 "register_operand" "0,f")]))]
17040   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17041    && !(TARGET_SSE2 && TARGET_SSE_MATH)
17042    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17043   "* return output_387_binary_op (insn, operands);"
17044   [(set (attr "type")
17045         (cond [(match_operand:DF 3 "mult_operator" "")
17046                  (const_string "fmul")
17047                (match_operand:DF 3 "div_operator" "")
17048                  (const_string "fdiv")
17049               ]
17050               (const_string "fop")))
17051    (set_attr "mode" "SF")])
17052
17053 (define_insn "*fop_df_5_i387"
17054   [(set (match_operand:DF 0 "register_operand" "=f,f")
17055         (match_operator:DF 3 "binary_fp_operator"
17056           [(match_operand:DF 1 "register_operand" "0,f")
17057            (float_extend:DF
17058             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17059   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17060    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17061   "* return output_387_binary_op (insn, operands);"
17062   [(set (attr "type")
17063         (cond [(match_operand:DF 3 "mult_operator" "")
17064                  (const_string "fmul")
17065                (match_operand:DF 3 "div_operator" "")
17066                  (const_string "fdiv")
17067               ]
17068               (const_string "fop")))
17069    (set_attr "mode" "SF")])
17070
17071 (define_insn "*fop_df_6_i387"
17072   [(set (match_operand:DF 0 "register_operand" "=f,f")
17073         (match_operator:DF 3 "binary_fp_operator"
17074           [(float_extend:DF
17075             (match_operand:SF 1 "register_operand" "0,f"))
17076            (float_extend:DF
17077             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17078   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17079    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17080   "* return output_387_binary_op (insn, operands);"
17081   [(set (attr "type")
17082         (cond [(match_operand:DF 3 "mult_operator" "")
17083                  (const_string "fmul")
17084                (match_operand:DF 3 "div_operator" "")
17085                  (const_string "fdiv")
17086               ]
17087               (const_string "fop")))
17088    (set_attr "mode" "SF")])
17089
17090 (define_insn "*fop_xf_comm_i387"
17091   [(set (match_operand:XF 0 "register_operand" "=f")
17092         (match_operator:XF 3 "binary_fp_operator"
17093                         [(match_operand:XF 1 "register_operand" "%0")
17094                          (match_operand:XF 2 "register_operand" "f")]))]
17095   "TARGET_80387
17096    && COMMUTATIVE_ARITH_P (operands[3])"
17097   "* return output_387_binary_op (insn, operands);"
17098   [(set (attr "type")
17099         (if_then_else (match_operand:XF 3 "mult_operator" "")
17100            (const_string "fmul")
17101            (const_string "fop")))
17102    (set_attr "mode" "XF")])
17103
17104 (define_insn "*fop_xf_1_i387"
17105   [(set (match_operand:XF 0 "register_operand" "=f,f")
17106         (match_operator:XF 3 "binary_fp_operator"
17107                         [(match_operand:XF 1 "register_operand" "0,f")
17108                          (match_operand:XF 2 "register_operand" "f,0")]))]
17109   "TARGET_80387
17110    && !COMMUTATIVE_ARITH_P (operands[3])"
17111   "* return output_387_binary_op (insn, operands);"
17112   [(set (attr "type")
17113         (cond [(match_operand:XF 3 "mult_operator" "")
17114                  (const_string "fmul")
17115                (match_operand:XF 3 "div_operator" "")
17116                  (const_string "fdiv")
17117               ]
17118               (const_string "fop")))
17119    (set_attr "mode" "XF")])
17120
17121 (define_insn "*fop_xf_2_i387"
17122   [(set (match_operand:XF 0 "register_operand" "=f,f")
17123         (match_operator:XF 3 "binary_fp_operator"
17124           [(float:XF
17125              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17126            (match_operand:XF 2 "register_operand" "0,0")]))]
17127   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17128   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17129   [(set (attr "type")
17130         (cond [(match_operand:XF 3 "mult_operator" "")
17131                  (const_string "fmul")
17132                (match_operand:XF 3 "div_operator" "")
17133                  (const_string "fdiv")
17134               ]
17135               (const_string "fop")))
17136    (set_attr "fp_int_src" "true")
17137    (set_attr "mode" "<MODE>")])
17138
17139 (define_insn "*fop_xf_3_i387"
17140   [(set (match_operand:XF 0 "register_operand" "=f,f")
17141         (match_operator:XF 3 "binary_fp_operator"
17142           [(match_operand:XF 1 "register_operand" "0,0")
17143            (float:XF
17144              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17145   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17146   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17147   [(set (attr "type")
17148         (cond [(match_operand:XF 3 "mult_operator" "")
17149                  (const_string "fmul")
17150                (match_operand:XF 3 "div_operator" "")
17151                  (const_string "fdiv")
17152               ]
17153               (const_string "fop")))
17154    (set_attr "fp_int_src" "true")
17155    (set_attr "mode" "<MODE>")])
17156
17157 (define_insn "*fop_xf_4_i387"
17158   [(set (match_operand:XF 0 "register_operand" "=f,f")
17159         (match_operator:XF 3 "binary_fp_operator"
17160            [(float_extend:XF
17161               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17162             (match_operand:XF 2 "register_operand" "0,f")]))]
17163   "TARGET_80387"
17164   "* return output_387_binary_op (insn, operands);"
17165   [(set (attr "type")
17166         (cond [(match_operand:XF 3 "mult_operator" "")
17167                  (const_string "fmul")
17168                (match_operand:XF 3 "div_operator" "")
17169                  (const_string "fdiv")
17170               ]
17171               (const_string "fop")))
17172    (set_attr "mode" "<MODE>")])
17173
17174 (define_insn "*fop_xf_5_i387"
17175   [(set (match_operand:XF 0 "register_operand" "=f,f")
17176         (match_operator:XF 3 "binary_fp_operator"
17177           [(match_operand:XF 1 "register_operand" "0,f")
17178            (float_extend:XF
17179              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17180   "TARGET_80387"
17181   "* return output_387_binary_op (insn, operands);"
17182   [(set (attr "type")
17183         (cond [(match_operand:XF 3 "mult_operator" "")
17184                  (const_string "fmul")
17185                (match_operand:XF 3 "div_operator" "")
17186                  (const_string "fdiv")
17187               ]
17188               (const_string "fop")))
17189    (set_attr "mode" "<MODE>")])
17190
17191 (define_insn "*fop_xf_6_i387"
17192   [(set (match_operand:XF 0 "register_operand" "=f,f")
17193         (match_operator:XF 3 "binary_fp_operator"
17194           [(float_extend:XF
17195              (match_operand:MODEF 1 "register_operand" "0,f"))
17196            (float_extend:XF
17197              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17198   "TARGET_80387"
17199   "* return output_387_binary_op (insn, operands);"
17200   [(set (attr "type")
17201         (cond [(match_operand:XF 3 "mult_operator" "")
17202                  (const_string "fmul")
17203                (match_operand:XF 3 "div_operator" "")
17204                  (const_string "fdiv")
17205               ]
17206               (const_string "fop")))
17207    (set_attr "mode" "<MODE>")])
17208
17209 (define_split
17210   [(set (match_operand 0 "register_operand" "")
17211         (match_operator 3 "binary_fp_operator"
17212            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17213             (match_operand 2 "register_operand" "")]))]
17214   "reload_completed
17215    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17216    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17217   [(const_int 0)]
17218 {
17219   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17220   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17221   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17222                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17223                                           GET_MODE (operands[3]),
17224                                           operands[4],
17225                                           operands[2])));
17226   ix86_free_from_memory (GET_MODE (operands[1]));
17227   DONE;
17228 })
17229
17230 (define_split
17231   [(set (match_operand 0 "register_operand" "")
17232         (match_operator 3 "binary_fp_operator"
17233            [(match_operand 1 "register_operand" "")
17234             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17235   "reload_completed
17236    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17237    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17238   [(const_int 0)]
17239 {
17240   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17241   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17242   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17243                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17244                                           GET_MODE (operands[3]),
17245                                           operands[1],
17246                                           operands[4])));
17247   ix86_free_from_memory (GET_MODE (operands[2]));
17248   DONE;
17249 })
17250 \f
17251 ;; FPU special functions.
17252
17253 ;; This pattern implements a no-op XFmode truncation for
17254 ;; all fancy i386 XFmode math functions.
17255
17256 (define_insn "truncxf<mode>2_i387_noop_unspec"
17257   [(set (match_operand:MODEF 0 "register_operand" "=f")
17258         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17259         UNSPEC_TRUNC_NOOP))]
17260   "TARGET_USE_FANCY_MATH_387"
17261   "* return output_387_reg_move (insn, operands);"
17262   [(set_attr "type" "fmov")
17263    (set_attr "mode" "<MODE>")])
17264
17265 (define_insn "sqrtxf2"
17266   [(set (match_operand:XF 0 "register_operand" "=f")
17267         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17268   "TARGET_USE_FANCY_MATH_387"
17269   "fsqrt"
17270   [(set_attr "type" "fpspc")
17271    (set_attr "mode" "XF")
17272    (set_attr "athlon_decode" "direct")
17273    (set_attr "amdfam10_decode" "direct")])
17274
17275 (define_insn "sqrt_extend<mode>xf2_i387"
17276   [(set (match_operand:XF 0 "register_operand" "=f")
17277         (sqrt:XF
17278           (float_extend:XF
17279             (match_operand:MODEF 1 "register_operand" "0"))))]
17280   "TARGET_USE_FANCY_MATH_387"
17281   "fsqrt"
17282   [(set_attr "type" "fpspc")
17283    (set_attr "mode" "XF")
17284    (set_attr "athlon_decode" "direct")
17285    (set_attr "amdfam10_decode" "direct")])
17286
17287 (define_insn "*rsqrtsf2_sse"
17288   [(set (match_operand:SF 0 "register_operand" "=x")
17289         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17290                    UNSPEC_RSQRT))]
17291   "TARGET_SSE_MATH"
17292   "%vrsqrtss\t{%1, %d0|%d0, %1}"
17293   [(set_attr "type" "sse")
17294    (set_attr "atom_sse_attr" "rcp")
17295    (set_attr "prefix" "maybe_vex")
17296    (set_attr "mode" "SF")])
17297
17298 (define_expand "rsqrtsf2"
17299   [(set (match_operand:SF 0 "register_operand" "")
17300         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17301                    UNSPEC_RSQRT))]
17302   "TARGET_SSE_MATH"
17303 {
17304   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17305   DONE;
17306 })
17307
17308 (define_insn "*sqrt<mode>2_sse"
17309   [(set (match_operand:MODEF 0 "register_operand" "=x")
17310         (sqrt:MODEF
17311           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17312   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17313   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17314   [(set_attr "type" "sse")
17315    (set_attr "atom_sse_attr" "sqrt")
17316    (set_attr "prefix" "maybe_vex")
17317    (set_attr "mode" "<MODE>")
17318    (set_attr "athlon_decode" "*")
17319    (set_attr "amdfam10_decode" "*")])
17320
17321 (define_expand "sqrt<mode>2"
17322   [(set (match_operand:MODEF 0 "register_operand" "")
17323         (sqrt:MODEF
17324           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17325   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17326    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17327 {
17328   if (<MODE>mode == SFmode
17329       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17330       && flag_finite_math_only && !flag_trapping_math
17331       && flag_unsafe_math_optimizations)
17332     {
17333       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17334       DONE;
17335     }
17336
17337   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17338     {
17339       rtx op0 = gen_reg_rtx (XFmode);
17340       rtx op1 = force_reg (<MODE>mode, operands[1]);
17341
17342       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17343       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17344       DONE;
17345    }
17346 })
17347
17348 (define_insn "fpremxf4_i387"
17349   [(set (match_operand:XF 0 "register_operand" "=f")
17350         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17351                     (match_operand:XF 3 "register_operand" "1")]
17352                    UNSPEC_FPREM_F))
17353    (set (match_operand:XF 1 "register_operand" "=u")
17354         (unspec:XF [(match_dup 2) (match_dup 3)]
17355                    UNSPEC_FPREM_U))
17356    (set (reg:CCFP FPSR_REG)
17357         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17358                      UNSPEC_C2_FLAG))]
17359   "TARGET_USE_FANCY_MATH_387"
17360   "fprem"
17361   [(set_attr "type" "fpspc")
17362    (set_attr "mode" "XF")])
17363
17364 (define_expand "fmodxf3"
17365   [(use (match_operand:XF 0 "register_operand" ""))
17366    (use (match_operand:XF 1 "general_operand" ""))
17367    (use (match_operand:XF 2 "general_operand" ""))]
17368   "TARGET_USE_FANCY_MATH_387"
17369 {
17370   rtx label = gen_label_rtx ();
17371
17372   rtx op1 = gen_reg_rtx (XFmode);
17373   rtx op2 = gen_reg_rtx (XFmode);
17374
17375   emit_move_insn (op2, operands[2]);
17376   emit_move_insn (op1, operands[1]);
17377
17378   emit_label (label);
17379   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17380   ix86_emit_fp_unordered_jump (label);
17381   LABEL_NUSES (label) = 1;
17382
17383   emit_move_insn (operands[0], op1);
17384   DONE;
17385 })
17386
17387 (define_expand "fmod<mode>3"
17388   [(use (match_operand:MODEF 0 "register_operand" ""))
17389    (use (match_operand:MODEF 1 "general_operand" ""))
17390    (use (match_operand:MODEF 2 "general_operand" ""))]
17391   "TARGET_USE_FANCY_MATH_387"
17392 {
17393   rtx label = gen_label_rtx ();
17394
17395   rtx op1 = gen_reg_rtx (XFmode);
17396   rtx op2 = gen_reg_rtx (XFmode);
17397
17398   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17399   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17400
17401   emit_label (label);
17402   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17403   ix86_emit_fp_unordered_jump (label);
17404   LABEL_NUSES (label) = 1;
17405
17406   /* Truncate the result properly for strict SSE math.  */
17407   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17408       && !TARGET_MIX_SSE_I387)
17409     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17410   else
17411     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17412
17413   DONE;
17414 })
17415
17416 (define_insn "fprem1xf4_i387"
17417   [(set (match_operand:XF 0 "register_operand" "=f")
17418         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17419                     (match_operand:XF 3 "register_operand" "1")]
17420                    UNSPEC_FPREM1_F))
17421    (set (match_operand:XF 1 "register_operand" "=u")
17422         (unspec:XF [(match_dup 2) (match_dup 3)]
17423                    UNSPEC_FPREM1_U))
17424    (set (reg:CCFP FPSR_REG)
17425         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17426                      UNSPEC_C2_FLAG))]
17427   "TARGET_USE_FANCY_MATH_387"
17428   "fprem1"
17429   [(set_attr "type" "fpspc")
17430    (set_attr "mode" "XF")])
17431
17432 (define_expand "remainderxf3"
17433   [(use (match_operand:XF 0 "register_operand" ""))
17434    (use (match_operand:XF 1 "general_operand" ""))
17435    (use (match_operand:XF 2 "general_operand" ""))]
17436   "TARGET_USE_FANCY_MATH_387"
17437 {
17438   rtx label = gen_label_rtx ();
17439
17440   rtx op1 = gen_reg_rtx (XFmode);
17441   rtx op2 = gen_reg_rtx (XFmode);
17442
17443   emit_move_insn (op2, operands[2]);
17444   emit_move_insn (op1, operands[1]);
17445
17446   emit_label (label);
17447   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17448   ix86_emit_fp_unordered_jump (label);
17449   LABEL_NUSES (label) = 1;
17450
17451   emit_move_insn (operands[0], op1);
17452   DONE;
17453 })
17454
17455 (define_expand "remainder<mode>3"
17456   [(use (match_operand:MODEF 0 "register_operand" ""))
17457    (use (match_operand:MODEF 1 "general_operand" ""))
17458    (use (match_operand:MODEF 2 "general_operand" ""))]
17459   "TARGET_USE_FANCY_MATH_387"
17460 {
17461   rtx label = gen_label_rtx ();
17462
17463   rtx op1 = gen_reg_rtx (XFmode);
17464   rtx op2 = gen_reg_rtx (XFmode);
17465
17466   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17467   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17468
17469   emit_label (label);
17470
17471   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17472   ix86_emit_fp_unordered_jump (label);
17473   LABEL_NUSES (label) = 1;
17474
17475   /* Truncate the result properly for strict SSE math.  */
17476   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17477       && !TARGET_MIX_SSE_I387)
17478     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17479   else
17480     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17481
17482   DONE;
17483 })
17484
17485 (define_insn "*sinxf2_i387"
17486   [(set (match_operand:XF 0 "register_operand" "=f")
17487         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17488   "TARGET_USE_FANCY_MATH_387
17489    && flag_unsafe_math_optimizations"
17490   "fsin"
17491   [(set_attr "type" "fpspc")
17492    (set_attr "mode" "XF")])
17493
17494 (define_insn "*sin_extend<mode>xf2_i387"
17495   [(set (match_operand:XF 0 "register_operand" "=f")
17496         (unspec:XF [(float_extend:XF
17497                       (match_operand:MODEF 1 "register_operand" "0"))]
17498                    UNSPEC_SIN))]
17499   "TARGET_USE_FANCY_MATH_387
17500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501        || TARGET_MIX_SSE_I387)
17502    && flag_unsafe_math_optimizations"
17503   "fsin"
17504   [(set_attr "type" "fpspc")
17505    (set_attr "mode" "XF")])
17506
17507 (define_insn "*cosxf2_i387"
17508   [(set (match_operand:XF 0 "register_operand" "=f")
17509         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17510   "TARGET_USE_FANCY_MATH_387
17511    && flag_unsafe_math_optimizations"
17512   "fcos"
17513   [(set_attr "type" "fpspc")
17514    (set_attr "mode" "XF")])
17515
17516 (define_insn "*cos_extend<mode>xf2_i387"
17517   [(set (match_operand:XF 0 "register_operand" "=f")
17518         (unspec:XF [(float_extend:XF
17519                       (match_operand:MODEF 1 "register_operand" "0"))]
17520                    UNSPEC_COS))]
17521   "TARGET_USE_FANCY_MATH_387
17522    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523        || TARGET_MIX_SSE_I387)
17524    && flag_unsafe_math_optimizations"
17525   "fcos"
17526   [(set_attr "type" "fpspc")
17527    (set_attr "mode" "XF")])
17528
17529 ;; When sincos pattern is defined, sin and cos builtin functions will be
17530 ;; expanded to sincos pattern with one of its outputs left unused.
17531 ;; CSE pass will figure out if two sincos patterns can be combined,
17532 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17533 ;; depending on the unused output.
17534
17535 (define_insn "sincosxf3"
17536   [(set (match_operand:XF 0 "register_operand" "=f")
17537         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17538                    UNSPEC_SINCOS_COS))
17539    (set (match_operand:XF 1 "register_operand" "=u")
17540         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17541   "TARGET_USE_FANCY_MATH_387
17542    && flag_unsafe_math_optimizations"
17543   "fsincos"
17544   [(set_attr "type" "fpspc")
17545    (set_attr "mode" "XF")])
17546
17547 (define_split
17548   [(set (match_operand:XF 0 "register_operand" "")
17549         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17550                    UNSPEC_SINCOS_COS))
17551    (set (match_operand:XF 1 "register_operand" "")
17552         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17553   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17554    && !(reload_completed || reload_in_progress)"
17555   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17556   "")
17557
17558 (define_split
17559   [(set (match_operand:XF 0 "register_operand" "")
17560         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17561                    UNSPEC_SINCOS_COS))
17562    (set (match_operand:XF 1 "register_operand" "")
17563         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17564   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17565    && !(reload_completed || reload_in_progress)"
17566   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17567   "")
17568
17569 (define_insn "sincos_extend<mode>xf3_i387"
17570   [(set (match_operand:XF 0 "register_operand" "=f")
17571         (unspec:XF [(float_extend:XF
17572                       (match_operand:MODEF 2 "register_operand" "0"))]
17573                    UNSPEC_SINCOS_COS))
17574    (set (match_operand:XF 1 "register_operand" "=u")
17575         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17576   "TARGET_USE_FANCY_MATH_387
17577    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17578        || TARGET_MIX_SSE_I387)
17579    && flag_unsafe_math_optimizations"
17580   "fsincos"
17581   [(set_attr "type" "fpspc")
17582    (set_attr "mode" "XF")])
17583
17584 (define_split
17585   [(set (match_operand:XF 0 "register_operand" "")
17586         (unspec:XF [(float_extend:XF
17587                       (match_operand:MODEF 2 "register_operand" ""))]
17588                    UNSPEC_SINCOS_COS))
17589    (set (match_operand:XF 1 "register_operand" "")
17590         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17591   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17592    && !(reload_completed || reload_in_progress)"
17593   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17594   "")
17595
17596 (define_split
17597   [(set (match_operand:XF 0 "register_operand" "")
17598         (unspec:XF [(float_extend:XF
17599                       (match_operand:MODEF 2 "register_operand" ""))]
17600                    UNSPEC_SINCOS_COS))
17601    (set (match_operand:XF 1 "register_operand" "")
17602         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17603   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17604    && !(reload_completed || reload_in_progress)"
17605   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17606   "")
17607
17608 (define_expand "sincos<mode>3"
17609   [(use (match_operand:MODEF 0 "register_operand" ""))
17610    (use (match_operand:MODEF 1 "register_operand" ""))
17611    (use (match_operand:MODEF 2 "register_operand" ""))]
17612   "TARGET_USE_FANCY_MATH_387
17613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614        || TARGET_MIX_SSE_I387)
17615    && flag_unsafe_math_optimizations"
17616 {
17617   rtx op0 = gen_reg_rtx (XFmode);
17618   rtx op1 = gen_reg_rtx (XFmode);
17619
17620   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17621   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17622   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17623   DONE;
17624 })
17625
17626 (define_insn "fptanxf4_i387"
17627   [(set (match_operand:XF 0 "register_operand" "=f")
17628         (match_operand:XF 3 "const_double_operand" "F"))
17629    (set (match_operand:XF 1 "register_operand" "=u")
17630         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17631                    UNSPEC_TAN))]
17632   "TARGET_USE_FANCY_MATH_387
17633    && flag_unsafe_math_optimizations
17634    && standard_80387_constant_p (operands[3]) == 2"
17635   "fptan"
17636   [(set_attr "type" "fpspc")
17637    (set_attr "mode" "XF")])
17638
17639 (define_insn "fptan_extend<mode>xf4_i387"
17640   [(set (match_operand:MODEF 0 "register_operand" "=f")
17641         (match_operand:MODEF 3 "const_double_operand" "F"))
17642    (set (match_operand:XF 1 "register_operand" "=u")
17643         (unspec:XF [(float_extend:XF
17644                       (match_operand:MODEF 2 "register_operand" "0"))]
17645                    UNSPEC_TAN))]
17646   "TARGET_USE_FANCY_MATH_387
17647    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17648        || TARGET_MIX_SSE_I387)
17649    && flag_unsafe_math_optimizations
17650    && standard_80387_constant_p (operands[3]) == 2"
17651   "fptan"
17652   [(set_attr "type" "fpspc")
17653    (set_attr "mode" "XF")])
17654
17655 (define_expand "tanxf2"
17656   [(use (match_operand:XF 0 "register_operand" ""))
17657    (use (match_operand:XF 1 "register_operand" ""))]
17658   "TARGET_USE_FANCY_MATH_387
17659    && flag_unsafe_math_optimizations"
17660 {
17661   rtx one = gen_reg_rtx (XFmode);
17662   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17663
17664   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17665   DONE;
17666 })
17667
17668 (define_expand "tan<mode>2"
17669   [(use (match_operand:MODEF 0 "register_operand" ""))
17670    (use (match_operand:MODEF 1 "register_operand" ""))]
17671   "TARGET_USE_FANCY_MATH_387
17672    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17673        || TARGET_MIX_SSE_I387)
17674    && flag_unsafe_math_optimizations"
17675 {
17676   rtx op0 = gen_reg_rtx (XFmode);
17677
17678   rtx one = gen_reg_rtx (<MODE>mode);
17679   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17680
17681   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17682                                              operands[1], op2));
17683   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17684   DONE;
17685 })
17686
17687 (define_insn "*fpatanxf3_i387"
17688   [(set (match_operand:XF 0 "register_operand" "=f")
17689         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17690                     (match_operand:XF 2 "register_operand" "u")]
17691                    UNSPEC_FPATAN))
17692    (clobber (match_scratch:XF 3 "=2"))]
17693   "TARGET_USE_FANCY_MATH_387
17694    && flag_unsafe_math_optimizations"
17695   "fpatan"
17696   [(set_attr "type" "fpspc")
17697    (set_attr "mode" "XF")])
17698
17699 (define_insn "fpatan_extend<mode>xf3_i387"
17700   [(set (match_operand:XF 0 "register_operand" "=f")
17701         (unspec:XF [(float_extend:XF
17702                       (match_operand:MODEF 1 "register_operand" "0"))
17703                     (float_extend:XF
17704                       (match_operand:MODEF 2 "register_operand" "u"))]
17705                    UNSPEC_FPATAN))
17706    (clobber (match_scratch:XF 3 "=2"))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17709        || TARGET_MIX_SSE_I387)
17710    && flag_unsafe_math_optimizations"
17711   "fpatan"
17712   [(set_attr "type" "fpspc")
17713    (set_attr "mode" "XF")])
17714
17715 (define_expand "atan2xf3"
17716   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17717                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17718                                (match_operand:XF 1 "register_operand" "")]
17719                               UNSPEC_FPATAN))
17720               (clobber (match_scratch:XF 3 ""))])]
17721   "TARGET_USE_FANCY_MATH_387
17722    && flag_unsafe_math_optimizations"
17723   "")
17724
17725 (define_expand "atan2<mode>3"
17726   [(use (match_operand:MODEF 0 "register_operand" ""))
17727    (use (match_operand:MODEF 1 "register_operand" ""))
17728    (use (match_operand:MODEF 2 "register_operand" ""))]
17729   "TARGET_USE_FANCY_MATH_387
17730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17731        || TARGET_MIX_SSE_I387)
17732    && flag_unsafe_math_optimizations"
17733 {
17734   rtx op0 = gen_reg_rtx (XFmode);
17735
17736   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17737   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17738   DONE;
17739 })
17740
17741 (define_expand "atanxf2"
17742   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17743                    (unspec:XF [(match_dup 2)
17744                                (match_operand:XF 1 "register_operand" "")]
17745                               UNSPEC_FPATAN))
17746               (clobber (match_scratch:XF 3 ""))])]
17747   "TARGET_USE_FANCY_MATH_387
17748    && flag_unsafe_math_optimizations"
17749 {
17750   operands[2] = gen_reg_rtx (XFmode);
17751   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17752 })
17753
17754 (define_expand "atan<mode>2"
17755   [(use (match_operand:MODEF 0 "register_operand" ""))
17756    (use (match_operand:MODEF 1 "register_operand" ""))]
17757   "TARGET_USE_FANCY_MATH_387
17758    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17759        || TARGET_MIX_SSE_I387)
17760    && flag_unsafe_math_optimizations"
17761 {
17762   rtx op0 = gen_reg_rtx (XFmode);
17763
17764   rtx op2 = gen_reg_rtx (<MODE>mode);
17765   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17766
17767   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17768   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17769   DONE;
17770 })
17771
17772 (define_expand "asinxf2"
17773   [(set (match_dup 2)
17774         (mult:XF (match_operand:XF 1 "register_operand" "")
17775                  (match_dup 1)))
17776    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17777    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17778    (parallel [(set (match_operand:XF 0 "register_operand" "")
17779                    (unspec:XF [(match_dup 5) (match_dup 1)]
17780                               UNSPEC_FPATAN))
17781               (clobber (match_scratch:XF 6 ""))])]
17782   "TARGET_USE_FANCY_MATH_387
17783    && flag_unsafe_math_optimizations"
17784 {
17785   int i;
17786
17787   if (optimize_insn_for_size_p ())
17788     FAIL;
17789
17790   for (i = 2; i < 6; i++)
17791     operands[i] = gen_reg_rtx (XFmode);
17792
17793   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17794 })
17795
17796 (define_expand "asin<mode>2"
17797   [(use (match_operand:MODEF 0 "register_operand" ""))
17798    (use (match_operand:MODEF 1 "general_operand" ""))]
17799  "TARGET_USE_FANCY_MATH_387
17800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17801        || TARGET_MIX_SSE_I387)
17802    && flag_unsafe_math_optimizations"
17803 {
17804   rtx op0 = gen_reg_rtx (XFmode);
17805   rtx op1 = gen_reg_rtx (XFmode);
17806
17807   if (optimize_insn_for_size_p ())
17808     FAIL;
17809
17810   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17811   emit_insn (gen_asinxf2 (op0, op1));
17812   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17813   DONE;
17814 })
17815
17816 (define_expand "acosxf2"
17817   [(set (match_dup 2)
17818         (mult:XF (match_operand:XF 1 "register_operand" "")
17819                  (match_dup 1)))
17820    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17821    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17822    (parallel [(set (match_operand:XF 0 "register_operand" "")
17823                    (unspec:XF [(match_dup 1) (match_dup 5)]
17824                               UNSPEC_FPATAN))
17825               (clobber (match_scratch:XF 6 ""))])]
17826   "TARGET_USE_FANCY_MATH_387
17827    && flag_unsafe_math_optimizations"
17828 {
17829   int i;
17830
17831   if (optimize_insn_for_size_p ())
17832     FAIL;
17833
17834   for (i = 2; i < 6; i++)
17835     operands[i] = gen_reg_rtx (XFmode);
17836
17837   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17838 })
17839
17840 (define_expand "acos<mode>2"
17841   [(use (match_operand:MODEF 0 "register_operand" ""))
17842    (use (match_operand:MODEF 1 "general_operand" ""))]
17843  "TARGET_USE_FANCY_MATH_387
17844    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17845        || TARGET_MIX_SSE_I387)
17846    && flag_unsafe_math_optimizations"
17847 {
17848   rtx op0 = gen_reg_rtx (XFmode);
17849   rtx op1 = gen_reg_rtx (XFmode);
17850
17851   if (optimize_insn_for_size_p ())
17852     FAIL;
17853
17854   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17855   emit_insn (gen_acosxf2 (op0, op1));
17856   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17857   DONE;
17858 })
17859
17860 (define_insn "fyl2xxf3_i387"
17861   [(set (match_operand:XF 0 "register_operand" "=f")
17862         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17863                     (match_operand:XF 2 "register_operand" "u")]
17864                    UNSPEC_FYL2X))
17865    (clobber (match_scratch:XF 3 "=2"))]
17866   "TARGET_USE_FANCY_MATH_387
17867    && flag_unsafe_math_optimizations"
17868   "fyl2x"
17869   [(set_attr "type" "fpspc")
17870    (set_attr "mode" "XF")])
17871
17872 (define_insn "fyl2x_extend<mode>xf3_i387"
17873   [(set (match_operand:XF 0 "register_operand" "=f")
17874         (unspec:XF [(float_extend:XF
17875                       (match_operand:MODEF 1 "register_operand" "0"))
17876                     (match_operand:XF 2 "register_operand" "u")]
17877                    UNSPEC_FYL2X))
17878    (clobber (match_scratch:XF 3 "=2"))]
17879   "TARGET_USE_FANCY_MATH_387
17880    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17881        || TARGET_MIX_SSE_I387)
17882    && flag_unsafe_math_optimizations"
17883   "fyl2x"
17884   [(set_attr "type" "fpspc")
17885    (set_attr "mode" "XF")])
17886
17887 (define_expand "logxf2"
17888   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17889                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17890                                (match_dup 2)] UNSPEC_FYL2X))
17891               (clobber (match_scratch:XF 3 ""))])]
17892   "TARGET_USE_FANCY_MATH_387
17893    && flag_unsafe_math_optimizations"
17894 {
17895   operands[2] = gen_reg_rtx (XFmode);
17896   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17897 })
17898
17899 (define_expand "log<mode>2"
17900   [(use (match_operand:MODEF 0 "register_operand" ""))
17901    (use (match_operand:MODEF 1 "register_operand" ""))]
17902   "TARGET_USE_FANCY_MATH_387
17903    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17904        || TARGET_MIX_SSE_I387)
17905    && flag_unsafe_math_optimizations"
17906 {
17907   rtx op0 = gen_reg_rtx (XFmode);
17908
17909   rtx op2 = gen_reg_rtx (XFmode);
17910   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17911
17912   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17913   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17914   DONE;
17915 })
17916
17917 (define_expand "log10xf2"
17918   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17919                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17920                                (match_dup 2)] UNSPEC_FYL2X))
17921               (clobber (match_scratch:XF 3 ""))])]
17922   "TARGET_USE_FANCY_MATH_387
17923    && flag_unsafe_math_optimizations"
17924 {
17925   operands[2] = gen_reg_rtx (XFmode);
17926   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17927 })
17928
17929 (define_expand "log10<mode>2"
17930   [(use (match_operand:MODEF 0 "register_operand" ""))
17931    (use (match_operand:MODEF 1 "register_operand" ""))]
17932   "TARGET_USE_FANCY_MATH_387
17933    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17934        || TARGET_MIX_SSE_I387)
17935    && flag_unsafe_math_optimizations"
17936 {
17937   rtx op0 = gen_reg_rtx (XFmode);
17938
17939   rtx op2 = gen_reg_rtx (XFmode);
17940   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17941
17942   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17943   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17944   DONE;
17945 })
17946
17947 (define_expand "log2xf2"
17948   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17949                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17950                                (match_dup 2)] UNSPEC_FYL2X))
17951               (clobber (match_scratch:XF 3 ""))])]
17952   "TARGET_USE_FANCY_MATH_387
17953    && flag_unsafe_math_optimizations"
17954 {
17955   operands[2] = gen_reg_rtx (XFmode);
17956   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17957 })
17958
17959 (define_expand "log2<mode>2"
17960   [(use (match_operand:MODEF 0 "register_operand" ""))
17961    (use (match_operand:MODEF 1 "register_operand" ""))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964        || TARGET_MIX_SSE_I387)
17965    && flag_unsafe_math_optimizations"
17966 {
17967   rtx op0 = gen_reg_rtx (XFmode);
17968
17969   rtx op2 = gen_reg_rtx (XFmode);
17970   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17971
17972   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17973   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17974   DONE;
17975 })
17976
17977 (define_insn "fyl2xp1xf3_i387"
17978   [(set (match_operand:XF 0 "register_operand" "=f")
17979         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17980                     (match_operand:XF 2 "register_operand" "u")]
17981                    UNSPEC_FYL2XP1))
17982    (clobber (match_scratch:XF 3 "=2"))]
17983   "TARGET_USE_FANCY_MATH_387
17984    && flag_unsafe_math_optimizations"
17985   "fyl2xp1"
17986   [(set_attr "type" "fpspc")
17987    (set_attr "mode" "XF")])
17988
17989 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17990   [(set (match_operand:XF 0 "register_operand" "=f")
17991         (unspec:XF [(float_extend:XF
17992                       (match_operand:MODEF 1 "register_operand" "0"))
17993                     (match_operand:XF 2 "register_operand" "u")]
17994                    UNSPEC_FYL2XP1))
17995    (clobber (match_scratch:XF 3 "=2"))]
17996   "TARGET_USE_FANCY_MATH_387
17997    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17998        || TARGET_MIX_SSE_I387)
17999    && flag_unsafe_math_optimizations"
18000   "fyl2xp1"
18001   [(set_attr "type" "fpspc")
18002    (set_attr "mode" "XF")])
18003
18004 (define_expand "log1pxf2"
18005   [(use (match_operand:XF 0 "register_operand" ""))
18006    (use (match_operand:XF 1 "register_operand" ""))]
18007   "TARGET_USE_FANCY_MATH_387
18008    && flag_unsafe_math_optimizations"
18009 {
18010   if (optimize_insn_for_size_p ())
18011     FAIL;
18012
18013   ix86_emit_i387_log1p (operands[0], operands[1]);
18014   DONE;
18015 })
18016
18017 (define_expand "log1p<mode>2"
18018   [(use (match_operand:MODEF 0 "register_operand" ""))
18019    (use (match_operand:MODEF 1 "register_operand" ""))]
18020   "TARGET_USE_FANCY_MATH_387
18021    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18022        || TARGET_MIX_SSE_I387)
18023    && flag_unsafe_math_optimizations"
18024 {
18025   rtx op0;
18026
18027   if (optimize_insn_for_size_p ())
18028     FAIL;
18029
18030   op0 = gen_reg_rtx (XFmode);
18031
18032   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18033
18034   ix86_emit_i387_log1p (op0, operands[1]);
18035   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18036   DONE;
18037 })
18038
18039 (define_insn "fxtractxf3_i387"
18040   [(set (match_operand:XF 0 "register_operand" "=f")
18041         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18042                    UNSPEC_XTRACT_FRACT))
18043    (set (match_operand:XF 1 "register_operand" "=u")
18044         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18045   "TARGET_USE_FANCY_MATH_387
18046    && flag_unsafe_math_optimizations"
18047   "fxtract"
18048   [(set_attr "type" "fpspc")
18049    (set_attr "mode" "XF")])
18050
18051 (define_insn "fxtract_extend<mode>xf3_i387"
18052   [(set (match_operand:XF 0 "register_operand" "=f")
18053         (unspec:XF [(float_extend:XF
18054                       (match_operand:MODEF 2 "register_operand" "0"))]
18055                    UNSPEC_XTRACT_FRACT))
18056    (set (match_operand:XF 1 "register_operand" "=u")
18057         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18058   "TARGET_USE_FANCY_MATH_387
18059    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18060        || TARGET_MIX_SSE_I387)
18061    && flag_unsafe_math_optimizations"
18062   "fxtract"
18063   [(set_attr "type" "fpspc")
18064    (set_attr "mode" "XF")])
18065
18066 (define_expand "logbxf2"
18067   [(parallel [(set (match_dup 2)
18068                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18069                               UNSPEC_XTRACT_FRACT))
18070               (set (match_operand:XF 0 "register_operand" "")
18071                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18072   "TARGET_USE_FANCY_MATH_387
18073    && flag_unsafe_math_optimizations"
18074 {
18075   operands[2] = gen_reg_rtx (XFmode);
18076 })
18077
18078 (define_expand "logb<mode>2"
18079   [(use (match_operand:MODEF 0 "register_operand" ""))
18080    (use (match_operand:MODEF 1 "register_operand" ""))]
18081   "TARGET_USE_FANCY_MATH_387
18082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18083        || TARGET_MIX_SSE_I387)
18084    && flag_unsafe_math_optimizations"
18085 {
18086   rtx op0 = gen_reg_rtx (XFmode);
18087   rtx op1 = gen_reg_rtx (XFmode);
18088
18089   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18090   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18091   DONE;
18092 })
18093
18094 (define_expand "ilogbxf2"
18095   [(use (match_operand:SI 0 "register_operand" ""))
18096    (use (match_operand:XF 1 "register_operand" ""))]
18097   "TARGET_USE_FANCY_MATH_387
18098    && flag_unsafe_math_optimizations"
18099 {
18100   rtx op0, op1;
18101
18102   if (optimize_insn_for_size_p ())
18103     FAIL;
18104
18105   op0 = gen_reg_rtx (XFmode);
18106   op1 = gen_reg_rtx (XFmode);
18107
18108   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18109   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18110   DONE;
18111 })
18112
18113 (define_expand "ilogb<mode>2"
18114   [(use (match_operand:SI 0 "register_operand" ""))
18115    (use (match_operand:MODEF 1 "register_operand" ""))]
18116   "TARGET_USE_FANCY_MATH_387
18117    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18118        || TARGET_MIX_SSE_I387)
18119    && flag_unsafe_math_optimizations"
18120 {
18121   rtx op0, op1;
18122
18123   if (optimize_insn_for_size_p ())
18124     FAIL;
18125
18126   op0 = gen_reg_rtx (XFmode);
18127   op1 = gen_reg_rtx (XFmode);
18128
18129   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18130   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18131   DONE;
18132 })
18133
18134 (define_insn "*f2xm1xf2_i387"
18135   [(set (match_operand:XF 0 "register_operand" "=f")
18136         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18137                    UNSPEC_F2XM1))]
18138   "TARGET_USE_FANCY_MATH_387
18139    && flag_unsafe_math_optimizations"
18140   "f2xm1"
18141   [(set_attr "type" "fpspc")
18142    (set_attr "mode" "XF")])
18143
18144 (define_insn "*fscalexf4_i387"
18145   [(set (match_operand:XF 0 "register_operand" "=f")
18146         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18147                     (match_operand:XF 3 "register_operand" "1")]
18148                    UNSPEC_FSCALE_FRACT))
18149    (set (match_operand:XF 1 "register_operand" "=u")
18150         (unspec:XF [(match_dup 2) (match_dup 3)]
18151                    UNSPEC_FSCALE_EXP))]
18152   "TARGET_USE_FANCY_MATH_387
18153    && flag_unsafe_math_optimizations"
18154   "fscale"
18155   [(set_attr "type" "fpspc")
18156    (set_attr "mode" "XF")])
18157
18158 (define_expand "expNcorexf3"
18159   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18160                                (match_operand:XF 2 "register_operand" "")))
18161    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18162    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18163    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18164    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18165    (parallel [(set (match_operand:XF 0 "register_operand" "")
18166                    (unspec:XF [(match_dup 8) (match_dup 4)]
18167                               UNSPEC_FSCALE_FRACT))
18168               (set (match_dup 9)
18169                    (unspec:XF [(match_dup 8) (match_dup 4)]
18170                               UNSPEC_FSCALE_EXP))])]
18171   "TARGET_USE_FANCY_MATH_387
18172    && flag_unsafe_math_optimizations"
18173 {
18174   int i;
18175
18176   if (optimize_insn_for_size_p ())
18177     FAIL;
18178
18179   for (i = 3; i < 10; i++)
18180     operands[i] = gen_reg_rtx (XFmode);
18181
18182   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
18183 })
18184
18185 (define_expand "expxf2"
18186   [(use (match_operand:XF 0 "register_operand" ""))
18187    (use (match_operand:XF 1 "register_operand" ""))]
18188   "TARGET_USE_FANCY_MATH_387
18189    && flag_unsafe_math_optimizations"
18190 {
18191   rtx op2;
18192
18193   if (optimize_insn_for_size_p ())
18194     FAIL;
18195
18196   op2 = gen_reg_rtx (XFmode);
18197   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18198
18199   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18200   DONE;
18201 })
18202
18203 (define_expand "exp<mode>2"
18204   [(use (match_operand:MODEF 0 "register_operand" ""))
18205    (use (match_operand:MODEF 1 "general_operand" ""))]
18206  "TARGET_USE_FANCY_MATH_387
18207    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18208        || TARGET_MIX_SSE_I387)
18209    && flag_unsafe_math_optimizations"
18210 {
18211   rtx op0, op1;
18212
18213   if (optimize_insn_for_size_p ())
18214     FAIL;
18215
18216   op0 = gen_reg_rtx (XFmode);
18217   op1 = gen_reg_rtx (XFmode);
18218
18219   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18220   emit_insn (gen_expxf2 (op0, op1));
18221   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18222   DONE;
18223 })
18224
18225 (define_expand "exp10xf2"
18226   [(use (match_operand:XF 0 "register_operand" ""))
18227    (use (match_operand:XF 1 "register_operand" ""))]
18228   "TARGET_USE_FANCY_MATH_387
18229    && flag_unsafe_math_optimizations"
18230 {
18231   rtx op2;
18232
18233   if (optimize_insn_for_size_p ())
18234     FAIL;
18235
18236   op2 = gen_reg_rtx (XFmode);
18237   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18238
18239   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18240   DONE;
18241 })
18242
18243 (define_expand "exp10<mode>2"
18244   [(use (match_operand:MODEF 0 "register_operand" ""))
18245    (use (match_operand:MODEF 1 "general_operand" ""))]
18246  "TARGET_USE_FANCY_MATH_387
18247    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18248        || TARGET_MIX_SSE_I387)
18249    && flag_unsafe_math_optimizations"
18250 {
18251   rtx op0, op1;
18252
18253   if (optimize_insn_for_size_p ())
18254     FAIL;
18255
18256   op0 = gen_reg_rtx (XFmode);
18257   op1 = gen_reg_rtx (XFmode);
18258
18259   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18260   emit_insn (gen_exp10xf2 (op0, op1));
18261   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18262   DONE;
18263 })
18264
18265 (define_expand "exp2xf2"
18266   [(use (match_operand:XF 0 "register_operand" ""))
18267    (use (match_operand:XF 1 "register_operand" ""))]
18268   "TARGET_USE_FANCY_MATH_387
18269    && flag_unsafe_math_optimizations"
18270 {
18271   rtx op2;
18272
18273   if (optimize_insn_for_size_p ())
18274     FAIL;
18275
18276   op2 = gen_reg_rtx (XFmode);
18277   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
18278
18279   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18280   DONE;
18281 })
18282
18283 (define_expand "exp2<mode>2"
18284   [(use (match_operand:MODEF 0 "register_operand" ""))
18285    (use (match_operand:MODEF 1 "general_operand" ""))]
18286  "TARGET_USE_FANCY_MATH_387
18287    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18288        || TARGET_MIX_SSE_I387)
18289    && flag_unsafe_math_optimizations"
18290 {
18291   rtx op0, op1;
18292
18293   if (optimize_insn_for_size_p ())
18294     FAIL;
18295
18296   op0 = gen_reg_rtx (XFmode);
18297   op1 = gen_reg_rtx (XFmode);
18298
18299   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18300   emit_insn (gen_exp2xf2 (op0, op1));
18301   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18302   DONE;
18303 })
18304
18305 (define_expand "expm1xf2"
18306   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18307                                (match_dup 2)))
18308    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18309    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18310    (set (match_dup 9) (float_extend:XF (match_dup 13)))
18311    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18312    (parallel [(set (match_dup 7)
18313                    (unspec:XF [(match_dup 6) (match_dup 4)]
18314                               UNSPEC_FSCALE_FRACT))
18315               (set (match_dup 8)
18316                    (unspec:XF [(match_dup 6) (match_dup 4)]
18317                               UNSPEC_FSCALE_EXP))])
18318    (parallel [(set (match_dup 10)
18319                    (unspec:XF [(match_dup 9) (match_dup 8)]
18320                               UNSPEC_FSCALE_FRACT))
18321               (set (match_dup 11)
18322                    (unspec:XF [(match_dup 9) (match_dup 8)]
18323                               UNSPEC_FSCALE_EXP))])
18324    (set (match_dup 12) (minus:XF (match_dup 10)
18325                                  (float_extend:XF (match_dup 13))))
18326    (set (match_operand:XF 0 "register_operand" "")
18327         (plus:XF (match_dup 12) (match_dup 7)))]
18328   "TARGET_USE_FANCY_MATH_387
18329    && flag_unsafe_math_optimizations"
18330 {
18331   int i;
18332
18333   if (optimize_insn_for_size_p ())
18334     FAIL;
18335
18336   for (i = 2; i < 13; i++)
18337     operands[i] = gen_reg_rtx (XFmode);
18338
18339   operands[13]
18340     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18341
18342   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18343 })
18344
18345 (define_expand "expm1<mode>2"
18346   [(use (match_operand:MODEF 0 "register_operand" ""))
18347    (use (match_operand:MODEF 1 "general_operand" ""))]
18348  "TARGET_USE_FANCY_MATH_387
18349    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18350        || TARGET_MIX_SSE_I387)
18351    && flag_unsafe_math_optimizations"
18352 {
18353   rtx op0, op1;
18354
18355   if (optimize_insn_for_size_p ())
18356     FAIL;
18357
18358   op0 = gen_reg_rtx (XFmode);
18359   op1 = gen_reg_rtx (XFmode);
18360
18361   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18362   emit_insn (gen_expm1xf2 (op0, op1));
18363   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18364   DONE;
18365 })
18366
18367 (define_expand "ldexpxf3"
18368   [(set (match_dup 3)
18369         (float:XF (match_operand:SI 2 "register_operand" "")))
18370    (parallel [(set (match_operand:XF 0 " register_operand" "")
18371                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18372                                (match_dup 3)]
18373                               UNSPEC_FSCALE_FRACT))
18374               (set (match_dup 4)
18375                    (unspec:XF [(match_dup 1) (match_dup 3)]
18376                               UNSPEC_FSCALE_EXP))])]
18377   "TARGET_USE_FANCY_MATH_387
18378    && flag_unsafe_math_optimizations"
18379 {
18380   if (optimize_insn_for_size_p ())
18381     FAIL;
18382
18383   operands[3] = gen_reg_rtx (XFmode);
18384   operands[4] = gen_reg_rtx (XFmode);
18385 })
18386
18387 (define_expand "ldexp<mode>3"
18388   [(use (match_operand:MODEF 0 "register_operand" ""))
18389    (use (match_operand:MODEF 1 "general_operand" ""))
18390    (use (match_operand:SI 2 "register_operand" ""))]
18391  "TARGET_USE_FANCY_MATH_387
18392    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18393        || TARGET_MIX_SSE_I387)
18394    && flag_unsafe_math_optimizations"
18395 {
18396   rtx op0, op1;
18397
18398   if (optimize_insn_for_size_p ())
18399     FAIL;
18400
18401   op0 = gen_reg_rtx (XFmode);
18402   op1 = gen_reg_rtx (XFmode);
18403
18404   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18405   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18406   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18407   DONE;
18408 })
18409
18410 (define_expand "scalbxf3"
18411   [(parallel [(set (match_operand:XF 0 " register_operand" "")
18412                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18413                                (match_operand:XF 2 "register_operand" "")]
18414                               UNSPEC_FSCALE_FRACT))
18415               (set (match_dup 3)
18416                    (unspec:XF [(match_dup 1) (match_dup 2)]
18417                               UNSPEC_FSCALE_EXP))])]
18418   "TARGET_USE_FANCY_MATH_387
18419    && flag_unsafe_math_optimizations"
18420 {
18421   if (optimize_insn_for_size_p ())
18422     FAIL;
18423
18424   operands[3] = gen_reg_rtx (XFmode);
18425 })
18426
18427 (define_expand "scalb<mode>3"
18428   [(use (match_operand:MODEF 0 "register_operand" ""))
18429    (use (match_operand:MODEF 1 "general_operand" ""))
18430    (use (match_operand:MODEF 2 "general_operand" ""))]
18431  "TARGET_USE_FANCY_MATH_387
18432    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18433        || TARGET_MIX_SSE_I387)
18434    && flag_unsafe_math_optimizations"
18435 {
18436   rtx op0, op1, op2;
18437
18438   if (optimize_insn_for_size_p ())
18439     FAIL;
18440
18441   op0 = gen_reg_rtx (XFmode);
18442   op1 = gen_reg_rtx (XFmode);
18443   op2 = gen_reg_rtx (XFmode);
18444
18445   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18446   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18447   emit_insn (gen_scalbxf3 (op0, op1, op2));
18448   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18449   DONE;
18450 })
18451
18452 (define_expand "significandxf2"
18453   [(parallel [(set (match_operand:XF 0 "register_operand" "")
18454                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18455                               UNSPEC_XTRACT_FRACT))
18456               (set (match_dup 2)
18457                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18458   "TARGET_USE_FANCY_MATH_387
18459    && flag_unsafe_math_optimizations"
18460 {
18461   operands[2] = gen_reg_rtx (XFmode);
18462 })
18463
18464 (define_expand "significand<mode>2"
18465   [(use (match_operand:MODEF 0 "register_operand" ""))
18466    (use (match_operand:MODEF 1 "register_operand" ""))]
18467   "TARGET_USE_FANCY_MATH_387
18468    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18469        || TARGET_MIX_SSE_I387)
18470    && flag_unsafe_math_optimizations"
18471 {
18472   rtx op0 = gen_reg_rtx (XFmode);
18473   rtx op1 = gen_reg_rtx (XFmode);
18474
18475   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18476   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18477   DONE;
18478 })
18479 \f
18480
18481 (define_insn "sse4_1_round<mode>2"
18482   [(set (match_operand:MODEF 0 "register_operand" "=x")
18483         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18484                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
18485                       UNSPEC_ROUND))]
18486   "TARGET_ROUND"
18487   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18488   [(set_attr "type" "ssecvt")
18489    (set_attr "prefix_extra" "1")
18490    (set_attr "prefix" "maybe_vex")
18491    (set_attr "mode" "<MODE>")])
18492
18493 (define_insn "rintxf2"
18494   [(set (match_operand:XF 0 "register_operand" "=f")
18495         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18496                    UNSPEC_FRNDINT))]
18497   "TARGET_USE_FANCY_MATH_387
18498    && flag_unsafe_math_optimizations"
18499   "frndint"
18500   [(set_attr "type" "fpspc")
18501    (set_attr "mode" "XF")])
18502
18503 (define_expand "rint<mode>2"
18504   [(use (match_operand:MODEF 0 "register_operand" ""))
18505    (use (match_operand:MODEF 1 "register_operand" ""))]
18506   "(TARGET_USE_FANCY_MATH_387
18507     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18508         || TARGET_MIX_SSE_I387)
18509     && flag_unsafe_math_optimizations)
18510    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18511        && !flag_trapping_math)"
18512 {
18513   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18514       && !flag_trapping_math)
18515     {
18516       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18517         FAIL;
18518       if (TARGET_ROUND)
18519         emit_insn (gen_sse4_1_round<mode>2
18520                    (operands[0], operands[1], GEN_INT (0x04)));
18521       else
18522         ix86_expand_rint (operand0, operand1);
18523     }
18524   else
18525     {
18526       rtx op0 = gen_reg_rtx (XFmode);
18527       rtx op1 = gen_reg_rtx (XFmode);
18528
18529       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18530       emit_insn (gen_rintxf2 (op0, op1));
18531
18532       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18533     }
18534   DONE;
18535 })
18536
18537 (define_expand "round<mode>2"
18538   [(match_operand:MODEF 0 "register_operand" "")
18539    (match_operand:MODEF 1 "nonimmediate_operand" "")]
18540   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18541    && !flag_trapping_math && !flag_rounding_math"
18542 {
18543   if (optimize_insn_for_size_p ())
18544     FAIL;
18545   if (TARGET_64BIT || (<MODE>mode != DFmode))
18546     ix86_expand_round (operand0, operand1);
18547   else
18548     ix86_expand_rounddf_32 (operand0, operand1);
18549   DONE;
18550 })
18551
18552 (define_insn_and_split "*fistdi2_1"
18553   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18554         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18555                    UNSPEC_FIST))]
18556   "TARGET_USE_FANCY_MATH_387
18557    && can_create_pseudo_p ()"
18558   "#"
18559   "&& 1"
18560   [(const_int 0)]
18561 {
18562   if (memory_operand (operands[0], VOIDmode))
18563     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18564   else
18565     {
18566       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18567       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18568                                          operands[2]));
18569     }
18570   DONE;
18571 }
18572   [(set_attr "type" "fpspc")
18573    (set_attr "mode" "DI")])
18574
18575 (define_insn "fistdi2"
18576   [(set (match_operand:DI 0 "memory_operand" "=m")
18577         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18578                    UNSPEC_FIST))
18579    (clobber (match_scratch:XF 2 "=&1f"))]
18580   "TARGET_USE_FANCY_MATH_387"
18581   "* return output_fix_trunc (insn, operands, 0);"
18582   [(set_attr "type" "fpspc")
18583    (set_attr "mode" "DI")])
18584
18585 (define_insn "fistdi2_with_temp"
18586   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18587         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18588                    UNSPEC_FIST))
18589    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18590    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18591   "TARGET_USE_FANCY_MATH_387"
18592   "#"
18593   [(set_attr "type" "fpspc")
18594    (set_attr "mode" "DI")])
18595
18596 (define_split
18597   [(set (match_operand:DI 0 "register_operand" "")
18598         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18599                    UNSPEC_FIST))
18600    (clobber (match_operand:DI 2 "memory_operand" ""))
18601    (clobber (match_scratch 3 ""))]
18602   "reload_completed"
18603   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18604               (clobber (match_dup 3))])
18605    (set (match_dup 0) (match_dup 2))]
18606   "")
18607
18608 (define_split
18609   [(set (match_operand:DI 0 "memory_operand" "")
18610         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18611                    UNSPEC_FIST))
18612    (clobber (match_operand:DI 2 "memory_operand" ""))
18613    (clobber (match_scratch 3 ""))]
18614   "reload_completed"
18615   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18616               (clobber (match_dup 3))])]
18617   "")
18618
18619 (define_insn_and_split "*fist<mode>2_1"
18620   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18621         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18622                            UNSPEC_FIST))]
18623   "TARGET_USE_FANCY_MATH_387
18624    && can_create_pseudo_p ()"
18625   "#"
18626   "&& 1"
18627   [(const_int 0)]
18628 {
18629   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18630   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18631                                         operands[2]));
18632   DONE;
18633 }
18634   [(set_attr "type" "fpspc")
18635    (set_attr "mode" "<MODE>")])
18636
18637 (define_insn "fist<mode>2"
18638   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18639         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18640                            UNSPEC_FIST))]
18641   "TARGET_USE_FANCY_MATH_387"
18642   "* return output_fix_trunc (insn, operands, 0);"
18643   [(set_attr "type" "fpspc")
18644    (set_attr "mode" "<MODE>")])
18645
18646 (define_insn "fist<mode>2_with_temp"
18647   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18648         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18649                            UNSPEC_FIST))
18650    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18651   "TARGET_USE_FANCY_MATH_387"
18652   "#"
18653   [(set_attr "type" "fpspc")
18654    (set_attr "mode" "<MODE>")])
18655
18656 (define_split
18657   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18658         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18659                            UNSPEC_FIST))
18660    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18661   "reload_completed"
18662   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18663    (set (match_dup 0) (match_dup 2))]
18664   "")
18665
18666 (define_split
18667   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18668         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18669                            UNSPEC_FIST))
18670    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18671   "reload_completed"
18672   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18673   "")
18674
18675 (define_expand "lrintxf<mode>2"
18676   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18677      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18678                       UNSPEC_FIST))]
18679   "TARGET_USE_FANCY_MATH_387"
18680   "")
18681
18682 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18683   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18684      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18685                         UNSPEC_FIX_NOTRUNC))]
18686   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18687    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18688   "")
18689
18690 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18691   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18692    (match_operand:MODEF 1 "register_operand" "")]
18693   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18694    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18695    && !flag_trapping_math && !flag_rounding_math"
18696 {
18697   if (optimize_insn_for_size_p ())
18698     FAIL;
18699   ix86_expand_lround (operand0, operand1);
18700   DONE;
18701 })
18702
18703 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18704 (define_insn_and_split "frndintxf2_floor"
18705   [(set (match_operand:XF 0 "register_operand" "")
18706         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18707          UNSPEC_FRNDINT_FLOOR))
18708    (clobber (reg:CC FLAGS_REG))]
18709   "TARGET_USE_FANCY_MATH_387
18710    && flag_unsafe_math_optimizations
18711    && can_create_pseudo_p ()"
18712   "#"
18713   "&& 1"
18714   [(const_int 0)]
18715 {
18716   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18717
18718   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18719   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18720
18721   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18722                                         operands[2], operands[3]));
18723   DONE;
18724 }
18725   [(set_attr "type" "frndint")
18726    (set_attr "i387_cw" "floor")
18727    (set_attr "mode" "XF")])
18728
18729 (define_insn "frndintxf2_floor_i387"
18730   [(set (match_operand:XF 0 "register_operand" "=f")
18731         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18732          UNSPEC_FRNDINT_FLOOR))
18733    (use (match_operand:HI 2 "memory_operand" "m"))
18734    (use (match_operand:HI 3 "memory_operand" "m"))]
18735   "TARGET_USE_FANCY_MATH_387
18736    && flag_unsafe_math_optimizations"
18737   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18738   [(set_attr "type" "frndint")
18739    (set_attr "i387_cw" "floor")
18740    (set_attr "mode" "XF")])
18741
18742 (define_expand "floorxf2"
18743   [(use (match_operand:XF 0 "register_operand" ""))
18744    (use (match_operand:XF 1 "register_operand" ""))]
18745   "TARGET_USE_FANCY_MATH_387
18746    && flag_unsafe_math_optimizations"
18747 {
18748   if (optimize_insn_for_size_p ())
18749     FAIL;
18750   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18751   DONE;
18752 })
18753
18754 (define_expand "floor<mode>2"
18755   [(use (match_operand:MODEF 0 "register_operand" ""))
18756    (use (match_operand:MODEF 1 "register_operand" ""))]
18757   "(TARGET_USE_FANCY_MATH_387
18758     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759         || TARGET_MIX_SSE_I387)
18760     && flag_unsafe_math_optimizations)
18761    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18762        && !flag_trapping_math)"
18763 {
18764   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18765       && !flag_trapping_math
18766       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18767     {
18768       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18769         FAIL;
18770       if (TARGET_ROUND)
18771         emit_insn (gen_sse4_1_round<mode>2
18772                    (operands[0], operands[1], GEN_INT (0x01)));
18773       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18774         ix86_expand_floorceil (operand0, operand1, true);
18775       else
18776         ix86_expand_floorceildf_32 (operand0, operand1, true);
18777     }
18778   else
18779     {
18780       rtx op0, op1;
18781
18782       if (optimize_insn_for_size_p ())
18783         FAIL;
18784
18785       op0 = gen_reg_rtx (XFmode);
18786       op1 = gen_reg_rtx (XFmode);
18787       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18788       emit_insn (gen_frndintxf2_floor (op0, op1));
18789
18790       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18791     }
18792   DONE;
18793 })
18794
18795 (define_insn_and_split "*fist<mode>2_floor_1"
18796   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18797         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18798          UNSPEC_FIST_FLOOR))
18799    (clobber (reg:CC FLAGS_REG))]
18800   "TARGET_USE_FANCY_MATH_387
18801    && flag_unsafe_math_optimizations
18802    && can_create_pseudo_p ()"
18803   "#"
18804   "&& 1"
18805   [(const_int 0)]
18806 {
18807   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18808
18809   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18810   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18811   if (memory_operand (operands[0], VOIDmode))
18812     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18813                                       operands[2], operands[3]));
18814   else
18815     {
18816       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18817       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18818                                                   operands[2], operands[3],
18819                                                   operands[4]));
18820     }
18821   DONE;
18822 }
18823   [(set_attr "type" "fistp")
18824    (set_attr "i387_cw" "floor")
18825    (set_attr "mode" "<MODE>")])
18826
18827 (define_insn "fistdi2_floor"
18828   [(set (match_operand:DI 0 "memory_operand" "=m")
18829         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18830          UNSPEC_FIST_FLOOR))
18831    (use (match_operand:HI 2 "memory_operand" "m"))
18832    (use (match_operand:HI 3 "memory_operand" "m"))
18833    (clobber (match_scratch:XF 4 "=&1f"))]
18834   "TARGET_USE_FANCY_MATH_387
18835    && flag_unsafe_math_optimizations"
18836   "* return output_fix_trunc (insn, operands, 0);"
18837   [(set_attr "type" "fistp")
18838    (set_attr "i387_cw" "floor")
18839    (set_attr "mode" "DI")])
18840
18841 (define_insn "fistdi2_floor_with_temp"
18842   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18843         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18844          UNSPEC_FIST_FLOOR))
18845    (use (match_operand:HI 2 "memory_operand" "m,m"))
18846    (use (match_operand:HI 3 "memory_operand" "m,m"))
18847    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18848    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18849   "TARGET_USE_FANCY_MATH_387
18850    && flag_unsafe_math_optimizations"
18851   "#"
18852   [(set_attr "type" "fistp")
18853    (set_attr "i387_cw" "floor")
18854    (set_attr "mode" "DI")])
18855
18856 (define_split
18857   [(set (match_operand:DI 0 "register_operand" "")
18858         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18859          UNSPEC_FIST_FLOOR))
18860    (use (match_operand:HI 2 "memory_operand" ""))
18861    (use (match_operand:HI 3 "memory_operand" ""))
18862    (clobber (match_operand:DI 4 "memory_operand" ""))
18863    (clobber (match_scratch 5 ""))]
18864   "reload_completed"
18865   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18866               (use (match_dup 2))
18867               (use (match_dup 3))
18868               (clobber (match_dup 5))])
18869    (set (match_dup 0) (match_dup 4))]
18870   "")
18871
18872 (define_split
18873   [(set (match_operand:DI 0 "memory_operand" "")
18874         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18875          UNSPEC_FIST_FLOOR))
18876    (use (match_operand:HI 2 "memory_operand" ""))
18877    (use (match_operand:HI 3 "memory_operand" ""))
18878    (clobber (match_operand:DI 4 "memory_operand" ""))
18879    (clobber (match_scratch 5 ""))]
18880   "reload_completed"
18881   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18882               (use (match_dup 2))
18883               (use (match_dup 3))
18884               (clobber (match_dup 5))])]
18885   "")
18886
18887 (define_insn "fist<mode>2_floor"
18888   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18889         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18890          UNSPEC_FIST_FLOOR))
18891    (use (match_operand:HI 2 "memory_operand" "m"))
18892    (use (match_operand:HI 3 "memory_operand" "m"))]
18893   "TARGET_USE_FANCY_MATH_387
18894    && flag_unsafe_math_optimizations"
18895   "* return output_fix_trunc (insn, operands, 0);"
18896   [(set_attr "type" "fistp")
18897    (set_attr "i387_cw" "floor")
18898    (set_attr "mode" "<MODE>")])
18899
18900 (define_insn "fist<mode>2_floor_with_temp"
18901   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18902         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18903          UNSPEC_FIST_FLOOR))
18904    (use (match_operand:HI 2 "memory_operand" "m,m"))
18905    (use (match_operand:HI 3 "memory_operand" "m,m"))
18906    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18907   "TARGET_USE_FANCY_MATH_387
18908    && flag_unsafe_math_optimizations"
18909   "#"
18910   [(set_attr "type" "fistp")
18911    (set_attr "i387_cw" "floor")
18912    (set_attr "mode" "<MODE>")])
18913
18914 (define_split
18915   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18916         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18917          UNSPEC_FIST_FLOOR))
18918    (use (match_operand:HI 2 "memory_operand" ""))
18919    (use (match_operand:HI 3 "memory_operand" ""))
18920    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18921   "reload_completed"
18922   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18923                                   UNSPEC_FIST_FLOOR))
18924               (use (match_dup 2))
18925               (use (match_dup 3))])
18926    (set (match_dup 0) (match_dup 4))]
18927   "")
18928
18929 (define_split
18930   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18931         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18932          UNSPEC_FIST_FLOOR))
18933    (use (match_operand:HI 2 "memory_operand" ""))
18934    (use (match_operand:HI 3 "memory_operand" ""))
18935    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18936   "reload_completed"
18937   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18938                                   UNSPEC_FIST_FLOOR))
18939               (use (match_dup 2))
18940               (use (match_dup 3))])]
18941   "")
18942
18943 (define_expand "lfloorxf<mode>2"
18944   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18945                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18946                     UNSPEC_FIST_FLOOR))
18947               (clobber (reg:CC FLAGS_REG))])]
18948   "TARGET_USE_FANCY_MATH_387
18949    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18950    && flag_unsafe_math_optimizations"
18951   "")
18952
18953 (define_expand "lfloor<mode>di2"
18954   [(match_operand:DI 0 "nonimmediate_operand" "")
18955    (match_operand:MODEF 1 "register_operand" "")]
18956   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18957    && !flag_trapping_math"
18958 {
18959   if (optimize_insn_for_size_p ())
18960     FAIL;
18961   ix86_expand_lfloorceil (operand0, operand1, true);
18962   DONE;
18963 })
18964
18965 (define_expand "lfloor<mode>si2"
18966   [(match_operand:SI 0 "nonimmediate_operand" "")
18967    (match_operand:MODEF 1 "register_operand" "")]
18968   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18969    && !flag_trapping_math"
18970 {
18971   if (optimize_insn_for_size_p () && TARGET_64BIT)
18972     FAIL;
18973   ix86_expand_lfloorceil (operand0, operand1, true);
18974   DONE;
18975 })
18976
18977 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18978 (define_insn_and_split "frndintxf2_ceil"
18979   [(set (match_operand:XF 0 "register_operand" "")
18980         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18981          UNSPEC_FRNDINT_CEIL))
18982    (clobber (reg:CC FLAGS_REG))]
18983   "TARGET_USE_FANCY_MATH_387
18984    && flag_unsafe_math_optimizations
18985    && can_create_pseudo_p ()"
18986   "#"
18987   "&& 1"
18988   [(const_int 0)]
18989 {
18990   ix86_optimize_mode_switching[I387_CEIL] = 1;
18991
18992   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18993   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18994
18995   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18996                                        operands[2], operands[3]));
18997   DONE;
18998 }
18999   [(set_attr "type" "frndint")
19000    (set_attr "i387_cw" "ceil")
19001    (set_attr "mode" "XF")])
19002
19003 (define_insn "frndintxf2_ceil_i387"
19004   [(set (match_operand:XF 0 "register_operand" "=f")
19005         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19006          UNSPEC_FRNDINT_CEIL))
19007    (use (match_operand:HI 2 "memory_operand" "m"))
19008    (use (match_operand:HI 3 "memory_operand" "m"))]
19009   "TARGET_USE_FANCY_MATH_387
19010    && flag_unsafe_math_optimizations"
19011   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19012   [(set_attr "type" "frndint")
19013    (set_attr "i387_cw" "ceil")
19014    (set_attr "mode" "XF")])
19015
19016 (define_expand "ceilxf2"
19017   [(use (match_operand:XF 0 "register_operand" ""))
19018    (use (match_operand:XF 1 "register_operand" ""))]
19019   "TARGET_USE_FANCY_MATH_387
19020    && flag_unsafe_math_optimizations"
19021 {
19022   if (optimize_insn_for_size_p ())
19023     FAIL;
19024   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19025   DONE;
19026 })
19027
19028 (define_expand "ceil<mode>2"
19029   [(use (match_operand:MODEF 0 "register_operand" ""))
19030    (use (match_operand:MODEF 1 "register_operand" ""))]
19031   "(TARGET_USE_FANCY_MATH_387
19032     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19033         || TARGET_MIX_SSE_I387)
19034     && flag_unsafe_math_optimizations)
19035    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19036        && !flag_trapping_math)"
19037 {
19038   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19039       && !flag_trapping_math
19040       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19041     {
19042       if (TARGET_ROUND)
19043         emit_insn (gen_sse4_1_round<mode>2
19044                    (operands[0], operands[1], GEN_INT (0x02)));
19045       else if (optimize_insn_for_size_p ())
19046         FAIL;
19047       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19048         ix86_expand_floorceil (operand0, operand1, false);
19049       else
19050         ix86_expand_floorceildf_32 (operand0, operand1, false);
19051     }
19052   else
19053     {
19054       rtx op0, op1;
19055
19056       if (optimize_insn_for_size_p ())
19057         FAIL;
19058
19059       op0 = gen_reg_rtx (XFmode);
19060       op1 = gen_reg_rtx (XFmode);
19061       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19062       emit_insn (gen_frndintxf2_ceil (op0, op1));
19063
19064       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19065     }
19066   DONE;
19067 })
19068
19069 (define_insn_and_split "*fist<mode>2_ceil_1"
19070   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19071         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19072          UNSPEC_FIST_CEIL))
19073    (clobber (reg:CC FLAGS_REG))]
19074   "TARGET_USE_FANCY_MATH_387
19075    && flag_unsafe_math_optimizations
19076    && can_create_pseudo_p ()"
19077   "#"
19078   "&& 1"
19079   [(const_int 0)]
19080 {
19081   ix86_optimize_mode_switching[I387_CEIL] = 1;
19082
19083   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19084   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19085   if (memory_operand (operands[0], VOIDmode))
19086     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19087                                      operands[2], operands[3]));
19088   else
19089     {
19090       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19091       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19092                                                  operands[2], operands[3],
19093                                                  operands[4]));
19094     }
19095   DONE;
19096 }
19097   [(set_attr "type" "fistp")
19098    (set_attr "i387_cw" "ceil")
19099    (set_attr "mode" "<MODE>")])
19100
19101 (define_insn "fistdi2_ceil"
19102   [(set (match_operand:DI 0 "memory_operand" "=m")
19103         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19104          UNSPEC_FIST_CEIL))
19105    (use (match_operand:HI 2 "memory_operand" "m"))
19106    (use (match_operand:HI 3 "memory_operand" "m"))
19107    (clobber (match_scratch:XF 4 "=&1f"))]
19108   "TARGET_USE_FANCY_MATH_387
19109    && flag_unsafe_math_optimizations"
19110   "* return output_fix_trunc (insn, operands, 0);"
19111   [(set_attr "type" "fistp")
19112    (set_attr "i387_cw" "ceil")
19113    (set_attr "mode" "DI")])
19114
19115 (define_insn "fistdi2_ceil_with_temp"
19116   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19117         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19118          UNSPEC_FIST_CEIL))
19119    (use (match_operand:HI 2 "memory_operand" "m,m"))
19120    (use (match_operand:HI 3 "memory_operand" "m,m"))
19121    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19122    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19123   "TARGET_USE_FANCY_MATH_387
19124    && flag_unsafe_math_optimizations"
19125   "#"
19126   [(set_attr "type" "fistp")
19127    (set_attr "i387_cw" "ceil")
19128    (set_attr "mode" "DI")])
19129
19130 (define_split
19131   [(set (match_operand:DI 0 "register_operand" "")
19132         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19133          UNSPEC_FIST_CEIL))
19134    (use (match_operand:HI 2 "memory_operand" ""))
19135    (use (match_operand:HI 3 "memory_operand" ""))
19136    (clobber (match_operand:DI 4 "memory_operand" ""))
19137    (clobber (match_scratch 5 ""))]
19138   "reload_completed"
19139   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19140               (use (match_dup 2))
19141               (use (match_dup 3))
19142               (clobber (match_dup 5))])
19143    (set (match_dup 0) (match_dup 4))]
19144   "")
19145
19146 (define_split
19147   [(set (match_operand:DI 0 "memory_operand" "")
19148         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19149          UNSPEC_FIST_CEIL))
19150    (use (match_operand:HI 2 "memory_operand" ""))
19151    (use (match_operand:HI 3 "memory_operand" ""))
19152    (clobber (match_operand:DI 4 "memory_operand" ""))
19153    (clobber (match_scratch 5 ""))]
19154   "reload_completed"
19155   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19156               (use (match_dup 2))
19157               (use (match_dup 3))
19158               (clobber (match_dup 5))])]
19159   "")
19160
19161 (define_insn "fist<mode>2_ceil"
19162   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19163         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19164          UNSPEC_FIST_CEIL))
19165    (use (match_operand:HI 2 "memory_operand" "m"))
19166    (use (match_operand:HI 3 "memory_operand" "m"))]
19167   "TARGET_USE_FANCY_MATH_387
19168    && flag_unsafe_math_optimizations"
19169   "* return output_fix_trunc (insn, operands, 0);"
19170   [(set_attr "type" "fistp")
19171    (set_attr "i387_cw" "ceil")
19172    (set_attr "mode" "<MODE>")])
19173
19174 (define_insn "fist<mode>2_ceil_with_temp"
19175   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19176         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19177          UNSPEC_FIST_CEIL))
19178    (use (match_operand:HI 2 "memory_operand" "m,m"))
19179    (use (match_operand:HI 3 "memory_operand" "m,m"))
19180    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19181   "TARGET_USE_FANCY_MATH_387
19182    && flag_unsafe_math_optimizations"
19183   "#"
19184   [(set_attr "type" "fistp")
19185    (set_attr "i387_cw" "ceil")
19186    (set_attr "mode" "<MODE>")])
19187
19188 (define_split
19189   [(set (match_operand:X87MODEI12 0 "register_operand" "")
19190         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19191          UNSPEC_FIST_CEIL))
19192    (use (match_operand:HI 2 "memory_operand" ""))
19193    (use (match_operand:HI 3 "memory_operand" ""))
19194    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19195   "reload_completed"
19196   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19197                                   UNSPEC_FIST_CEIL))
19198               (use (match_dup 2))
19199               (use (match_dup 3))])
19200    (set (match_dup 0) (match_dup 4))]
19201   "")
19202
19203 (define_split
19204   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19205         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19206          UNSPEC_FIST_CEIL))
19207    (use (match_operand:HI 2 "memory_operand" ""))
19208    (use (match_operand:HI 3 "memory_operand" ""))
19209    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19210   "reload_completed"
19211   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19212                                   UNSPEC_FIST_CEIL))
19213               (use (match_dup 2))
19214               (use (match_dup 3))])]
19215   "")
19216
19217 (define_expand "lceilxf<mode>2"
19218   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19219                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19220                     UNSPEC_FIST_CEIL))
19221               (clobber (reg:CC FLAGS_REG))])]
19222   "TARGET_USE_FANCY_MATH_387
19223    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19224    && flag_unsafe_math_optimizations"
19225   "")
19226
19227 (define_expand "lceil<mode>di2"
19228   [(match_operand:DI 0 "nonimmediate_operand" "")
19229    (match_operand:MODEF 1 "register_operand" "")]
19230   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19231    && !flag_trapping_math"
19232 {
19233   ix86_expand_lfloorceil (operand0, operand1, false);
19234   DONE;
19235 })
19236
19237 (define_expand "lceil<mode>si2"
19238   [(match_operand:SI 0 "nonimmediate_operand" "")
19239    (match_operand:MODEF 1 "register_operand" "")]
19240   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19241    && !flag_trapping_math"
19242 {
19243   ix86_expand_lfloorceil (operand0, operand1, false);
19244   DONE;
19245 })
19246
19247 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19248 (define_insn_and_split "frndintxf2_trunc"
19249   [(set (match_operand:XF 0 "register_operand" "")
19250         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19251          UNSPEC_FRNDINT_TRUNC))
19252    (clobber (reg:CC FLAGS_REG))]
19253   "TARGET_USE_FANCY_MATH_387
19254    && flag_unsafe_math_optimizations
19255    && can_create_pseudo_p ()"
19256   "#"
19257   "&& 1"
19258   [(const_int 0)]
19259 {
19260   ix86_optimize_mode_switching[I387_TRUNC] = 1;
19261
19262   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19263   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19264
19265   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19266                                         operands[2], operands[3]));
19267   DONE;
19268 }
19269   [(set_attr "type" "frndint")
19270    (set_attr "i387_cw" "trunc")
19271    (set_attr "mode" "XF")])
19272
19273 (define_insn "frndintxf2_trunc_i387"
19274   [(set (match_operand:XF 0 "register_operand" "=f")
19275         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19276          UNSPEC_FRNDINT_TRUNC))
19277    (use (match_operand:HI 2 "memory_operand" "m"))
19278    (use (match_operand:HI 3 "memory_operand" "m"))]
19279   "TARGET_USE_FANCY_MATH_387
19280    && flag_unsafe_math_optimizations"
19281   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19282   [(set_attr "type" "frndint")
19283    (set_attr "i387_cw" "trunc")
19284    (set_attr "mode" "XF")])
19285
19286 (define_expand "btruncxf2"
19287   [(use (match_operand:XF 0 "register_operand" ""))
19288    (use (match_operand:XF 1 "register_operand" ""))]
19289   "TARGET_USE_FANCY_MATH_387
19290    && flag_unsafe_math_optimizations"
19291 {
19292   if (optimize_insn_for_size_p ())
19293     FAIL;
19294   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19295   DONE;
19296 })
19297
19298 (define_expand "btrunc<mode>2"
19299   [(use (match_operand:MODEF 0 "register_operand" ""))
19300    (use (match_operand:MODEF 1 "register_operand" ""))]
19301   "(TARGET_USE_FANCY_MATH_387
19302     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19303         || TARGET_MIX_SSE_I387)
19304     && flag_unsafe_math_optimizations)
19305    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19306        && !flag_trapping_math)"
19307 {
19308   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19309       && !flag_trapping_math
19310       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19311     {
19312       if (TARGET_ROUND)
19313         emit_insn (gen_sse4_1_round<mode>2
19314                    (operands[0], operands[1], GEN_INT (0x03)));
19315       else if (optimize_insn_for_size_p ())
19316         FAIL;
19317       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19318         ix86_expand_trunc (operand0, operand1);
19319       else
19320         ix86_expand_truncdf_32 (operand0, operand1);
19321     }
19322   else
19323     {
19324       rtx op0, op1;
19325
19326       if (optimize_insn_for_size_p ())
19327         FAIL;
19328
19329       op0 = gen_reg_rtx (XFmode);
19330       op1 = gen_reg_rtx (XFmode);
19331       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19332       emit_insn (gen_frndintxf2_trunc (op0, op1));
19333
19334       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19335     }
19336   DONE;
19337 })
19338
19339 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19340 (define_insn_and_split "frndintxf2_mask_pm"
19341   [(set (match_operand:XF 0 "register_operand" "")
19342         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19343          UNSPEC_FRNDINT_MASK_PM))
19344    (clobber (reg:CC FLAGS_REG))]
19345   "TARGET_USE_FANCY_MATH_387
19346    && flag_unsafe_math_optimizations
19347    && can_create_pseudo_p ()"
19348   "#"
19349   "&& 1"
19350   [(const_int 0)]
19351 {
19352   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19353
19354   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19355   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19356
19357   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19358                                           operands[2], operands[3]));
19359   DONE;
19360 }
19361   [(set_attr "type" "frndint")
19362    (set_attr "i387_cw" "mask_pm")
19363    (set_attr "mode" "XF")])
19364
19365 (define_insn "frndintxf2_mask_pm_i387"
19366   [(set (match_operand:XF 0 "register_operand" "=f")
19367         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19368          UNSPEC_FRNDINT_MASK_PM))
19369    (use (match_operand:HI 2 "memory_operand" "m"))
19370    (use (match_operand:HI 3 "memory_operand" "m"))]
19371   "TARGET_USE_FANCY_MATH_387
19372    && flag_unsafe_math_optimizations"
19373   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19374   [(set_attr "type" "frndint")
19375    (set_attr "i387_cw" "mask_pm")
19376    (set_attr "mode" "XF")])
19377
19378 (define_expand "nearbyintxf2"
19379   [(use (match_operand:XF 0 "register_operand" ""))
19380    (use (match_operand:XF 1 "register_operand" ""))]
19381   "TARGET_USE_FANCY_MATH_387
19382    && flag_unsafe_math_optimizations"
19383 {
19384   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19385
19386   DONE;
19387 })
19388
19389 (define_expand "nearbyint<mode>2"
19390   [(use (match_operand:MODEF 0 "register_operand" ""))
19391    (use (match_operand:MODEF 1 "register_operand" ""))]
19392   "TARGET_USE_FANCY_MATH_387
19393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19394        || TARGET_MIX_SSE_I387)
19395    && flag_unsafe_math_optimizations"
19396 {
19397   rtx op0 = gen_reg_rtx (XFmode);
19398   rtx op1 = gen_reg_rtx (XFmode);
19399
19400   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19401   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19402
19403   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19404   DONE;
19405 })
19406
19407 (define_insn "fxam<mode>2_i387"
19408   [(set (match_operand:HI 0 "register_operand" "=a")
19409         (unspec:HI
19410           [(match_operand:X87MODEF 1 "register_operand" "f")]
19411           UNSPEC_FXAM))]
19412   "TARGET_USE_FANCY_MATH_387"
19413   "fxam\n\tfnstsw\t%0"
19414   [(set_attr "type" "multi")
19415    (set_attr "length" "4")
19416    (set_attr "unit" "i387")
19417    (set_attr "mode" "<MODE>")])
19418
19419 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19420   [(set (match_operand:HI 0 "register_operand" "")
19421         (unspec:HI
19422           [(match_operand:MODEF 1 "memory_operand" "")]
19423           UNSPEC_FXAM_MEM))]
19424   "TARGET_USE_FANCY_MATH_387
19425    && can_create_pseudo_p ()"
19426   "#"
19427   "&& 1"
19428   [(set (match_dup 2)(match_dup 1))
19429    (set (match_dup 0)
19430         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19431 {
19432   operands[2] = gen_reg_rtx (<MODE>mode);
19433
19434   MEM_VOLATILE_P (operands[1]) = 1;
19435 }
19436   [(set_attr "type" "multi")
19437    (set_attr "unit" "i387")
19438    (set_attr "mode" "<MODE>")])
19439
19440 (define_expand "isinfxf2"
19441   [(use (match_operand:SI 0 "register_operand" ""))
19442    (use (match_operand:XF 1 "register_operand" ""))]
19443   "TARGET_USE_FANCY_MATH_387
19444    && TARGET_C99_FUNCTIONS"
19445 {
19446   rtx mask = GEN_INT (0x45);
19447   rtx val = GEN_INT (0x05);
19448
19449   rtx cond;
19450
19451   rtx scratch = gen_reg_rtx (HImode);
19452   rtx res = gen_reg_rtx (QImode);
19453
19454   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19455
19456   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19457   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19458   cond = gen_rtx_fmt_ee (EQ, QImode,
19459                          gen_rtx_REG (CCmode, FLAGS_REG),
19460                          const0_rtx);
19461   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19462   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19463   DONE;
19464 })
19465
19466 (define_expand "isinf<mode>2"
19467   [(use (match_operand:SI 0 "register_operand" ""))
19468    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19469   "TARGET_USE_FANCY_MATH_387
19470    && TARGET_C99_FUNCTIONS
19471    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19472 {
19473   rtx mask = GEN_INT (0x45);
19474   rtx val = GEN_INT (0x05);
19475
19476   rtx cond;
19477
19478   rtx scratch = gen_reg_rtx (HImode);
19479   rtx res = gen_reg_rtx (QImode);
19480
19481   /* Remove excess precision by forcing value through memory. */
19482   if (memory_operand (operands[1], VOIDmode))
19483     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19484   else
19485     {
19486       enum ix86_stack_slot slot = (virtuals_instantiated
19487                                    ? SLOT_TEMP
19488                                    : SLOT_VIRTUAL);
19489       rtx temp = assign_386_stack_local (<MODE>mode, slot);
19490
19491       emit_move_insn (temp, operands[1]);
19492       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19493     }
19494
19495   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19496   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19497   cond = gen_rtx_fmt_ee (EQ, QImode,
19498                          gen_rtx_REG (CCmode, FLAGS_REG),
19499                          const0_rtx);
19500   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19501   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19502   DONE;
19503 })
19504
19505 (define_expand "signbit<mode>2"
19506   [(use (match_operand:SI 0 "register_operand" ""))
19507    (use (match_operand:X87MODEF 1 "register_operand" ""))]
19508   "TARGET_USE_FANCY_MATH_387
19509    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19510 {
19511   rtx mask = GEN_INT (0x0200);
19512
19513   rtx scratch = gen_reg_rtx (HImode);
19514
19515   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19516   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19517   DONE;
19518 })
19519 \f
19520 ;; Block operation instructions
19521
19522 (define_insn "cld"
19523   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19524   ""
19525   "cld"
19526   [(set_attr "length" "1")
19527    (set_attr "length_immediate" "0")
19528    (set_attr "modrm" "0")])
19529
19530 (define_expand "movmemsi"
19531   [(use (match_operand:BLK 0 "memory_operand" ""))
19532    (use (match_operand:BLK 1 "memory_operand" ""))
19533    (use (match_operand:SI 2 "nonmemory_operand" ""))
19534    (use (match_operand:SI 3 "const_int_operand" ""))
19535    (use (match_operand:SI 4 "const_int_operand" ""))
19536    (use (match_operand:SI 5 "const_int_operand" ""))]
19537   ""
19538 {
19539  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19540                          operands[4], operands[5]))
19541    DONE;
19542  else
19543    FAIL;
19544 })
19545
19546 (define_expand "movmemdi"
19547   [(use (match_operand:BLK 0 "memory_operand" ""))
19548    (use (match_operand:BLK 1 "memory_operand" ""))
19549    (use (match_operand:DI 2 "nonmemory_operand" ""))
19550    (use (match_operand:DI 3 "const_int_operand" ""))
19551    (use (match_operand:SI 4 "const_int_operand" ""))
19552    (use (match_operand:SI 5 "const_int_operand" ""))]
19553   "TARGET_64BIT"
19554 {
19555  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19556                          operands[4], operands[5]))
19557    DONE;
19558  else
19559    FAIL;
19560 })
19561
19562 ;; Most CPUs don't like single string operations
19563 ;; Handle this case here to simplify previous expander.
19564
19565 (define_expand "strmov"
19566   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19567    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19568    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19569               (clobber (reg:CC FLAGS_REG))])
19570    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19571               (clobber (reg:CC FLAGS_REG))])]
19572   ""
19573 {
19574   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19575
19576   /* If .md ever supports :P for Pmode, these can be directly
19577      in the pattern above.  */
19578   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19579   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19580
19581   /* Can't use this if the user has appropriated esi or edi.  */
19582   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19583       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19584     {
19585       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19586                                       operands[2], operands[3],
19587                                       operands[5], operands[6]));
19588       DONE;
19589     }
19590
19591   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19592 })
19593
19594 (define_expand "strmov_singleop"
19595   [(parallel [(set (match_operand 1 "memory_operand" "")
19596                    (match_operand 3 "memory_operand" ""))
19597               (set (match_operand 0 "register_operand" "")
19598                    (match_operand 4 "" ""))
19599               (set (match_operand 2 "register_operand" "")
19600                    (match_operand 5 "" ""))])]
19601   ""
19602   "ix86_current_function_needs_cld = 1;")
19603
19604 (define_insn "*strmovdi_rex_1"
19605   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19606         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19607    (set (match_operand:DI 0 "register_operand" "=D")
19608         (plus:DI (match_dup 2)
19609                  (const_int 8)))
19610    (set (match_operand:DI 1 "register_operand" "=S")
19611         (plus:DI (match_dup 3)
19612                  (const_int 8)))]
19613   "TARGET_64BIT"
19614   "movsq"
19615   [(set_attr "type" "str")
19616    (set_attr "mode" "DI")
19617    (set_attr "memory" "both")])
19618
19619 (define_insn "*strmovsi_1"
19620   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19621         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19622    (set (match_operand:SI 0 "register_operand" "=D")
19623         (plus:SI (match_dup 2)
19624                  (const_int 4)))
19625    (set (match_operand:SI 1 "register_operand" "=S")
19626         (plus:SI (match_dup 3)
19627                  (const_int 4)))]
19628   "!TARGET_64BIT"
19629   "movs{l|d}"
19630   [(set_attr "type" "str")
19631    (set_attr "mode" "SI")
19632    (set_attr "memory" "both")])
19633
19634 (define_insn "*strmovsi_rex_1"
19635   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19636         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19637    (set (match_operand:DI 0 "register_operand" "=D")
19638         (plus:DI (match_dup 2)
19639                  (const_int 4)))
19640    (set (match_operand:DI 1 "register_operand" "=S")
19641         (plus:DI (match_dup 3)
19642                  (const_int 4)))]
19643   "TARGET_64BIT"
19644   "movs{l|d}"
19645   [(set_attr "type" "str")
19646    (set_attr "mode" "SI")
19647    (set_attr "memory" "both")])
19648
19649 (define_insn "*strmovhi_1"
19650   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19651         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19652    (set (match_operand:SI 0 "register_operand" "=D")
19653         (plus:SI (match_dup 2)
19654                  (const_int 2)))
19655    (set (match_operand:SI 1 "register_operand" "=S")
19656         (plus:SI (match_dup 3)
19657                  (const_int 2)))]
19658   "!TARGET_64BIT"
19659   "movsw"
19660   [(set_attr "type" "str")
19661    (set_attr "memory" "both")
19662    (set_attr "mode" "HI")])
19663
19664 (define_insn "*strmovhi_rex_1"
19665   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19666         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19667    (set (match_operand:DI 0 "register_operand" "=D")
19668         (plus:DI (match_dup 2)
19669                  (const_int 2)))
19670    (set (match_operand:DI 1 "register_operand" "=S")
19671         (plus:DI (match_dup 3)
19672                  (const_int 2)))]
19673   "TARGET_64BIT"
19674   "movsw"
19675   [(set_attr "type" "str")
19676    (set_attr "memory" "both")
19677    (set_attr "mode" "HI")])
19678
19679 (define_insn "*strmovqi_1"
19680   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19681         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19682    (set (match_operand:SI 0 "register_operand" "=D")
19683         (plus:SI (match_dup 2)
19684                  (const_int 1)))
19685    (set (match_operand:SI 1 "register_operand" "=S")
19686         (plus:SI (match_dup 3)
19687                  (const_int 1)))]
19688   "!TARGET_64BIT"
19689   "movsb"
19690   [(set_attr "type" "str")
19691    (set_attr "memory" "both")
19692    (set_attr "mode" "QI")])
19693
19694 (define_insn "*strmovqi_rex_1"
19695   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19696         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19697    (set (match_operand:DI 0 "register_operand" "=D")
19698         (plus:DI (match_dup 2)
19699                  (const_int 1)))
19700    (set (match_operand:DI 1 "register_operand" "=S")
19701         (plus:DI (match_dup 3)
19702                  (const_int 1)))]
19703   "TARGET_64BIT"
19704   "movsb"
19705   [(set_attr "type" "str")
19706    (set_attr "memory" "both")
19707    (set_attr "prefix_rex" "0")
19708    (set_attr "mode" "QI")])
19709
19710 (define_expand "rep_mov"
19711   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19712               (set (match_operand 0 "register_operand" "")
19713                    (match_operand 5 "" ""))
19714               (set (match_operand 2 "register_operand" "")
19715                    (match_operand 6 "" ""))
19716               (set (match_operand 1 "memory_operand" "")
19717                    (match_operand 3 "memory_operand" ""))
19718               (use (match_dup 4))])]
19719   ""
19720   "ix86_current_function_needs_cld = 1;")
19721
19722 (define_insn "*rep_movdi_rex64"
19723   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19724    (set (match_operand:DI 0 "register_operand" "=D")
19725         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19726                             (const_int 3))
19727                  (match_operand:DI 3 "register_operand" "0")))
19728    (set (match_operand:DI 1 "register_operand" "=S")
19729         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19730                  (match_operand:DI 4 "register_operand" "1")))
19731    (set (mem:BLK (match_dup 3))
19732         (mem:BLK (match_dup 4)))
19733    (use (match_dup 5))]
19734   "TARGET_64BIT"
19735   "rep movsq"
19736   [(set_attr "type" "str")
19737    (set_attr "prefix_rep" "1")
19738    (set_attr "memory" "both")
19739    (set_attr "mode" "DI")])
19740
19741 (define_insn "*rep_movsi"
19742   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19743    (set (match_operand:SI 0 "register_operand" "=D")
19744         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19745                             (const_int 2))
19746                  (match_operand:SI 3 "register_operand" "0")))
19747    (set (match_operand:SI 1 "register_operand" "=S")
19748         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19749                  (match_operand:SI 4 "register_operand" "1")))
19750    (set (mem:BLK (match_dup 3))
19751         (mem:BLK (match_dup 4)))
19752    (use (match_dup 5))]
19753   "!TARGET_64BIT"
19754   "rep movs{l|d}"
19755   [(set_attr "type" "str")
19756    (set_attr "prefix_rep" "1")
19757    (set_attr "memory" "both")
19758    (set_attr "mode" "SI")])
19759
19760 (define_insn "*rep_movsi_rex64"
19761   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19762    (set (match_operand:DI 0 "register_operand" "=D")
19763         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19764                             (const_int 2))
19765                  (match_operand:DI 3 "register_operand" "0")))
19766    (set (match_operand:DI 1 "register_operand" "=S")
19767         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19768                  (match_operand:DI 4 "register_operand" "1")))
19769    (set (mem:BLK (match_dup 3))
19770         (mem:BLK (match_dup 4)))
19771    (use (match_dup 5))]
19772   "TARGET_64BIT"
19773   "rep movs{l|d}"
19774   [(set_attr "type" "str")
19775    (set_attr "prefix_rep" "1")
19776    (set_attr "memory" "both")
19777    (set_attr "mode" "SI")])
19778
19779 (define_insn "*rep_movqi"
19780   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19781    (set (match_operand:SI 0 "register_operand" "=D")
19782         (plus:SI (match_operand:SI 3 "register_operand" "0")
19783                  (match_operand:SI 5 "register_operand" "2")))
19784    (set (match_operand:SI 1 "register_operand" "=S")
19785         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19786    (set (mem:BLK (match_dup 3))
19787         (mem:BLK (match_dup 4)))
19788    (use (match_dup 5))]
19789   "!TARGET_64BIT"
19790   "rep movsb"
19791   [(set_attr "type" "str")
19792    (set_attr "prefix_rep" "1")
19793    (set_attr "memory" "both")
19794    (set_attr "mode" "SI")])
19795
19796 (define_insn "*rep_movqi_rex64"
19797   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19798    (set (match_operand:DI 0 "register_operand" "=D")
19799         (plus:DI (match_operand:DI 3 "register_operand" "0")
19800                  (match_operand:DI 5 "register_operand" "2")))
19801    (set (match_operand:DI 1 "register_operand" "=S")
19802         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19803    (set (mem:BLK (match_dup 3))
19804         (mem:BLK (match_dup 4)))
19805    (use (match_dup 5))]
19806   "TARGET_64BIT"
19807   "rep movsb"
19808   [(set_attr "type" "str")
19809    (set_attr "prefix_rep" "1")
19810    (set_attr "memory" "both")
19811    (set_attr "mode" "SI")])
19812
19813 (define_expand "setmemsi"
19814    [(use (match_operand:BLK 0 "memory_operand" ""))
19815     (use (match_operand:SI 1 "nonmemory_operand" ""))
19816     (use (match_operand 2 "const_int_operand" ""))
19817     (use (match_operand 3 "const_int_operand" ""))
19818     (use (match_operand:SI 4 "const_int_operand" ""))
19819     (use (match_operand:SI 5 "const_int_operand" ""))]
19820   ""
19821 {
19822  if (ix86_expand_setmem (operands[0], operands[1],
19823                          operands[2], operands[3],
19824                          operands[4], operands[5]))
19825    DONE;
19826  else
19827    FAIL;
19828 })
19829
19830 (define_expand "setmemdi"
19831    [(use (match_operand:BLK 0 "memory_operand" ""))
19832     (use (match_operand:DI 1 "nonmemory_operand" ""))
19833     (use (match_operand 2 "const_int_operand" ""))
19834     (use (match_operand 3 "const_int_operand" ""))
19835     (use (match_operand 4 "const_int_operand" ""))
19836     (use (match_operand 5 "const_int_operand" ""))]
19837   "TARGET_64BIT"
19838 {
19839  if (ix86_expand_setmem (operands[0], operands[1],
19840                          operands[2], operands[3],
19841                          operands[4], operands[5]))
19842    DONE;
19843  else
19844    FAIL;
19845 })
19846
19847 ;; Most CPUs don't like single string operations
19848 ;; Handle this case here to simplify previous expander.
19849
19850 (define_expand "strset"
19851   [(set (match_operand 1 "memory_operand" "")
19852         (match_operand 2 "register_operand" ""))
19853    (parallel [(set (match_operand 0 "register_operand" "")
19854                    (match_dup 3))
19855               (clobber (reg:CC FLAGS_REG))])]
19856   ""
19857 {
19858   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19859     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19860
19861   /* If .md ever supports :P for Pmode, this can be directly
19862      in the pattern above.  */
19863   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19864                               GEN_INT (GET_MODE_SIZE (GET_MODE
19865                                                       (operands[2]))));
19866   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19867     {
19868       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19869                                       operands[3]));
19870       DONE;
19871     }
19872 })
19873
19874 (define_expand "strset_singleop"
19875   [(parallel [(set (match_operand 1 "memory_operand" "")
19876                    (match_operand 2 "register_operand" ""))
19877               (set (match_operand 0 "register_operand" "")
19878                    (match_operand 3 "" ""))])]
19879   ""
19880   "ix86_current_function_needs_cld = 1;")
19881
19882 (define_insn "*strsetdi_rex_1"
19883   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19884         (match_operand:DI 2 "register_operand" "a"))
19885    (set (match_operand:DI 0 "register_operand" "=D")
19886         (plus:DI (match_dup 1)
19887                  (const_int 8)))]
19888   "TARGET_64BIT"
19889   "stosq"
19890   [(set_attr "type" "str")
19891    (set_attr "memory" "store")
19892    (set_attr "mode" "DI")])
19893
19894 (define_insn "*strsetsi_1"
19895   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19896         (match_operand:SI 2 "register_operand" "a"))
19897    (set (match_operand:SI 0 "register_operand" "=D")
19898         (plus:SI (match_dup 1)
19899                  (const_int 4)))]
19900   "!TARGET_64BIT"
19901   "stos{l|d}"
19902   [(set_attr "type" "str")
19903    (set_attr "memory" "store")
19904    (set_attr "mode" "SI")])
19905
19906 (define_insn "*strsetsi_rex_1"
19907   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19908         (match_operand:SI 2 "register_operand" "a"))
19909    (set (match_operand:DI 0 "register_operand" "=D")
19910         (plus:DI (match_dup 1)
19911                  (const_int 4)))]
19912   "TARGET_64BIT"
19913   "stos{l|d}"
19914   [(set_attr "type" "str")
19915    (set_attr "memory" "store")
19916    (set_attr "mode" "SI")])
19917
19918 (define_insn "*strsethi_1"
19919   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19920         (match_operand:HI 2 "register_operand" "a"))
19921    (set (match_operand:SI 0 "register_operand" "=D")
19922         (plus:SI (match_dup 1)
19923                  (const_int 2)))]
19924   "!TARGET_64BIT"
19925   "stosw"
19926   [(set_attr "type" "str")
19927    (set_attr "memory" "store")
19928    (set_attr "mode" "HI")])
19929
19930 (define_insn "*strsethi_rex_1"
19931   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19932         (match_operand:HI 2 "register_operand" "a"))
19933    (set (match_operand:DI 0 "register_operand" "=D")
19934         (plus:DI (match_dup 1)
19935                  (const_int 2)))]
19936   "TARGET_64BIT"
19937   "stosw"
19938   [(set_attr "type" "str")
19939    (set_attr "memory" "store")
19940    (set_attr "mode" "HI")])
19941
19942 (define_insn "*strsetqi_1"
19943   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19944         (match_operand:QI 2 "register_operand" "a"))
19945    (set (match_operand:SI 0 "register_operand" "=D")
19946         (plus:SI (match_dup 1)
19947                  (const_int 1)))]
19948   "!TARGET_64BIT"
19949   "stosb"
19950   [(set_attr "type" "str")
19951    (set_attr "memory" "store")
19952    (set_attr "mode" "QI")])
19953
19954 (define_insn "*strsetqi_rex_1"
19955   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19956         (match_operand:QI 2 "register_operand" "a"))
19957    (set (match_operand:DI 0 "register_operand" "=D")
19958         (plus:DI (match_dup 1)
19959                  (const_int 1)))]
19960   "TARGET_64BIT"
19961   "stosb"
19962   [(set_attr "type" "str")
19963    (set_attr "memory" "store")
19964    (set_attr "prefix_rex" "0")
19965    (set_attr "mode" "QI")])
19966
19967 (define_expand "rep_stos"
19968   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19969               (set (match_operand 0 "register_operand" "")
19970                    (match_operand 4 "" ""))
19971               (set (match_operand 2 "memory_operand" "") (const_int 0))
19972               (use (match_operand 3 "register_operand" ""))
19973               (use (match_dup 1))])]
19974   ""
19975   "ix86_current_function_needs_cld = 1;")
19976
19977 (define_insn "*rep_stosdi_rex64"
19978   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19979    (set (match_operand:DI 0 "register_operand" "=D")
19980         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19981                             (const_int 3))
19982                  (match_operand:DI 3 "register_operand" "0")))
19983    (set (mem:BLK (match_dup 3))
19984         (const_int 0))
19985    (use (match_operand:DI 2 "register_operand" "a"))
19986    (use (match_dup 4))]
19987   "TARGET_64BIT"
19988   "rep stosq"
19989   [(set_attr "type" "str")
19990    (set_attr "prefix_rep" "1")
19991    (set_attr "memory" "store")
19992    (set_attr "mode" "DI")])
19993
19994 (define_insn "*rep_stossi"
19995   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19996    (set (match_operand:SI 0 "register_operand" "=D")
19997         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19998                             (const_int 2))
19999                  (match_operand:SI 3 "register_operand" "0")))
20000    (set (mem:BLK (match_dup 3))
20001         (const_int 0))
20002    (use (match_operand:SI 2 "register_operand" "a"))
20003    (use (match_dup 4))]
20004   "!TARGET_64BIT"
20005   "rep stos{l|d}"
20006   [(set_attr "type" "str")
20007    (set_attr "prefix_rep" "1")
20008    (set_attr "memory" "store")
20009    (set_attr "mode" "SI")])
20010
20011 (define_insn "*rep_stossi_rex64"
20012   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20013    (set (match_operand:DI 0 "register_operand" "=D")
20014         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20015                             (const_int 2))
20016                  (match_operand:DI 3 "register_operand" "0")))
20017    (set (mem:BLK (match_dup 3))
20018         (const_int 0))
20019    (use (match_operand:SI 2 "register_operand" "a"))
20020    (use (match_dup 4))]
20021   "TARGET_64BIT"
20022   "rep stos{l|d}"
20023   [(set_attr "type" "str")
20024    (set_attr "prefix_rep" "1")
20025    (set_attr "memory" "store")
20026    (set_attr "mode" "SI")])
20027
20028 (define_insn "*rep_stosqi"
20029   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20030    (set (match_operand:SI 0 "register_operand" "=D")
20031         (plus:SI (match_operand:SI 3 "register_operand" "0")
20032                  (match_operand:SI 4 "register_operand" "1")))
20033    (set (mem:BLK (match_dup 3))
20034         (const_int 0))
20035    (use (match_operand:QI 2 "register_operand" "a"))
20036    (use (match_dup 4))]
20037   "!TARGET_64BIT"
20038   "rep stosb"
20039   [(set_attr "type" "str")
20040    (set_attr "prefix_rep" "1")
20041    (set_attr "memory" "store")
20042    (set_attr "mode" "QI")])
20043
20044 (define_insn "*rep_stosqi_rex64"
20045   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20046    (set (match_operand:DI 0 "register_operand" "=D")
20047         (plus:DI (match_operand:DI 3 "register_operand" "0")
20048                  (match_operand:DI 4 "register_operand" "1")))
20049    (set (mem:BLK (match_dup 3))
20050         (const_int 0))
20051    (use (match_operand:QI 2 "register_operand" "a"))
20052    (use (match_dup 4))]
20053   "TARGET_64BIT"
20054   "rep stosb"
20055   [(set_attr "type" "str")
20056    (set_attr "prefix_rep" "1")
20057    (set_attr "memory" "store")
20058    (set_attr "prefix_rex" "0")
20059    (set_attr "mode" "QI")])
20060
20061 (define_expand "cmpstrnsi"
20062   [(set (match_operand:SI 0 "register_operand" "")
20063         (compare:SI (match_operand:BLK 1 "general_operand" "")
20064                     (match_operand:BLK 2 "general_operand" "")))
20065    (use (match_operand 3 "general_operand" ""))
20066    (use (match_operand 4 "immediate_operand" ""))]
20067   ""
20068 {
20069   rtx addr1, addr2, out, outlow, count, countreg, align;
20070
20071   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20072     FAIL;
20073
20074   /* Can't use this if the user has appropriated esi or edi.  */
20075   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20076     FAIL;
20077
20078   out = operands[0];
20079   if (!REG_P (out))
20080     out = gen_reg_rtx (SImode);
20081
20082   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20083   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20084   if (addr1 != XEXP (operands[1], 0))
20085     operands[1] = replace_equiv_address_nv (operands[1], addr1);
20086   if (addr2 != XEXP (operands[2], 0))
20087     operands[2] = replace_equiv_address_nv (operands[2], addr2);
20088
20089   count = operands[3];
20090   countreg = ix86_zero_extend_to_Pmode (count);
20091
20092   /* %%% Iff we are testing strict equality, we can use known alignment
20093      to good advantage.  This may be possible with combine, particularly
20094      once cc0 is dead.  */
20095   align = operands[4];
20096
20097   if (CONST_INT_P (count))
20098     {
20099       if (INTVAL (count) == 0)
20100         {
20101           emit_move_insn (operands[0], const0_rtx);
20102           DONE;
20103         }
20104       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20105                                      operands[1], operands[2]));
20106     }
20107   else
20108     {
20109       if (TARGET_64BIT)
20110         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20111       else
20112         emit_insn (gen_cmpsi_1 (countreg, countreg));
20113       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20114                                   operands[1], operands[2]));
20115     }
20116
20117   outlow = gen_lowpart (QImode, out);
20118   emit_insn (gen_cmpintqi (outlow));
20119   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20120
20121   if (operands[0] != out)
20122     emit_move_insn (operands[0], out);
20123
20124   DONE;
20125 })
20126
20127 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20128
20129 (define_expand "cmpintqi"
20130   [(set (match_dup 1)
20131         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20132    (set (match_dup 2)
20133         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20134    (parallel [(set (match_operand:QI 0 "register_operand" "")
20135                    (minus:QI (match_dup 1)
20136                              (match_dup 2)))
20137               (clobber (reg:CC FLAGS_REG))])]
20138   ""
20139   "operands[1] = gen_reg_rtx (QImode);
20140    operands[2] = gen_reg_rtx (QImode);")
20141
20142 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
20143 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
20144
20145 (define_expand "cmpstrnqi_nz_1"
20146   [(parallel [(set (reg:CC FLAGS_REG)
20147                    (compare:CC (match_operand 4 "memory_operand" "")
20148                                (match_operand 5 "memory_operand" "")))
20149               (use (match_operand 2 "register_operand" ""))
20150               (use (match_operand:SI 3 "immediate_operand" ""))
20151               (clobber (match_operand 0 "register_operand" ""))
20152               (clobber (match_operand 1 "register_operand" ""))
20153               (clobber (match_dup 2))])]
20154   ""
20155   "ix86_current_function_needs_cld = 1;")
20156
20157 (define_insn "*cmpstrnqi_nz_1"
20158   [(set (reg:CC FLAGS_REG)
20159         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20160                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20161    (use (match_operand:SI 6 "register_operand" "2"))
20162    (use (match_operand:SI 3 "immediate_operand" "i"))
20163    (clobber (match_operand:SI 0 "register_operand" "=S"))
20164    (clobber (match_operand:SI 1 "register_operand" "=D"))
20165    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20166   "!TARGET_64BIT"
20167   "repz cmpsb"
20168   [(set_attr "type" "str")
20169    (set_attr "mode" "QI")
20170    (set_attr "prefix_rep" "1")])
20171
20172 (define_insn "*cmpstrnqi_nz_rex_1"
20173   [(set (reg:CC FLAGS_REG)
20174         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20175                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20176    (use (match_operand:DI 6 "register_operand" "2"))
20177    (use (match_operand:SI 3 "immediate_operand" "i"))
20178    (clobber (match_operand:DI 0 "register_operand" "=S"))
20179    (clobber (match_operand:DI 1 "register_operand" "=D"))
20180    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20181   "TARGET_64BIT"
20182   "repz cmpsb"
20183   [(set_attr "type" "str")
20184    (set_attr "mode" "QI")
20185    (set_attr "prefix_rex" "0")
20186    (set_attr "prefix_rep" "1")])
20187
20188 ;; The same, but the count is not known to not be zero.
20189
20190 (define_expand "cmpstrnqi_1"
20191   [(parallel [(set (reg:CC FLAGS_REG)
20192                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20193                                      (const_int 0))
20194                   (compare:CC (match_operand 4 "memory_operand" "")
20195                               (match_operand 5 "memory_operand" ""))
20196                   (const_int 0)))
20197               (use (match_operand:SI 3 "immediate_operand" ""))
20198               (use (reg:CC FLAGS_REG))
20199               (clobber (match_operand 0 "register_operand" ""))
20200               (clobber (match_operand 1 "register_operand" ""))
20201               (clobber (match_dup 2))])]
20202   ""
20203   "ix86_current_function_needs_cld = 1;")
20204
20205 (define_insn "*cmpstrnqi_1"
20206   [(set (reg:CC FLAGS_REG)
20207         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20208                              (const_int 0))
20209           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20210                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20211           (const_int 0)))
20212    (use (match_operand:SI 3 "immediate_operand" "i"))
20213    (use (reg:CC FLAGS_REG))
20214    (clobber (match_operand:SI 0 "register_operand" "=S"))
20215    (clobber (match_operand:SI 1 "register_operand" "=D"))
20216    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20217   "!TARGET_64BIT"
20218   "repz cmpsb"
20219   [(set_attr "type" "str")
20220    (set_attr "mode" "QI")
20221    (set_attr "prefix_rep" "1")])
20222
20223 (define_insn "*cmpstrnqi_rex_1"
20224   [(set (reg:CC FLAGS_REG)
20225         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20226                              (const_int 0))
20227           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20228                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20229           (const_int 0)))
20230    (use (match_operand:SI 3 "immediate_operand" "i"))
20231    (use (reg:CC FLAGS_REG))
20232    (clobber (match_operand:DI 0 "register_operand" "=S"))
20233    (clobber (match_operand:DI 1 "register_operand" "=D"))
20234    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20235   "TARGET_64BIT"
20236   "repz cmpsb"
20237   [(set_attr "type" "str")
20238    (set_attr "mode" "QI")
20239    (set_attr "prefix_rex" "0")
20240    (set_attr "prefix_rep" "1")])
20241
20242 (define_expand "strlensi"
20243   [(set (match_operand:SI 0 "register_operand" "")
20244         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20245                     (match_operand:QI 2 "immediate_operand" "")
20246                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20247   ""
20248 {
20249  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20250    DONE;
20251  else
20252    FAIL;
20253 })
20254
20255 (define_expand "strlendi"
20256   [(set (match_operand:DI 0 "register_operand" "")
20257         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20258                     (match_operand:QI 2 "immediate_operand" "")
20259                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20260   ""
20261 {
20262  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20263    DONE;
20264  else
20265    FAIL;
20266 })
20267
20268 (define_expand "strlenqi_1"
20269   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20270               (clobber (match_operand 1 "register_operand" ""))
20271               (clobber (reg:CC FLAGS_REG))])]
20272   ""
20273   "ix86_current_function_needs_cld = 1;")
20274
20275 (define_insn "*strlenqi_1"
20276   [(set (match_operand:SI 0 "register_operand" "=&c")
20277         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20278                     (match_operand:QI 2 "register_operand" "a")
20279                     (match_operand:SI 3 "immediate_operand" "i")
20280                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20281    (clobber (match_operand:SI 1 "register_operand" "=D"))
20282    (clobber (reg:CC FLAGS_REG))]
20283   "!TARGET_64BIT"
20284   "repnz scasb"
20285   [(set_attr "type" "str")
20286    (set_attr "mode" "QI")
20287    (set_attr "prefix_rep" "1")])
20288
20289 (define_insn "*strlenqi_rex_1"
20290   [(set (match_operand:DI 0 "register_operand" "=&c")
20291         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20292                     (match_operand:QI 2 "register_operand" "a")
20293                     (match_operand:DI 3 "immediate_operand" "i")
20294                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20295    (clobber (match_operand:DI 1 "register_operand" "=D"))
20296    (clobber (reg:CC FLAGS_REG))]
20297   "TARGET_64BIT"
20298   "repnz scasb"
20299   [(set_attr "type" "str")
20300    (set_attr "mode" "QI")
20301    (set_attr "prefix_rex" "0")
20302    (set_attr "prefix_rep" "1")])
20303
20304 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
20305 ;; handled in combine, but it is not currently up to the task.
20306 ;; When used for their truth value, the cmpstrn* expanders generate
20307 ;; code like this:
20308 ;;
20309 ;;   repz cmpsb
20310 ;;   seta       %al
20311 ;;   setb       %dl
20312 ;;   cmpb       %al, %dl
20313 ;;   jcc        label
20314 ;;
20315 ;; The intermediate three instructions are unnecessary.
20316
20317 ;; This one handles cmpstrn*_nz_1...
20318 (define_peephole2
20319   [(parallel[
20320      (set (reg:CC FLAGS_REG)
20321           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20322                       (mem:BLK (match_operand 5 "register_operand" ""))))
20323      (use (match_operand 6 "register_operand" ""))
20324      (use (match_operand:SI 3 "immediate_operand" ""))
20325      (clobber (match_operand 0 "register_operand" ""))
20326      (clobber (match_operand 1 "register_operand" ""))
20327      (clobber (match_operand 2 "register_operand" ""))])
20328    (set (match_operand:QI 7 "register_operand" "")
20329         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20330    (set (match_operand:QI 8 "register_operand" "")
20331         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20332    (set (reg FLAGS_REG)
20333         (compare (match_dup 7) (match_dup 8)))
20334   ]
20335   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20336   [(parallel[
20337      (set (reg:CC FLAGS_REG)
20338           (compare:CC (mem:BLK (match_dup 4))
20339                       (mem:BLK (match_dup 5))))
20340      (use (match_dup 6))
20341      (use (match_dup 3))
20342      (clobber (match_dup 0))
20343      (clobber (match_dup 1))
20344      (clobber (match_dup 2))])]
20345   "")
20346
20347 ;; ...and this one handles cmpstrn*_1.
20348 (define_peephole2
20349   [(parallel[
20350      (set (reg:CC FLAGS_REG)
20351           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20352                                (const_int 0))
20353             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20354                         (mem:BLK (match_operand 5 "register_operand" "")))
20355             (const_int 0)))
20356      (use (match_operand:SI 3 "immediate_operand" ""))
20357      (use (reg:CC FLAGS_REG))
20358      (clobber (match_operand 0 "register_operand" ""))
20359      (clobber (match_operand 1 "register_operand" ""))
20360      (clobber (match_operand 2 "register_operand" ""))])
20361    (set (match_operand:QI 7 "register_operand" "")
20362         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20363    (set (match_operand:QI 8 "register_operand" "")
20364         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20365    (set (reg FLAGS_REG)
20366         (compare (match_dup 7) (match_dup 8)))
20367   ]
20368   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20369   [(parallel[
20370      (set (reg:CC FLAGS_REG)
20371           (if_then_else:CC (ne (match_dup 6)
20372                                (const_int 0))
20373             (compare:CC (mem:BLK (match_dup 4))
20374                         (mem:BLK (match_dup 5)))
20375             (const_int 0)))
20376      (use (match_dup 3))
20377      (use (reg:CC FLAGS_REG))
20378      (clobber (match_dup 0))
20379      (clobber (match_dup 1))
20380      (clobber (match_dup 2))])]
20381   "")
20382
20383
20384 \f
20385 ;; Conditional move instructions.
20386
20387 (define_expand "movdicc"
20388   [(set (match_operand:DI 0 "register_operand" "")
20389         (if_then_else:DI (match_operand 1 "comparison_operator" "")
20390                          (match_operand:DI 2 "general_operand" "")
20391                          (match_operand:DI 3 "general_operand" "")))]
20392   "TARGET_64BIT"
20393   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20394
20395 (define_insn "x86_movdicc_0_m1_rex64"
20396   [(set (match_operand:DI 0 "register_operand" "=r")
20397         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20398           (const_int -1)
20399           (const_int 0)))
20400    (clobber (reg:CC FLAGS_REG))]
20401   "TARGET_64BIT"
20402   "sbb{q}\t%0, %0"
20403   ; Since we don't have the proper number of operands for an alu insn,
20404   ; fill in all the blanks.
20405   [(set_attr "type" "alu")
20406    (set_attr "use_carry" "1")
20407    (set_attr "pent_pair" "pu")
20408    (set_attr "memory" "none")
20409    (set_attr "imm_disp" "false")
20410    (set_attr "mode" "DI")
20411    (set_attr "length_immediate" "0")])
20412
20413 (define_insn "*x86_movdicc_0_m1_se"
20414   [(set (match_operand:DI 0 "register_operand" "=r")
20415         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20416                          (const_int 1)
20417                          (const_int 0)))
20418    (clobber (reg:CC FLAGS_REG))]
20419   ""
20420   "sbb{q}\t%0, %0"
20421   [(set_attr "type" "alu")
20422    (set_attr "use_carry" "1")
20423    (set_attr "pent_pair" "pu")
20424    (set_attr "memory" "none")
20425    (set_attr "imm_disp" "false")
20426    (set_attr "mode" "DI")
20427    (set_attr "length_immediate" "0")])
20428
20429 (define_insn "*movdicc_c_rex64"
20430   [(set (match_operand:DI 0 "register_operand" "=r,r")
20431         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20432                                 [(reg FLAGS_REG) (const_int 0)])
20433                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20434                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20435   "TARGET_64BIT && TARGET_CMOVE
20436    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20437   "@
20438    cmov%O2%C1\t{%2, %0|%0, %2}
20439    cmov%O2%c1\t{%3, %0|%0, %3}"
20440   [(set_attr "type" "icmov")
20441    (set_attr "mode" "DI")])
20442
20443 (define_expand "movsicc"
20444   [(set (match_operand:SI 0 "register_operand" "")
20445         (if_then_else:SI (match_operand 1 "comparison_operator" "")
20446                          (match_operand:SI 2 "general_operand" "")
20447                          (match_operand:SI 3 "general_operand" "")))]
20448   ""
20449   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20450
20451 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20452 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20453 ;; So just document what we're doing explicitly.
20454
20455 (define_insn "x86_movsicc_0_m1"
20456   [(set (match_operand:SI 0 "register_operand" "=r")
20457         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20458           (const_int -1)
20459           (const_int 0)))
20460    (clobber (reg:CC FLAGS_REG))]
20461   ""
20462   "sbb{l}\t%0, %0"
20463   ; Since we don't have the proper number of operands for an alu insn,
20464   ; fill in all the blanks.
20465   [(set_attr "type" "alu")
20466    (set_attr "use_carry" "1")
20467    (set_attr "pent_pair" "pu")
20468    (set_attr "memory" "none")
20469    (set_attr "imm_disp" "false")
20470    (set_attr "mode" "SI")
20471    (set_attr "length_immediate" "0")])
20472
20473 (define_insn "*x86_movsicc_0_m1_se"
20474   [(set (match_operand:SI 0 "register_operand" "=r")
20475         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20476                          (const_int 1)
20477                          (const_int 0)))
20478    (clobber (reg:CC FLAGS_REG))]
20479   ""
20480   "sbb{l}\t%0, %0"
20481   [(set_attr "type" "alu")
20482    (set_attr "use_carry" "1")
20483    (set_attr "pent_pair" "pu")
20484    (set_attr "memory" "none")
20485    (set_attr "imm_disp" "false")
20486    (set_attr "mode" "SI")
20487    (set_attr "length_immediate" "0")])
20488
20489 (define_insn "*movsicc_noc"
20490   [(set (match_operand:SI 0 "register_operand" "=r,r")
20491         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20492                                 [(reg FLAGS_REG) (const_int 0)])
20493                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20494                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20495   "TARGET_CMOVE
20496    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20497   "@
20498    cmov%O2%C1\t{%2, %0|%0, %2}
20499    cmov%O2%c1\t{%3, %0|%0, %3}"
20500   [(set_attr "type" "icmov")
20501    (set_attr "mode" "SI")])
20502
20503 (define_expand "movhicc"
20504   [(set (match_operand:HI 0 "register_operand" "")
20505         (if_then_else:HI (match_operand 1 "comparison_operator" "")
20506                          (match_operand:HI 2 "general_operand" "")
20507                          (match_operand:HI 3 "general_operand" "")))]
20508   "TARGET_HIMODE_MATH"
20509   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20510
20511 (define_insn "*movhicc_noc"
20512   [(set (match_operand:HI 0 "register_operand" "=r,r")
20513         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20514                                 [(reg FLAGS_REG) (const_int 0)])
20515                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20516                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20517   "TARGET_CMOVE
20518    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20519   "@
20520    cmov%O2%C1\t{%2, %0|%0, %2}
20521    cmov%O2%c1\t{%3, %0|%0, %3}"
20522   [(set_attr "type" "icmov")
20523    (set_attr "mode" "HI")])
20524
20525 (define_expand "movqicc"
20526   [(set (match_operand:QI 0 "register_operand" "")
20527         (if_then_else:QI (match_operand 1 "comparison_operator" "")
20528                          (match_operand:QI 2 "general_operand" "")
20529                          (match_operand:QI 3 "general_operand" "")))]
20530   "TARGET_QIMODE_MATH"
20531   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20532
20533 (define_insn_and_split "*movqicc_noc"
20534   [(set (match_operand:QI 0 "register_operand" "=r,r")
20535         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20536                                 [(match_operand 4 "flags_reg_operand" "")
20537                                  (const_int 0)])
20538                       (match_operand:QI 2 "register_operand" "r,0")
20539                       (match_operand:QI 3 "register_operand" "0,r")))]
20540   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20541   "#"
20542   "&& reload_completed"
20543   [(set (match_dup 0)
20544         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20545                       (match_dup 2)
20546                       (match_dup 3)))]
20547   "operands[0] = gen_lowpart (SImode, operands[0]);
20548    operands[2] = gen_lowpart (SImode, operands[2]);
20549    operands[3] = gen_lowpart (SImode, operands[3]);"
20550   [(set_attr "type" "icmov")
20551    (set_attr "mode" "SI")])
20552
20553 (define_expand "mov<mode>cc"
20554   [(set (match_operand:X87MODEF 0 "register_operand" "")
20555         (if_then_else:X87MODEF
20556           (match_operand 1 "ix86_fp_comparison_operator" "")
20557           (match_operand:X87MODEF 2 "register_operand" "")
20558           (match_operand:X87MODEF 3 "register_operand" "")))]
20559   "(TARGET_80387 && TARGET_CMOVE)
20560    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20561   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20562
20563 (define_insn "*movsfcc_1_387"
20564   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20565         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20566                                 [(reg FLAGS_REG) (const_int 0)])
20567                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20568                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20569   "TARGET_80387 && TARGET_CMOVE
20570    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20571   "@
20572    fcmov%F1\t{%2, %0|%0, %2}
20573    fcmov%f1\t{%3, %0|%0, %3}
20574    cmov%O2%C1\t{%2, %0|%0, %2}
20575    cmov%O2%c1\t{%3, %0|%0, %3}"
20576   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20577    (set_attr "mode" "SF,SF,SI,SI")])
20578
20579 (define_insn "*movdfcc_1"
20580   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20581         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20582                                 [(reg FLAGS_REG) (const_int 0)])
20583                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20584                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20585   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20586    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20587   "@
20588    fcmov%F1\t{%2, %0|%0, %2}
20589    fcmov%f1\t{%3, %0|%0, %3}
20590    #
20591    #"
20592   [(set_attr "type" "fcmov,fcmov,multi,multi")
20593    (set_attr "mode" "DF")])
20594
20595 (define_insn "*movdfcc_1_rex64"
20596   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20597         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20598                                 [(reg FLAGS_REG) (const_int 0)])
20599                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20600                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20601   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20602    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20603   "@
20604    fcmov%F1\t{%2, %0|%0, %2}
20605    fcmov%f1\t{%3, %0|%0, %3}
20606    cmov%O2%C1\t{%2, %0|%0, %2}
20607    cmov%O2%c1\t{%3, %0|%0, %3}"
20608   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20609    (set_attr "mode" "DF")])
20610
20611 (define_split
20612   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20613         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20614                                 [(match_operand 4 "flags_reg_operand" "")
20615                                  (const_int 0)])
20616                       (match_operand:DF 2 "nonimmediate_operand" "")
20617                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20618   "!TARGET_64BIT && reload_completed"
20619   [(set (match_dup 2)
20620         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20621                       (match_dup 5)
20622                       (match_dup 6)))
20623    (set (match_dup 3)
20624         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20625                       (match_dup 7)
20626                       (match_dup 8)))]
20627   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20628    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20629
20630 (define_insn "*movxfcc_1"
20631   [(set (match_operand:XF 0 "register_operand" "=f,f")
20632         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20633                                 [(reg FLAGS_REG) (const_int 0)])
20634                       (match_operand:XF 2 "register_operand" "f,0")
20635                       (match_operand:XF 3 "register_operand" "0,f")))]
20636   "TARGET_80387 && TARGET_CMOVE"
20637   "@
20638    fcmov%F1\t{%2, %0|%0, %2}
20639    fcmov%f1\t{%3, %0|%0, %3}"
20640   [(set_attr "type" "fcmov")
20641    (set_attr "mode" "XF")])
20642
20643 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20644 ;; the scalar versions to have only XMM registers as operands.
20645
20646 ;; SSE5 conditional move
20647 (define_insn "*sse5_pcmov_<mode>"
20648   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20649         (if_then_else:MODEF
20650           (match_operand:MODEF 1 "register_operand" "x,0")
20651           (match_operand:MODEF 2 "register_operand" "0,x")
20652           (match_operand:MODEF 3 "register_operand" "x,x")))]
20653   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20654   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20655   [(set_attr "type" "sse4arg")])
20656
20657 ;; These versions of the min/max patterns are intentionally ignorant of
20658 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20659 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20660 ;; are undefined in this condition, we're certain this is correct.
20661
20662 (define_insn "*avx_<code><mode>3"
20663   [(set (match_operand:MODEF 0 "register_operand" "=x")
20664         (smaxmin:MODEF
20665           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20666           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20667   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20668   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20669   [(set_attr "type" "sseadd")
20670    (set_attr "prefix" "vex")
20671    (set_attr "mode" "<MODE>")])
20672
20673 (define_insn "<code><mode>3"
20674   [(set (match_operand:MODEF 0 "register_operand" "=x")
20675         (smaxmin:MODEF
20676           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20677           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20678   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20679   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20680   [(set_attr "type" "sseadd")
20681    (set_attr "mode" "<MODE>")])
20682
20683 ;; These versions of the min/max patterns implement exactly the operations
20684 ;;   min = (op1 < op2 ? op1 : op2)
20685 ;;   max = (!(op1 < op2) ? op1 : op2)
20686 ;; Their operands are not commutative, and thus they may be used in the
20687 ;; presence of -0.0 and NaN.
20688
20689 (define_insn "*avx_ieee_smin<mode>3"
20690   [(set (match_operand:MODEF 0 "register_operand" "=x")
20691         (unspec:MODEF
20692           [(match_operand:MODEF 1 "register_operand" "x")
20693            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20694          UNSPEC_IEEE_MIN))]
20695   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20696   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20697   [(set_attr "type" "sseadd")
20698    (set_attr "prefix" "vex")
20699    (set_attr "mode" "<MODE>")])
20700
20701 (define_insn "*ieee_smin<mode>3"
20702   [(set (match_operand:MODEF 0 "register_operand" "=x")
20703         (unspec:MODEF
20704           [(match_operand:MODEF 1 "register_operand" "0")
20705            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20706          UNSPEC_IEEE_MIN))]
20707   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20708   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20709   [(set_attr "type" "sseadd")
20710    (set_attr "mode" "<MODE>")])
20711
20712 (define_insn "*avx_ieee_smax<mode>3"
20713   [(set (match_operand:MODEF 0 "register_operand" "=x")
20714         (unspec:MODEF
20715           [(match_operand:MODEF 1 "register_operand" "0")
20716            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20717          UNSPEC_IEEE_MAX))]
20718   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20719   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20720   [(set_attr "type" "sseadd")
20721    (set_attr "prefix" "vex")
20722    (set_attr "mode" "<MODE>")])
20723
20724 (define_insn "*ieee_smax<mode>3"
20725   [(set (match_operand:MODEF 0 "register_operand" "=x")
20726         (unspec:MODEF
20727           [(match_operand:MODEF 1 "register_operand" "0")
20728            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20729          UNSPEC_IEEE_MAX))]
20730   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20731   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20732   [(set_attr "type" "sseadd")
20733    (set_attr "mode" "<MODE>")])
20734
20735 ;; Make two stack loads independent:
20736 ;;   fld aa              fld aa
20737 ;;   fld %st(0)     ->   fld bb
20738 ;;   fmul bb             fmul %st(1), %st
20739 ;;
20740 ;; Actually we only match the last two instructions for simplicity.
20741 (define_peephole2
20742   [(set (match_operand 0 "fp_register_operand" "")
20743         (match_operand 1 "fp_register_operand" ""))
20744    (set (match_dup 0)
20745         (match_operator 2 "binary_fp_operator"
20746            [(match_dup 0)
20747             (match_operand 3 "memory_operand" "")]))]
20748   "REGNO (operands[0]) != REGNO (operands[1])"
20749   [(set (match_dup 0) (match_dup 3))
20750    (set (match_dup 0) (match_dup 4))]
20751
20752   ;; The % modifier is not operational anymore in peephole2's, so we have to
20753   ;; swap the operands manually in the case of addition and multiplication.
20754   "if (COMMUTATIVE_ARITH_P (operands[2]))
20755      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20756                                  operands[0], operands[1]);
20757    else
20758      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20759                                  operands[1], operands[0]);")
20760
20761 ;; Conditional addition patterns
20762 (define_expand "add<mode>cc"
20763   [(match_operand:SWI 0 "register_operand" "")
20764    (match_operand 1 "comparison_operator" "")
20765    (match_operand:SWI 2 "register_operand" "")
20766    (match_operand:SWI 3 "const_int_operand" "")]
20767   ""
20768   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20769
20770 \f
20771 ;; Misc patterns (?)
20772
20773 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20774 ;; Otherwise there will be nothing to keep
20775 ;;
20776 ;; [(set (reg ebp) (reg esp))]
20777 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20778 ;;  (clobber (eflags)]
20779 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20780 ;;
20781 ;; in proper program order.
20782 (define_insn "pro_epilogue_adjust_stack_1"
20783   [(set (match_operand:SI 0 "register_operand" "=r,r")
20784         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20785                  (match_operand:SI 2 "immediate_operand" "i,i")))
20786    (clobber (reg:CC FLAGS_REG))
20787    (clobber (mem:BLK (scratch)))]
20788   "!TARGET_64BIT"
20789 {
20790   switch (get_attr_type (insn))
20791     {
20792     case TYPE_IMOV:
20793       return "mov{l}\t{%1, %0|%0, %1}";
20794
20795     case TYPE_ALU:
20796       if (CONST_INT_P (operands[2])
20797           && (INTVAL (operands[2]) == 128
20798               || (INTVAL (operands[2]) < 0
20799                   && INTVAL (operands[2]) != -128)))
20800         {
20801           operands[2] = GEN_INT (-INTVAL (operands[2]));
20802           return "sub{l}\t{%2, %0|%0, %2}";
20803         }
20804       return "add{l}\t{%2, %0|%0, %2}";
20805
20806     case TYPE_LEA:
20807       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20808       return "lea{l}\t{%a2, %0|%0, %a2}";
20809
20810     default:
20811       gcc_unreachable ();
20812     }
20813 }
20814   [(set (attr "type")
20815         (cond [(and (eq_attr "alternative" "0") 
20816                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20817                  (const_string "alu")
20818                (match_operand:SI 2 "const0_operand" "")
20819                  (const_string "imov")
20820               ]
20821               (const_string "lea")))
20822    (set (attr "length_immediate")
20823         (cond [(eq_attr "type" "imov")
20824                  (const_string "0")
20825                (and (eq_attr "type" "alu")
20826                     (match_operand 2 "const128_operand" ""))
20827                  (const_string "1")
20828               ]
20829               (const_string "*")))
20830    (set_attr "mode" "SI")])
20831
20832 (define_insn "pro_epilogue_adjust_stack_rex64"
20833   [(set (match_operand:DI 0 "register_operand" "=r,r")
20834         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20835                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20836    (clobber (reg:CC FLAGS_REG))
20837    (clobber (mem:BLK (scratch)))]
20838   "TARGET_64BIT"
20839 {
20840   switch (get_attr_type (insn))
20841     {
20842     case TYPE_IMOV:
20843       return "mov{q}\t{%1, %0|%0, %1}";
20844
20845     case TYPE_ALU:
20846       if (CONST_INT_P (operands[2])
20847           /* Avoid overflows.  */
20848           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20849           && (INTVAL (operands[2]) == 128
20850               || (INTVAL (operands[2]) < 0
20851                   && INTVAL (operands[2]) != -128)))
20852         {
20853           operands[2] = GEN_INT (-INTVAL (operands[2]));
20854           return "sub{q}\t{%2, %0|%0, %2}";
20855         }
20856       return "add{q}\t{%2, %0|%0, %2}";
20857
20858     case TYPE_LEA:
20859       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20860       return "lea{q}\t{%a2, %0|%0, %a2}";
20861
20862     default:
20863       gcc_unreachable ();
20864     }
20865 }
20866   [(set (attr "type")
20867         (cond [(and (eq_attr "alternative" "0")
20868                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20869                  (const_string "alu")
20870                (match_operand:DI 2 "const0_operand" "")
20871                  (const_string "imov")
20872               ]
20873               (const_string "lea")))
20874    (set (attr "length_immediate")
20875         (cond [(eq_attr "type" "imov")
20876                  (const_string "0")
20877                (and (eq_attr "type" "alu")
20878                     (match_operand 2 "const128_operand" ""))
20879                  (const_string "1")
20880               ]
20881               (const_string "*")))
20882    (set_attr "mode" "DI")])
20883
20884 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20885   [(set (match_operand:DI 0 "register_operand" "=r,r")
20886         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20887                  (match_operand:DI 3 "immediate_operand" "i,i")))
20888    (use (match_operand:DI 2 "register_operand" "r,r"))
20889    (clobber (reg:CC FLAGS_REG))
20890    (clobber (mem:BLK (scratch)))]
20891   "TARGET_64BIT"
20892 {
20893   switch (get_attr_type (insn))
20894     {
20895     case TYPE_ALU:
20896       return "add{q}\t{%2, %0|%0, %2}";
20897
20898     case TYPE_LEA:
20899       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20900       return "lea{q}\t{%a2, %0|%0, %a2}";
20901
20902     default:
20903       gcc_unreachable ();
20904     }
20905 }
20906   [(set_attr "type" "alu,lea")
20907    (set_attr "mode" "DI")])
20908
20909 (define_insn "allocate_stack_worker_32"
20910   [(set (match_operand:SI 0 "register_operand" "=a")
20911         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20912                             UNSPECV_STACK_PROBE))
20913    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20914    (clobber (reg:CC FLAGS_REG))]
20915   "!TARGET_64BIT && TARGET_STACK_PROBE"
20916   "call\t___chkstk"
20917   [(set_attr "type" "multi")
20918    (set_attr "length" "5")])
20919
20920 (define_insn "allocate_stack_worker_64"
20921   [(set (match_operand:DI 0 "register_operand" "=a")
20922         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20923                             UNSPECV_STACK_PROBE))
20924    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20925    (clobber (reg:DI R10_REG))
20926    (clobber (reg:DI R11_REG))
20927    (clobber (reg:CC FLAGS_REG))]
20928   "TARGET_64BIT && TARGET_STACK_PROBE"
20929   "call\t___chkstk"
20930   [(set_attr "type" "multi")
20931    (set_attr "length" "5")])
20932
20933 (define_expand "allocate_stack"
20934   [(match_operand 0 "register_operand" "")
20935    (match_operand 1 "general_operand" "")]
20936   "TARGET_STACK_PROBE"
20937 {
20938   rtx x;
20939
20940 #ifndef CHECK_STACK_LIMIT
20941 #define CHECK_STACK_LIMIT 0
20942 #endif
20943
20944   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20945       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20946     {
20947       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20948                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20949       if (x != stack_pointer_rtx)
20950         emit_move_insn (stack_pointer_rtx, x);
20951     }
20952   else
20953     {
20954       x = copy_to_mode_reg (Pmode, operands[1]);
20955       if (TARGET_64BIT)
20956         x = gen_allocate_stack_worker_64 (x, x);
20957       else
20958         x = gen_allocate_stack_worker_32 (x, x);
20959       emit_insn (x);
20960     }
20961
20962   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20963   DONE;
20964 })
20965
20966 (define_expand "builtin_setjmp_receiver"
20967   [(label_ref (match_operand 0 "" ""))]
20968   "!TARGET_64BIT && flag_pic"
20969 {
20970 #if TARGET_MACHO
20971   if (TARGET_MACHO)
20972     {
20973       rtx xops[3];
20974       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20975       rtx label_rtx = gen_label_rtx ();
20976       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20977       xops[0] = xops[1] = picreg;
20978       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20979       ix86_expand_binary_operator (MINUS, SImode, xops);
20980     }
20981   else
20982 #endif
20983     emit_insn (gen_set_got (pic_offset_table_rtx));
20984   DONE;
20985 })
20986 \f
20987 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20988
20989 (define_split
20990   [(set (match_operand 0 "register_operand" "")
20991         (match_operator 3 "promotable_binary_operator"
20992            [(match_operand 1 "register_operand" "")
20993             (match_operand 2 "aligned_operand" "")]))
20994    (clobber (reg:CC FLAGS_REG))]
20995   "! TARGET_PARTIAL_REG_STALL && reload_completed
20996    && ((GET_MODE (operands[0]) == HImode
20997         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20998             /* ??? next two lines just !satisfies_constraint_K (...) */
20999             || !CONST_INT_P (operands[2])
21000             || satisfies_constraint_K (operands[2])))
21001        || (GET_MODE (operands[0]) == QImode
21002            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21003   [(parallel [(set (match_dup 0)
21004                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21005               (clobber (reg:CC FLAGS_REG))])]
21006   "operands[0] = gen_lowpart (SImode, operands[0]);
21007    operands[1] = gen_lowpart (SImode, operands[1]);
21008    if (GET_CODE (operands[3]) != ASHIFT)
21009      operands[2] = gen_lowpart (SImode, operands[2]);
21010    PUT_MODE (operands[3], SImode);")
21011
21012 ; Promote the QImode tests, as i386 has encoding of the AND
21013 ; instruction with 32-bit sign-extended immediate and thus the
21014 ; instruction size is unchanged, except in the %eax case for
21015 ; which it is increased by one byte, hence the ! optimize_size.
21016 (define_split
21017   [(set (match_operand 0 "flags_reg_operand" "")
21018         (match_operator 2 "compare_operator"
21019           [(and (match_operand 3 "aligned_operand" "")
21020                 (match_operand 4 "const_int_operand" ""))
21021            (const_int 0)]))
21022    (set (match_operand 1 "register_operand" "")
21023         (and (match_dup 3) (match_dup 4)))]
21024   "! TARGET_PARTIAL_REG_STALL && reload_completed
21025    && optimize_insn_for_speed_p ()
21026    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21027        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21028    /* Ensure that the operand will remain sign-extended immediate.  */
21029    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21030   [(parallel [(set (match_dup 0)
21031                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21032                                     (const_int 0)]))
21033               (set (match_dup 1)
21034                    (and:SI (match_dup 3) (match_dup 4)))])]
21035 {
21036   operands[4]
21037     = gen_int_mode (INTVAL (operands[4])
21038                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21039   operands[1] = gen_lowpart (SImode, operands[1]);
21040   operands[3] = gen_lowpart (SImode, operands[3]);
21041 })
21042
21043 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21044 ; the TEST instruction with 32-bit sign-extended immediate and thus
21045 ; the instruction size would at least double, which is not what we
21046 ; want even with ! optimize_size.
21047 (define_split
21048   [(set (match_operand 0 "flags_reg_operand" "")
21049         (match_operator 1 "compare_operator"
21050           [(and (match_operand:HI 2 "aligned_operand" "")
21051                 (match_operand:HI 3 "const_int_operand" ""))
21052            (const_int 0)]))]
21053   "! TARGET_PARTIAL_REG_STALL && reload_completed
21054    && ! TARGET_FAST_PREFIX
21055    && optimize_insn_for_speed_p ()
21056    /* Ensure that the operand will remain sign-extended immediate.  */
21057    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21058   [(set (match_dup 0)
21059         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21060                          (const_int 0)]))]
21061 {
21062   operands[3]
21063     = gen_int_mode (INTVAL (operands[3])
21064                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21065   operands[2] = gen_lowpart (SImode, operands[2]);
21066 })
21067
21068 (define_split
21069   [(set (match_operand 0 "register_operand" "")
21070         (neg (match_operand 1 "register_operand" "")))
21071    (clobber (reg:CC FLAGS_REG))]
21072   "! TARGET_PARTIAL_REG_STALL && reload_completed
21073    && (GET_MODE (operands[0]) == HImode
21074        || (GET_MODE (operands[0]) == QImode
21075            && (TARGET_PROMOTE_QImode
21076                || optimize_insn_for_size_p ())))"
21077   [(parallel [(set (match_dup 0)
21078                    (neg:SI (match_dup 1)))
21079               (clobber (reg:CC FLAGS_REG))])]
21080   "operands[0] = gen_lowpart (SImode, operands[0]);
21081    operands[1] = gen_lowpart (SImode, operands[1]);")
21082
21083 (define_split
21084   [(set (match_operand 0 "register_operand" "")
21085         (not (match_operand 1 "register_operand" "")))]
21086   "! TARGET_PARTIAL_REG_STALL && reload_completed
21087    && (GET_MODE (operands[0]) == HImode
21088        || (GET_MODE (operands[0]) == QImode
21089            && (TARGET_PROMOTE_QImode
21090                || optimize_insn_for_size_p ())))"
21091   [(set (match_dup 0)
21092         (not:SI (match_dup 1)))]
21093   "operands[0] = gen_lowpart (SImode, operands[0]);
21094    operands[1] = gen_lowpart (SImode, operands[1]);")
21095
21096 (define_split
21097   [(set (match_operand 0 "register_operand" "")
21098         (if_then_else (match_operator 1 "comparison_operator"
21099                                 [(reg FLAGS_REG) (const_int 0)])
21100                       (match_operand 2 "register_operand" "")
21101                       (match_operand 3 "register_operand" "")))]
21102   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21103    && (GET_MODE (operands[0]) == HImode
21104        || (GET_MODE (operands[0]) == QImode
21105            && (TARGET_PROMOTE_QImode
21106                || optimize_insn_for_size_p ())))"
21107   [(set (match_dup 0)
21108         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21109   "operands[0] = gen_lowpart (SImode, operands[0]);
21110    operands[2] = gen_lowpart (SImode, operands[2]);
21111    operands[3] = gen_lowpart (SImode, operands[3]);")
21112
21113 \f
21114 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
21115 ;; transform a complex memory operation into two memory to register operations.
21116
21117 ;; Don't push memory operands
21118 (define_peephole2
21119   [(set (match_operand:SI 0 "push_operand" "")
21120         (match_operand:SI 1 "memory_operand" ""))
21121    (match_scratch:SI 2 "r")]
21122   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21123    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21124   [(set (match_dup 2) (match_dup 1))
21125    (set (match_dup 0) (match_dup 2))]
21126   "")
21127
21128 (define_peephole2
21129   [(set (match_operand:DI 0 "push_operand" "")
21130         (match_operand:DI 1 "memory_operand" ""))
21131    (match_scratch:DI 2 "r")]
21132   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21133    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21134   [(set (match_dup 2) (match_dup 1))
21135    (set (match_dup 0) (match_dup 2))]
21136   "")
21137
21138 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21139 ;; SImode pushes.
21140 (define_peephole2
21141   [(set (match_operand:SF 0 "push_operand" "")
21142         (match_operand:SF 1 "memory_operand" ""))
21143    (match_scratch:SF 2 "r")]
21144   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21145    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21146   [(set (match_dup 2) (match_dup 1))
21147    (set (match_dup 0) (match_dup 2))]
21148   "")
21149
21150 (define_peephole2
21151   [(set (match_operand:HI 0 "push_operand" "")
21152         (match_operand:HI 1 "memory_operand" ""))
21153    (match_scratch:HI 2 "r")]
21154   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21155    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21156   [(set (match_dup 2) (match_dup 1))
21157    (set (match_dup 0) (match_dup 2))]
21158   "")
21159
21160 (define_peephole2
21161   [(set (match_operand:QI 0 "push_operand" "")
21162         (match_operand:QI 1 "memory_operand" ""))
21163    (match_scratch:QI 2 "q")]
21164   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21165    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21166   [(set (match_dup 2) (match_dup 1))
21167    (set (match_dup 0) (match_dup 2))]
21168   "")
21169
21170 ;; Don't move an immediate directly to memory when the instruction
21171 ;; gets too big.
21172 (define_peephole2
21173   [(match_scratch:SI 1 "r")
21174    (set (match_operand:SI 0 "memory_operand" "")
21175         (const_int 0))]
21176   "optimize_insn_for_speed_p ()
21177    && ! TARGET_USE_MOV0
21178    && TARGET_SPLIT_LONG_MOVES
21179    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21180    && peep2_regno_dead_p (0, FLAGS_REG)"
21181   [(parallel [(set (match_dup 1) (const_int 0))
21182               (clobber (reg:CC FLAGS_REG))])
21183    (set (match_dup 0) (match_dup 1))]
21184   "")
21185
21186 (define_peephole2
21187   [(match_scratch:HI 1 "r")
21188    (set (match_operand:HI 0 "memory_operand" "")
21189         (const_int 0))]
21190   "optimize_insn_for_speed_p ()
21191    && ! TARGET_USE_MOV0
21192    && TARGET_SPLIT_LONG_MOVES
21193    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21194    && peep2_regno_dead_p (0, FLAGS_REG)"
21195   [(parallel [(set (match_dup 2) (const_int 0))
21196               (clobber (reg:CC FLAGS_REG))])
21197    (set (match_dup 0) (match_dup 1))]
21198   "operands[2] = gen_lowpart (SImode, operands[1]);")
21199
21200 (define_peephole2
21201   [(match_scratch:QI 1 "q")
21202    (set (match_operand:QI 0 "memory_operand" "")
21203         (const_int 0))]
21204   "optimize_insn_for_speed_p ()
21205    && ! TARGET_USE_MOV0
21206    && TARGET_SPLIT_LONG_MOVES
21207    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21208    && peep2_regno_dead_p (0, FLAGS_REG)"
21209   [(parallel [(set (match_dup 2) (const_int 0))
21210               (clobber (reg:CC FLAGS_REG))])
21211    (set (match_dup 0) (match_dup 1))]
21212   "operands[2] = gen_lowpart (SImode, operands[1]);")
21213
21214 (define_peephole2
21215   [(match_scratch:SI 2 "r")
21216    (set (match_operand:SI 0 "memory_operand" "")
21217         (match_operand:SI 1 "immediate_operand" ""))]
21218   "optimize_insn_for_speed_p ()
21219    && TARGET_SPLIT_LONG_MOVES
21220    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21221   [(set (match_dup 2) (match_dup 1))
21222    (set (match_dup 0) (match_dup 2))]
21223   "")
21224
21225 (define_peephole2
21226   [(match_scratch:HI 2 "r")
21227    (set (match_operand:HI 0 "memory_operand" "")
21228         (match_operand:HI 1 "immediate_operand" ""))]
21229   "optimize_insn_for_speed_p ()
21230    && TARGET_SPLIT_LONG_MOVES
21231    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21232   [(set (match_dup 2) (match_dup 1))
21233    (set (match_dup 0) (match_dup 2))]
21234   "")
21235
21236 (define_peephole2
21237   [(match_scratch:QI 2 "q")
21238    (set (match_operand:QI 0 "memory_operand" "")
21239         (match_operand:QI 1 "immediate_operand" ""))]
21240   "optimize_insn_for_speed_p ()
21241    && TARGET_SPLIT_LONG_MOVES
21242    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21243   [(set (match_dup 2) (match_dup 1))
21244    (set (match_dup 0) (match_dup 2))]
21245   "")
21246
21247 ;; Don't compare memory with zero, load and use a test instead.
21248 (define_peephole2
21249   [(set (match_operand 0 "flags_reg_operand" "")
21250         (match_operator 1 "compare_operator"
21251           [(match_operand:SI 2 "memory_operand" "")
21252            (const_int 0)]))
21253    (match_scratch:SI 3 "r")]
21254   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21255   [(set (match_dup 3) (match_dup 2))
21256    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21257   "")
21258
21259 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21260 ;; Don't split NOTs with a displacement operand, because resulting XOR
21261 ;; will not be pairable anyway.
21262 ;;
21263 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21264 ;; represented using a modRM byte.  The XOR replacement is long decoded,
21265 ;; so this split helps here as well.
21266 ;;
21267 ;; Note: Can't do this as a regular split because we can't get proper
21268 ;; lifetime information then.
21269
21270 (define_peephole2
21271   [(set (match_operand:SI 0 "nonimmediate_operand" "")
21272         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21273   "optimize_insn_for_speed_p ()
21274    && ((TARGET_NOT_UNPAIRABLE
21275         && (!MEM_P (operands[0])
21276             || !memory_displacement_operand (operands[0], SImode)))
21277        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21278    && peep2_regno_dead_p (0, FLAGS_REG)"
21279   [(parallel [(set (match_dup 0)
21280                    (xor:SI (match_dup 1) (const_int -1)))
21281               (clobber (reg:CC FLAGS_REG))])]
21282   "")
21283
21284 (define_peephole2
21285   [(set (match_operand:HI 0 "nonimmediate_operand" "")
21286         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21287   "optimize_insn_for_speed_p ()
21288    && ((TARGET_NOT_UNPAIRABLE
21289         && (!MEM_P (operands[0])
21290             || !memory_displacement_operand (operands[0], HImode)))
21291        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21292    && peep2_regno_dead_p (0, FLAGS_REG)"
21293   [(parallel [(set (match_dup 0)
21294                    (xor:HI (match_dup 1) (const_int -1)))
21295               (clobber (reg:CC FLAGS_REG))])]
21296   "")
21297
21298 (define_peephole2
21299   [(set (match_operand:QI 0 "nonimmediate_operand" "")
21300         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21301   "optimize_insn_for_speed_p ()
21302    && ((TARGET_NOT_UNPAIRABLE
21303         && (!MEM_P (operands[0])
21304             || !memory_displacement_operand (operands[0], QImode)))
21305        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21306    && peep2_regno_dead_p (0, FLAGS_REG)"
21307   [(parallel [(set (match_dup 0)
21308                    (xor:QI (match_dup 1) (const_int -1)))
21309               (clobber (reg:CC FLAGS_REG))])]
21310   "")
21311
21312 ;; Non pairable "test imm, reg" instructions can be translated to
21313 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
21314 ;; byte opcode instead of two, have a short form for byte operands),
21315 ;; so do it for other CPUs as well.  Given that the value was dead,
21316 ;; this should not create any new dependencies.  Pass on the sub-word
21317 ;; versions if we're concerned about partial register stalls.
21318
21319 (define_peephole2
21320   [(set (match_operand 0 "flags_reg_operand" "")
21321         (match_operator 1 "compare_operator"
21322           [(and:SI (match_operand:SI 2 "register_operand" "")
21323                    (match_operand:SI 3 "immediate_operand" ""))
21324            (const_int 0)]))]
21325   "ix86_match_ccmode (insn, CCNOmode)
21326    && (true_regnum (operands[2]) != AX_REG
21327        || satisfies_constraint_K (operands[3]))
21328    && peep2_reg_dead_p (1, operands[2])"
21329   [(parallel
21330      [(set (match_dup 0)
21331            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21332                             (const_int 0)]))
21333       (set (match_dup 2)
21334            (and:SI (match_dup 2) (match_dup 3)))])]
21335   "")
21336
21337 ;; We don't need to handle HImode case, because it will be promoted to SImode
21338 ;; on ! TARGET_PARTIAL_REG_STALL
21339
21340 (define_peephole2
21341   [(set (match_operand 0 "flags_reg_operand" "")
21342         (match_operator 1 "compare_operator"
21343           [(and:QI (match_operand:QI 2 "register_operand" "")
21344                    (match_operand:QI 3 "immediate_operand" ""))
21345            (const_int 0)]))]
21346   "! TARGET_PARTIAL_REG_STALL
21347    && ix86_match_ccmode (insn, CCNOmode)
21348    && true_regnum (operands[2]) != AX_REG
21349    && peep2_reg_dead_p (1, operands[2])"
21350   [(parallel
21351      [(set (match_dup 0)
21352            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21353                             (const_int 0)]))
21354       (set (match_dup 2)
21355            (and:QI (match_dup 2) (match_dup 3)))])]
21356   "")
21357
21358 (define_peephole2
21359   [(set (match_operand 0 "flags_reg_operand" "")
21360         (match_operator 1 "compare_operator"
21361           [(and:SI
21362              (zero_extract:SI
21363                (match_operand 2 "ext_register_operand" "")
21364                (const_int 8)
21365                (const_int 8))
21366              (match_operand 3 "const_int_operand" ""))
21367            (const_int 0)]))]
21368   "! TARGET_PARTIAL_REG_STALL
21369    && ix86_match_ccmode (insn, CCNOmode)
21370    && true_regnum (operands[2]) != AX_REG
21371    && peep2_reg_dead_p (1, operands[2])"
21372   [(parallel [(set (match_dup 0)
21373                    (match_op_dup 1
21374                      [(and:SI
21375                         (zero_extract:SI
21376                           (match_dup 2)
21377                           (const_int 8)
21378                           (const_int 8))
21379                         (match_dup 3))
21380                       (const_int 0)]))
21381               (set (zero_extract:SI (match_dup 2)
21382                                     (const_int 8)
21383                                     (const_int 8))
21384                    (and:SI
21385                      (zero_extract:SI
21386                        (match_dup 2)
21387                        (const_int 8)
21388                        (const_int 8))
21389                      (match_dup 3)))])]
21390   "")
21391
21392 ;; Don't do logical operations with memory inputs.
21393 (define_peephole2
21394   [(match_scratch:SI 2 "r")
21395    (parallel [(set (match_operand:SI 0 "register_operand" "")
21396                    (match_operator:SI 3 "arith_or_logical_operator"
21397                      [(match_dup 0)
21398                       (match_operand:SI 1 "memory_operand" "")]))
21399               (clobber (reg:CC FLAGS_REG))])]
21400   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21401   [(set (match_dup 2) (match_dup 1))
21402    (parallel [(set (match_dup 0)
21403                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21404               (clobber (reg:CC FLAGS_REG))])]
21405   "")
21406
21407 (define_peephole2
21408   [(match_scratch:SI 2 "r")
21409    (parallel [(set (match_operand:SI 0 "register_operand" "")
21410                    (match_operator:SI 3 "arith_or_logical_operator"
21411                      [(match_operand:SI 1 "memory_operand" "")
21412                       (match_dup 0)]))
21413               (clobber (reg:CC FLAGS_REG))])]
21414   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21415   [(set (match_dup 2) (match_dup 1))
21416    (parallel [(set (match_dup 0)
21417                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21418               (clobber (reg:CC FLAGS_REG))])]
21419   "")
21420
21421 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
21422 ;; refers to the destination of the load!
21423
21424 (define_peephole2
21425   [(set (match_operand:SI 0 "register_operand" "")
21426         (match_operand:SI 1 "register_operand" ""))
21427    (parallel [(set (match_dup 0)
21428                    (match_operator:SI 3 "commutative_operator"
21429                      [(match_dup 0)
21430                       (match_operand:SI 2 "memory_operand" "")]))
21431               (clobber (reg:CC FLAGS_REG))])]
21432   "REGNO (operands[0]) != REGNO (operands[1])
21433    && GENERAL_REGNO_P (REGNO (operands[0]))
21434    && GENERAL_REGNO_P (REGNO (operands[1]))"
21435   [(set (match_dup 0) (match_dup 4))
21436    (parallel [(set (match_dup 0)
21437                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21438               (clobber (reg:CC FLAGS_REG))])]
21439   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21440
21441 (define_peephole2
21442   [(set (match_operand 0 "register_operand" "")
21443         (match_operand 1 "register_operand" ""))
21444    (set (match_dup 0)
21445                    (match_operator 3 "commutative_operator"
21446                      [(match_dup 0)
21447                       (match_operand 2 "memory_operand" "")]))]
21448   "REGNO (operands[0]) != REGNO (operands[1])
21449    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
21450        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21451   [(set (match_dup 0) (match_dup 2))
21452    (set (match_dup 0)
21453         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21454   "")
21455
21456 ; Don't do logical operations with memory outputs
21457 ;
21458 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21459 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
21460 ; the same decoder scheduling characteristics as the original.
21461
21462 (define_peephole2
21463   [(match_scratch:SI 2 "r")
21464    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21465                    (match_operator:SI 3 "arith_or_logical_operator"
21466                      [(match_dup 0)
21467                       (match_operand:SI 1 "nonmemory_operand" "")]))
21468               (clobber (reg:CC FLAGS_REG))])]
21469   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21470   [(set (match_dup 2) (match_dup 0))
21471    (parallel [(set (match_dup 2)
21472                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21473               (clobber (reg:CC FLAGS_REG))])
21474    (set (match_dup 0) (match_dup 2))]
21475   "")
21476
21477 (define_peephole2
21478   [(match_scratch:SI 2 "r")
21479    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21480                    (match_operator:SI 3 "arith_or_logical_operator"
21481                      [(match_operand:SI 1 "nonmemory_operand" "")
21482                       (match_dup 0)]))
21483               (clobber (reg:CC FLAGS_REG))])]
21484   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21485   [(set (match_dup 2) (match_dup 0))
21486    (parallel [(set (match_dup 2)
21487                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21488               (clobber (reg:CC FLAGS_REG))])
21489    (set (match_dup 0) (match_dup 2))]
21490   "")
21491
21492 ;; Attempt to always use XOR for zeroing registers.
21493 (define_peephole2
21494   [(set (match_operand 0 "register_operand" "")
21495         (match_operand 1 "const0_operand" ""))]
21496   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21497    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21498    && GENERAL_REG_P (operands[0])
21499    && peep2_regno_dead_p (0, FLAGS_REG)"
21500   [(parallel [(set (match_dup 0) (const_int 0))
21501               (clobber (reg:CC FLAGS_REG))])]
21502 {
21503   operands[0] = gen_lowpart (word_mode, operands[0]);
21504 })
21505
21506 (define_peephole2
21507   [(set (strict_low_part (match_operand 0 "register_operand" ""))
21508         (const_int 0))]
21509   "(GET_MODE (operands[0]) == QImode
21510     || GET_MODE (operands[0]) == HImode)
21511    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21512    && peep2_regno_dead_p (0, FLAGS_REG)"
21513   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21514               (clobber (reg:CC FLAGS_REG))])])
21515
21516 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21517 (define_peephole2
21518   [(set (match_operand 0 "register_operand" "")
21519         (const_int -1))]
21520   "(GET_MODE (operands[0]) == HImode
21521     || GET_MODE (operands[0]) == SImode
21522     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21523    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21524    && peep2_regno_dead_p (0, FLAGS_REG)"
21525   [(parallel [(set (match_dup 0) (const_int -1))
21526               (clobber (reg:CC FLAGS_REG))])]
21527   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21528                               operands[0]);")
21529
21530 ;; Attempt to convert simple leas to adds. These can be created by
21531 ;; move expanders.
21532 (define_peephole2
21533   [(set (match_operand:SI 0 "register_operand" "")
21534         (plus:SI (match_dup 0)
21535                  (match_operand:SI 1 "nonmemory_operand" "")))]
21536   "peep2_regno_dead_p (0, FLAGS_REG)"
21537   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21538               (clobber (reg:CC FLAGS_REG))])]
21539   "")
21540
21541 (define_peephole2
21542   [(set (match_operand:SI 0 "register_operand" "")
21543         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21544                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21545   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21546   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21547               (clobber (reg:CC FLAGS_REG))])]
21548   "operands[2] = gen_lowpart (SImode, operands[2]);")
21549
21550 (define_peephole2
21551   [(set (match_operand:DI 0 "register_operand" "")
21552         (plus:DI (match_dup 0)
21553                  (match_operand:DI 1 "x86_64_general_operand" "")))]
21554   "peep2_regno_dead_p (0, FLAGS_REG)"
21555   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21556               (clobber (reg:CC FLAGS_REG))])]
21557   "")
21558
21559 (define_peephole2
21560   [(set (match_operand:SI 0 "register_operand" "")
21561         (mult:SI (match_dup 0)
21562                  (match_operand:SI 1 "const_int_operand" "")))]
21563   "exact_log2 (INTVAL (operands[1])) >= 0
21564    && peep2_regno_dead_p (0, FLAGS_REG)"
21565   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21566               (clobber (reg:CC FLAGS_REG))])]
21567   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21568
21569 (define_peephole2
21570   [(set (match_operand:DI 0 "register_operand" "")
21571         (mult:DI (match_dup 0)
21572                  (match_operand:DI 1 "const_int_operand" "")))]
21573   "exact_log2 (INTVAL (operands[1])) >= 0
21574    && peep2_regno_dead_p (0, FLAGS_REG)"
21575   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21576               (clobber (reg:CC FLAGS_REG))])]
21577   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21578
21579 (define_peephole2
21580   [(set (match_operand:SI 0 "register_operand" "")
21581         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21582                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21583   "exact_log2 (INTVAL (operands[2])) >= 0
21584    && REGNO (operands[0]) == REGNO (operands[1])
21585    && peep2_regno_dead_p (0, FLAGS_REG)"
21586   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21587               (clobber (reg:CC FLAGS_REG))])]
21588   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21589
21590 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21591 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21592 ;; many CPUs it is also faster, since special hardware to avoid esp
21593 ;; dependencies is present.
21594
21595 ;; While some of these conversions may be done using splitters, we use peepholes
21596 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21597
21598 ;; Convert prologue esp subtractions to push.
21599 ;; We need register to push.  In order to keep verify_flow_info happy we have
21600 ;; two choices
21601 ;; - use scratch and clobber it in order to avoid dependencies
21602 ;; - use already live register
21603 ;; We can't use the second way right now, since there is no reliable way how to
21604 ;; verify that given register is live.  First choice will also most likely in
21605 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21606 ;; call clobbered registers are dead.  We may want to use base pointer as an
21607 ;; alternative when no register is available later.
21608
21609 (define_peephole2
21610   [(match_scratch:SI 0 "r")
21611    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21612               (clobber (reg:CC FLAGS_REG))
21613               (clobber (mem:BLK (scratch)))])]
21614   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21615   [(clobber (match_dup 0))
21616    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21617               (clobber (mem:BLK (scratch)))])])
21618
21619 (define_peephole2
21620   [(match_scratch:SI 0 "r")
21621    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21622               (clobber (reg:CC FLAGS_REG))
21623               (clobber (mem:BLK (scratch)))])]
21624   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21625   [(clobber (match_dup 0))
21626    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21627    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21628               (clobber (mem:BLK (scratch)))])])
21629
21630 ;; Convert esp subtractions to push.
21631 (define_peephole2
21632   [(match_scratch:SI 0 "r")
21633    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21634               (clobber (reg:CC FLAGS_REG))])]
21635   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21636   [(clobber (match_dup 0))
21637    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21638
21639 (define_peephole2
21640   [(match_scratch:SI 0 "r")
21641    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21642               (clobber (reg:CC FLAGS_REG))])]
21643   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21644   [(clobber (match_dup 0))
21645    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21646    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21647
21648 ;; Convert epilogue deallocator to pop.
21649 (define_peephole2
21650   [(match_scratch:SI 0 "r")
21651    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21652               (clobber (reg:CC FLAGS_REG))
21653               (clobber (mem:BLK (scratch)))])]
21654   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21655   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21656               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21657               (clobber (mem:BLK (scratch)))])]
21658   "")
21659
21660 ;; Two pops case is tricky, since pop causes dependency on destination register.
21661 ;; We use two registers if available.
21662 (define_peephole2
21663   [(match_scratch:SI 0 "r")
21664    (match_scratch:SI 1 "r")
21665    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21666               (clobber (reg:CC FLAGS_REG))
21667               (clobber (mem:BLK (scratch)))])]
21668   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21669   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21670               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21671               (clobber (mem:BLK (scratch)))])
21672    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21673               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21674   "")
21675
21676 (define_peephole2
21677   [(match_scratch:SI 0 "r")
21678    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21679               (clobber (reg:CC FLAGS_REG))
21680               (clobber (mem:BLK (scratch)))])]
21681   "optimize_insn_for_size_p ()"
21682   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21683               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21684               (clobber (mem:BLK (scratch)))])
21685    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21686               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21687   "")
21688
21689 ;; Convert esp additions to pop.
21690 (define_peephole2
21691   [(match_scratch:SI 0 "r")
21692    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21693               (clobber (reg:CC FLAGS_REG))])]
21694   ""
21695   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21696               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21697   "")
21698
21699 ;; Two pops case is tricky, since pop causes dependency on destination register.
21700 ;; We use two registers if available.
21701 (define_peephole2
21702   [(match_scratch:SI 0 "r")
21703    (match_scratch:SI 1 "r")
21704    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21705               (clobber (reg:CC FLAGS_REG))])]
21706   ""
21707   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21708               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21709    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21710               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21711   "")
21712
21713 (define_peephole2
21714   [(match_scratch:SI 0 "r")
21715    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21716               (clobber (reg:CC FLAGS_REG))])]
21717   "optimize_insn_for_size_p ()"
21718   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21719               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21720    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21721               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21722   "")
21723 \f
21724 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21725 ;; required and register dies.  Similarly for 128 to -128.
21726 (define_peephole2
21727   [(set (match_operand 0 "flags_reg_operand" "")
21728         (match_operator 1 "compare_operator"
21729           [(match_operand 2 "register_operand" "")
21730            (match_operand 3 "const_int_operand" "")]))]
21731   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21732      && incdec_operand (operands[3], GET_MODE (operands[3])))
21733     || (!TARGET_FUSE_CMP_AND_BRANCH
21734         && INTVAL (operands[3]) == 128))
21735    && ix86_match_ccmode (insn, CCGCmode)
21736    && peep2_reg_dead_p (1, operands[2])"
21737   [(parallel [(set (match_dup 0)
21738                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21739               (clobber (match_dup 2))])]
21740   "")
21741 \f
21742 (define_peephole2
21743   [(match_scratch:DI 0 "r")
21744    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21745               (clobber (reg:CC FLAGS_REG))
21746               (clobber (mem:BLK (scratch)))])]
21747   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21748   [(clobber (match_dup 0))
21749    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21750               (clobber (mem:BLK (scratch)))])])
21751
21752 (define_peephole2
21753   [(match_scratch:DI 0 "r")
21754    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21755               (clobber (reg:CC FLAGS_REG))
21756               (clobber (mem:BLK (scratch)))])]
21757   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21758   [(clobber (match_dup 0))
21759    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21760    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21761               (clobber (mem:BLK (scratch)))])])
21762
21763 ;; Convert esp subtractions to push.
21764 (define_peephole2
21765   [(match_scratch:DI 0 "r")
21766    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21767               (clobber (reg:CC FLAGS_REG))])]
21768   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21769   [(clobber (match_dup 0))
21770    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21771
21772 (define_peephole2
21773   [(match_scratch:DI 0 "r")
21774    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21775               (clobber (reg:CC FLAGS_REG))])]
21776   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21777   [(clobber (match_dup 0))
21778    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21779    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21780
21781 ;; Convert epilogue deallocator to pop.
21782 (define_peephole2
21783   [(match_scratch:DI 0 "r")
21784    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21785               (clobber (reg:CC FLAGS_REG))
21786               (clobber (mem:BLK (scratch)))])]
21787   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21788   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21789               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21790               (clobber (mem:BLK (scratch)))])]
21791   "")
21792
21793 ;; Two pops case is tricky, since pop causes dependency on destination register.
21794 ;; We use two registers if available.
21795 (define_peephole2
21796   [(match_scratch:DI 0 "r")
21797    (match_scratch:DI 1 "r")
21798    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21799               (clobber (reg:CC FLAGS_REG))
21800               (clobber (mem:BLK (scratch)))])]
21801   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21802   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21803               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21804               (clobber (mem:BLK (scratch)))])
21805    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21806               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21807   "")
21808
21809 (define_peephole2
21810   [(match_scratch:DI 0 "r")
21811    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21812               (clobber (reg:CC FLAGS_REG))
21813               (clobber (mem:BLK (scratch)))])]
21814   "optimize_insn_for_size_p ()"
21815   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21816               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21817               (clobber (mem:BLK (scratch)))])
21818    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21819               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21820   "")
21821
21822 ;; Convert esp additions to pop.
21823 (define_peephole2
21824   [(match_scratch:DI 0 "r")
21825    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21826               (clobber (reg:CC FLAGS_REG))])]
21827   ""
21828   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21829               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21830   "")
21831
21832 ;; Two pops case is tricky, since pop causes dependency on destination register.
21833 ;; We use two registers if available.
21834 (define_peephole2
21835   [(match_scratch:DI 0 "r")
21836    (match_scratch:DI 1 "r")
21837    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21838               (clobber (reg:CC FLAGS_REG))])]
21839   ""
21840   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21841               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21842    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21843               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21844   "")
21845
21846 (define_peephole2
21847   [(match_scratch:DI 0 "r")
21848    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21849               (clobber (reg:CC FLAGS_REG))])]
21850   "optimize_insn_for_size_p ()"
21851   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21852               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21853    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21854               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21855   "")
21856 \f
21857 ;; Convert imul by three, five and nine into lea
21858 (define_peephole2
21859   [(parallel
21860     [(set (match_operand:SI 0 "register_operand" "")
21861           (mult:SI (match_operand:SI 1 "register_operand" "")
21862                    (match_operand:SI 2 "const_int_operand" "")))
21863      (clobber (reg:CC FLAGS_REG))])]
21864   "INTVAL (operands[2]) == 3
21865    || INTVAL (operands[2]) == 5
21866    || INTVAL (operands[2]) == 9"
21867   [(set (match_dup 0)
21868         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21869                  (match_dup 1)))]
21870   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21871
21872 (define_peephole2
21873   [(parallel
21874     [(set (match_operand:SI 0 "register_operand" "")
21875           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21876                    (match_operand:SI 2 "const_int_operand" "")))
21877      (clobber (reg:CC FLAGS_REG))])]
21878   "optimize_insn_for_speed_p ()
21879    && (INTVAL (operands[2]) == 3
21880        || INTVAL (operands[2]) == 5
21881        || INTVAL (operands[2]) == 9)"
21882   [(set (match_dup 0) (match_dup 1))
21883    (set (match_dup 0)
21884         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21885                  (match_dup 0)))]
21886   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21887
21888 (define_peephole2
21889   [(parallel
21890     [(set (match_operand:DI 0 "register_operand" "")
21891           (mult:DI (match_operand:DI 1 "register_operand" "")
21892                    (match_operand:DI 2 "const_int_operand" "")))
21893      (clobber (reg:CC FLAGS_REG))])]
21894   "TARGET_64BIT
21895    && (INTVAL (operands[2]) == 3
21896        || INTVAL (operands[2]) == 5
21897        || INTVAL (operands[2]) == 9)"
21898   [(set (match_dup 0)
21899         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21900                  (match_dup 1)))]
21901   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21902
21903 (define_peephole2
21904   [(parallel
21905     [(set (match_operand:DI 0 "register_operand" "")
21906           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21907                    (match_operand:DI 2 "const_int_operand" "")))
21908      (clobber (reg:CC FLAGS_REG))])]
21909   "TARGET_64BIT
21910    && optimize_insn_for_speed_p ()
21911    && (INTVAL (operands[2]) == 3
21912        || INTVAL (operands[2]) == 5
21913        || INTVAL (operands[2]) == 9)"
21914   [(set (match_dup 0) (match_dup 1))
21915    (set (match_dup 0)
21916         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21917                  (match_dup 0)))]
21918   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21919
21920 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21921 ;; imul $32bit_imm, reg, reg is direct decoded.
21922 (define_peephole2
21923   [(match_scratch:DI 3 "r")
21924    (parallel [(set (match_operand:DI 0 "register_operand" "")
21925                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21926                             (match_operand:DI 2 "immediate_operand" "")))
21927               (clobber (reg:CC FLAGS_REG))])]
21928   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21929    && !satisfies_constraint_K (operands[2])"
21930   [(set (match_dup 3) (match_dup 1))
21931    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21932               (clobber (reg:CC FLAGS_REG))])]
21933 "")
21934
21935 (define_peephole2
21936   [(match_scratch:SI 3 "r")
21937    (parallel [(set (match_operand:SI 0 "register_operand" "")
21938                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21939                             (match_operand:SI 2 "immediate_operand" "")))
21940               (clobber (reg:CC FLAGS_REG))])]
21941   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21942    && !satisfies_constraint_K (operands[2])"
21943   [(set (match_dup 3) (match_dup 1))
21944    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21945               (clobber (reg:CC FLAGS_REG))])]
21946 "")
21947
21948 (define_peephole2
21949   [(match_scratch:SI 3 "r")
21950    (parallel [(set (match_operand:DI 0 "register_operand" "")
21951                    (zero_extend:DI
21952                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21953                               (match_operand:SI 2 "immediate_operand" ""))))
21954               (clobber (reg:CC FLAGS_REG))])]
21955   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21956    && !satisfies_constraint_K (operands[2])"
21957   [(set (match_dup 3) (match_dup 1))
21958    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21959               (clobber (reg:CC FLAGS_REG))])]
21960 "")
21961
21962 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21963 ;; Convert it into imul reg, reg
21964 ;; It would be better to force assembler to encode instruction using long
21965 ;; immediate, but there is apparently no way to do so.
21966 (define_peephole2
21967   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21968                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21969                             (match_operand:DI 2 "const_int_operand" "")))
21970               (clobber (reg:CC FLAGS_REG))])
21971    (match_scratch:DI 3 "r")]
21972   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21973    && satisfies_constraint_K (operands[2])"
21974   [(set (match_dup 3) (match_dup 2))
21975    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21976               (clobber (reg:CC FLAGS_REG))])]
21977 {
21978   if (!rtx_equal_p (operands[0], operands[1]))
21979     emit_move_insn (operands[0], operands[1]);
21980 })
21981
21982 (define_peephole2
21983   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21984                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21985                             (match_operand:SI 2 "const_int_operand" "")))
21986               (clobber (reg:CC FLAGS_REG))])
21987    (match_scratch:SI 3 "r")]
21988   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21989    && satisfies_constraint_K (operands[2])"
21990   [(set (match_dup 3) (match_dup 2))
21991    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21992               (clobber (reg:CC FLAGS_REG))])]
21993 {
21994   if (!rtx_equal_p (operands[0], operands[1]))
21995     emit_move_insn (operands[0], operands[1]);
21996 })
21997
21998 (define_peephole2
21999   [(parallel [(set (match_operand:HI 0 "register_operand" "")
22000                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22001                             (match_operand:HI 2 "immediate_operand" "")))
22002               (clobber (reg:CC FLAGS_REG))])
22003    (match_scratch:HI 3 "r")]
22004   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22005   [(set (match_dup 3) (match_dup 2))
22006    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22007               (clobber (reg:CC FLAGS_REG))])]
22008 {
22009   if (!rtx_equal_p (operands[0], operands[1]))
22010     emit_move_insn (operands[0], operands[1]);
22011 })
22012
22013 ;; After splitting up read-modify operations, array accesses with memory
22014 ;; operands might end up in form:
22015 ;;  sall    $2, %eax
22016 ;;  movl    4(%esp), %edx
22017 ;;  addl    %edx, %eax
22018 ;; instead of pre-splitting:
22019 ;;  sall    $2, %eax
22020 ;;  addl    4(%esp), %eax
22021 ;; Turn it into:
22022 ;;  movl    4(%esp), %edx
22023 ;;  leal    (%edx,%eax,4), %eax
22024
22025 (define_peephole2
22026   [(parallel [(set (match_operand 0 "register_operand" "")
22027                    (ashift (match_operand 1 "register_operand" "")
22028                            (match_operand 2 "const_int_operand" "")))
22029                (clobber (reg:CC FLAGS_REG))])
22030    (set (match_operand 3 "register_operand")
22031         (match_operand 4 "x86_64_general_operand" ""))
22032    (parallel [(set (match_operand 5 "register_operand" "")
22033                    (plus (match_operand 6 "register_operand" "")
22034                          (match_operand 7 "register_operand" "")))
22035                    (clobber (reg:CC FLAGS_REG))])]
22036   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22037    /* Validate MODE for lea.  */
22038    && ((!TARGET_PARTIAL_REG_STALL
22039         && (GET_MODE (operands[0]) == QImode
22040             || GET_MODE (operands[0]) == HImode))
22041        || GET_MODE (operands[0]) == SImode
22042        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22043    /* We reorder load and the shift.  */
22044    && !rtx_equal_p (operands[1], operands[3])
22045    && !reg_overlap_mentioned_p (operands[0], operands[4])
22046    /* Last PLUS must consist of operand 0 and 3.  */
22047    && !rtx_equal_p (operands[0], operands[3])
22048    && (rtx_equal_p (operands[3], operands[6])
22049        || rtx_equal_p (operands[3], operands[7]))
22050    && (rtx_equal_p (operands[0], operands[6])
22051        || rtx_equal_p (operands[0], operands[7]))
22052    /* The intermediate operand 0 must die or be same as output.  */
22053    && (rtx_equal_p (operands[0], operands[5])
22054        || peep2_reg_dead_p (3, operands[0]))"
22055   [(set (match_dup 3) (match_dup 4))
22056    (set (match_dup 0) (match_dup 1))]
22057 {
22058   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22059   int scale = 1 << INTVAL (operands[2]);
22060   rtx index = gen_lowpart (Pmode, operands[1]);
22061   rtx base = gen_lowpart (Pmode, operands[3]);
22062   rtx dest = gen_lowpart (mode, operands[5]);
22063
22064   operands[1] = gen_rtx_PLUS (Pmode, base,
22065                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22066   if (mode != Pmode)
22067     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22068   operands[0] = dest;
22069 })
22070 \f
22071 ;; Call-value patterns last so that the wildcard operand does not
22072 ;; disrupt insn-recog's switch tables.
22073
22074 (define_insn "*call_value_pop_0"
22075   [(set (match_operand 0 "" "")
22076         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22077               (match_operand:SI 2 "" "")))
22078    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22079                             (match_operand:SI 3 "immediate_operand" "")))]
22080   "!TARGET_64BIT"
22081 {
22082   if (SIBLING_CALL_P (insn))
22083     return "jmp\t%P1";
22084   else
22085     return "call\t%P1";
22086 }
22087   [(set_attr "type" "callv")])
22088
22089 (define_insn "*call_value_pop_1"
22090   [(set (match_operand 0 "" "")
22091         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22092               (match_operand:SI 2 "" "")))
22093    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22094                             (match_operand:SI 3 "immediate_operand" "i")))]
22095   "!TARGET_64BIT"
22096 {
22097   if (constant_call_address_operand (operands[1], Pmode))
22098     {
22099       if (SIBLING_CALL_P (insn))
22100         return "jmp\t%P1";
22101       else
22102         return "call\t%P1";
22103     }
22104   if (SIBLING_CALL_P (insn))
22105     return "jmp\t%A1";
22106   else
22107     return "call\t%A1";
22108 }
22109   [(set_attr "type" "callv")])
22110
22111 (define_insn "*call_value_0"
22112   [(set (match_operand 0 "" "")
22113         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22114               (match_operand:SI 2 "" "")))]
22115   "!TARGET_64BIT"
22116 {
22117   if (SIBLING_CALL_P (insn))
22118     return "jmp\t%P1";
22119   else
22120     return "call\t%P1";
22121 }
22122   [(set_attr "type" "callv")])
22123
22124 (define_insn "*call_value_0_rex64"
22125   [(set (match_operand 0 "" "")
22126         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22127               (match_operand:DI 2 "const_int_operand" "")))]
22128   "TARGET_64BIT"
22129 {
22130   if (SIBLING_CALL_P (insn))
22131     return "jmp\t%P1";
22132   else
22133     return "call\t%P1";
22134 }
22135   [(set_attr "type" "callv")])
22136
22137 (define_insn "*call_value_0_rex64_ms_sysv"
22138   [(set (match_operand 0 "" "")
22139         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22140               (match_operand:DI 2 "const_int_operand" "")))
22141    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22142    (clobber (reg:TI XMM6_REG))
22143    (clobber (reg:TI XMM7_REG))
22144    (clobber (reg:TI XMM8_REG))
22145    (clobber (reg:TI XMM9_REG))
22146    (clobber (reg:TI XMM10_REG))
22147    (clobber (reg:TI XMM11_REG))
22148    (clobber (reg:TI XMM12_REG))
22149    (clobber (reg:TI XMM13_REG))
22150    (clobber (reg:TI XMM14_REG))
22151    (clobber (reg:TI XMM15_REG))
22152    (clobber (reg:DI SI_REG))
22153    (clobber (reg:DI DI_REG))]
22154   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22155 {
22156   if (SIBLING_CALL_P (insn))
22157     return "jmp\t%P1";
22158   else
22159     return "call\t%P1";
22160 }
22161   [(set_attr "type" "callv")])
22162
22163 (define_insn "*call_value_1"
22164   [(set (match_operand 0 "" "")
22165         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22166               (match_operand:SI 2 "" "")))]
22167   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22168 {
22169   if (constant_call_address_operand (operands[1], Pmode))
22170     return "call\t%P1";
22171   return "call\t%A1";
22172 }
22173   [(set_attr "type" "callv")])
22174
22175 (define_insn "*sibcall_value_1"
22176   [(set (match_operand 0 "" "")
22177         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
22178               (match_operand:SI 2 "" "")))]
22179   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22180   "@
22181    jmp\t%P1
22182    jmp\t%A1"
22183   [(set_attr "type" "callv")])
22184
22185 (define_insn "*call_value_1_rex64"
22186   [(set (match_operand 0 "" "")
22187         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22188               (match_operand:DI 2 "" "")))]
22189   "!SIBLING_CALL_P (insn) && TARGET_64BIT
22190    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22191 {
22192   if (constant_call_address_operand (operands[1], Pmode))
22193     return "call\t%P1";
22194   return "call\t%A1";
22195 }
22196   [(set_attr "type" "callv")])
22197
22198 (define_insn "*call_value_1_rex64_ms_sysv"
22199   [(set (match_operand 0 "" "")
22200         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22201               (match_operand:DI 2 "" "")))
22202    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22203    (clobber (reg:TI 27))
22204    (clobber (reg:TI 28))
22205    (clobber (reg:TI 45))
22206    (clobber (reg:TI 46))
22207    (clobber (reg:TI 47))
22208    (clobber (reg:TI 48))
22209    (clobber (reg:TI 49))
22210    (clobber (reg:TI 50))
22211    (clobber (reg:TI 51))
22212    (clobber (reg:TI 52))
22213    (clobber (reg:DI SI_REG))
22214    (clobber (reg:DI DI_REG))]
22215   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22216 {
22217   if (constant_call_address_operand (operands[1], Pmode))
22218     return "call\t%P1";
22219   return "call\t%A1";
22220 }
22221   [(set_attr "type" "callv")])
22222
22223 (define_insn "*call_value_1_rex64_large"
22224   [(set (match_operand 0 "" "")
22225         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22226               (match_operand:DI 2 "" "")))]
22227   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22228   "call\t%A1"
22229   [(set_attr "type" "callv")])
22230
22231 (define_insn "*sibcall_value_1_rex64"
22232   [(set (match_operand 0 "" "")
22233         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
22234               (match_operand:DI 2 "" "")))]
22235   "SIBLING_CALL_P (insn) && TARGET_64BIT"
22236   "@
22237    jmp\t%P1
22238    jmp\t%A1"
22239   [(set_attr "type" "callv")])
22240 \f
22241 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22242 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22243 ;; caught for use by garbage collectors and the like.  Using an insn that
22244 ;; maps to SIGILL makes it more likely the program will rightfully die.
22245 ;; Keeping with tradition, "6" is in honor of #UD.
22246 (define_insn "trap"
22247   [(trap_if (const_int 1) (const_int 6))]
22248   ""
22249   { return ASM_SHORT "0x0b0f"; }
22250   [(set_attr "length" "2")])
22251
22252 (define_expand "sse_prologue_save"
22253   [(parallel [(set (match_operand:BLK 0 "" "")
22254                    (unspec:BLK [(reg:DI 21)
22255                                 (reg:DI 22)
22256                                 (reg:DI 23)
22257                                 (reg:DI 24)
22258                                 (reg:DI 25)
22259                                 (reg:DI 26)
22260                                 (reg:DI 27)
22261                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22262               (use (match_operand:DI 1 "register_operand" ""))
22263               (use (match_operand:DI 2 "immediate_operand" ""))
22264               (use (label_ref:DI (match_operand 3 "" "")))])]
22265   "TARGET_64BIT"
22266   "")
22267
22268 (define_insn "*sse_prologue_save_insn"
22269   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22270                           (match_operand:DI 4 "const_int_operand" "n")))
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" "r"))
22280    (use (match_operand:DI 2 "const_int_operand" "i"))
22281    (use (label_ref:DI (match_operand 3 "" "X")))]
22282   "TARGET_64BIT
22283    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22284    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22285 {
22286   int i;
22287   operands[0] = gen_rtx_MEM (Pmode,
22288                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22289   /* VEX instruction with a REX prefix will #UD.  */
22290   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22291     gcc_unreachable ();
22292
22293   output_asm_insn ("jmp\t%A1", operands);
22294   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22295     {
22296       operands[4] = adjust_address (operands[0], DImode, i*16);
22297       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22298       PUT_MODE (operands[4], TImode);
22299       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22300         output_asm_insn ("rex", operands);
22301       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22302     }
22303   (*targetm.asm_out.internal_label) (asm_out_file, "L",
22304                                      CODE_LABEL_NUMBER (operands[3]));
22305   return "";
22306 }
22307   [(set_attr "type" "other")
22308    (set_attr "length_immediate" "0")
22309    (set_attr "length_address" "0")
22310    (set (attr "length")
22311      (if_then_else
22312        (eq (symbol_ref "TARGET_AVX") (const_int 0))
22313        (const_string "34")
22314        (const_string "42")))
22315    (set_attr "memory" "store")
22316    (set_attr "modrm" "0")
22317    (set_attr "prefix" "maybe_vex")
22318    (set_attr "mode" "DI")])
22319
22320 (define_expand "prefetch"
22321   [(prefetch (match_operand 0 "address_operand" "")
22322              (match_operand:SI 1 "const_int_operand" "")
22323              (match_operand:SI 2 "const_int_operand" ""))]
22324   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22325 {
22326   int rw = INTVAL (operands[1]);
22327   int locality = INTVAL (operands[2]);
22328
22329   gcc_assert (rw == 0 || rw == 1);
22330   gcc_assert (locality >= 0 && locality <= 3);
22331   gcc_assert (GET_MODE (operands[0]) == Pmode
22332               || GET_MODE (operands[0]) == VOIDmode);
22333
22334   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22335      supported by SSE counterpart or the SSE prefetch is not available
22336      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22337      of locality.  */
22338   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22339     operands[2] = GEN_INT (3);
22340   else
22341     operands[1] = const0_rtx;
22342 })
22343
22344 (define_insn "*prefetch_sse"
22345   [(prefetch (match_operand:SI 0 "address_operand" "p")
22346              (const_int 0)
22347              (match_operand:SI 1 "const_int_operand" ""))]
22348   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22349 {
22350   static const char * const patterns[4] = {
22351    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22352   };
22353
22354   int locality = INTVAL (operands[1]);
22355   gcc_assert (locality >= 0 && locality <= 3);
22356
22357   return patterns[locality];
22358 }
22359   [(set_attr "type" "sse")
22360    (set_attr "atom_sse_attr" "prefetch")
22361    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22362    (set_attr "memory" "none")])
22363
22364 (define_insn "*prefetch_sse_rex"
22365   [(prefetch (match_operand:DI 0 "address_operand" "p")
22366              (const_int 0)
22367              (match_operand:SI 1 "const_int_operand" ""))]
22368   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22369 {
22370   static const char * const patterns[4] = {
22371    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22372   };
22373
22374   int locality = INTVAL (operands[1]);
22375   gcc_assert (locality >= 0 && locality <= 3);
22376
22377   return patterns[locality];
22378 }
22379   [(set_attr "type" "sse")
22380    (set_attr "atom_sse_attr" "prefetch")
22381    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22382    (set_attr "memory" "none")])
22383
22384 (define_insn "*prefetch_3dnow"
22385   [(prefetch (match_operand:SI 0 "address_operand" "p")
22386              (match_operand:SI 1 "const_int_operand" "n")
22387              (const_int 3))]
22388   "TARGET_3DNOW && !TARGET_64BIT"
22389 {
22390   if (INTVAL (operands[1]) == 0)
22391     return "prefetch\t%a0";
22392   else
22393     return "prefetchw\t%a0";
22394 }
22395   [(set_attr "type" "mmx")
22396    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22397    (set_attr "memory" "none")])
22398
22399 (define_insn "*prefetch_3dnow_rex"
22400   [(prefetch (match_operand:DI 0 "address_operand" "p")
22401              (match_operand:SI 1 "const_int_operand" "n")
22402              (const_int 3))]
22403   "TARGET_3DNOW && TARGET_64BIT"
22404 {
22405   if (INTVAL (operands[1]) == 0)
22406     return "prefetch\t%a0";
22407   else
22408     return "prefetchw\t%a0";
22409 }
22410   [(set_attr "type" "mmx")
22411    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22412    (set_attr "memory" "none")])
22413
22414 (define_expand "stack_protect_set"
22415   [(match_operand 0 "memory_operand" "")
22416    (match_operand 1 "memory_operand" "")]
22417   ""
22418 {
22419 #ifdef TARGET_THREAD_SSP_OFFSET
22420   if (TARGET_64BIT)
22421     emit_insn (gen_stack_tls_protect_set_di (operands[0],
22422                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22423   else
22424     emit_insn (gen_stack_tls_protect_set_si (operands[0],
22425                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22426 #else
22427   if (TARGET_64BIT)
22428     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22429   else
22430     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22431 #endif
22432   DONE;
22433 })
22434
22435 (define_insn "stack_protect_set_si"
22436   [(set (match_operand:SI 0 "memory_operand" "=m")
22437         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22438    (set (match_scratch:SI 2 "=&r") (const_int 0))
22439    (clobber (reg:CC FLAGS_REG))]
22440   ""
22441   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22442   [(set_attr "type" "multi")])
22443
22444 (define_insn "stack_protect_set_di"
22445   [(set (match_operand:DI 0 "memory_operand" "=m")
22446         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22447    (set (match_scratch:DI 2 "=&r") (const_int 0))
22448    (clobber (reg:CC FLAGS_REG))]
22449   "TARGET_64BIT"
22450   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22451   [(set_attr "type" "multi")])
22452
22453 (define_insn "stack_tls_protect_set_si"
22454   [(set (match_operand:SI 0 "memory_operand" "=m")
22455         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22456    (set (match_scratch:SI 2 "=&r") (const_int 0))
22457    (clobber (reg:CC FLAGS_REG))]
22458   ""
22459   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22460   [(set_attr "type" "multi")])
22461
22462 (define_insn "stack_tls_protect_set_di"
22463   [(set (match_operand:DI 0 "memory_operand" "=m")
22464         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22465    (set (match_scratch:DI 2 "=&r") (const_int 0))
22466    (clobber (reg:CC FLAGS_REG))]
22467   "TARGET_64BIT"
22468   {
22469      /* The kernel uses a different segment register for performance reasons; a
22470         system call would not have to trash the userspace segment register,
22471         which would be expensive */
22472      if (ix86_cmodel != CM_KERNEL)
22473         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22474      else
22475         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22476   }
22477   [(set_attr "type" "multi")])
22478
22479 (define_expand "stack_protect_test"
22480   [(match_operand 0 "memory_operand" "")
22481    (match_operand 1 "memory_operand" "")
22482    (match_operand 2 "" "")]
22483   ""
22484 {
22485   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22486
22487 #ifdef TARGET_THREAD_SSP_OFFSET
22488   if (TARGET_64BIT)
22489     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22490                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22491   else
22492     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22493                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22494 #else
22495   if (TARGET_64BIT)
22496     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22497   else
22498     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22499 #endif
22500
22501   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22502                                   flags, const0_rtx, operands[2]));
22503   DONE;
22504 })
22505
22506 (define_insn "stack_protect_test_si"
22507   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22508         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22509                      (match_operand:SI 2 "memory_operand" "m")]
22510                     UNSPEC_SP_TEST))
22511    (clobber (match_scratch:SI 3 "=&r"))]
22512   ""
22513   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22514   [(set_attr "type" "multi")])
22515
22516 (define_insn "stack_protect_test_di"
22517   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22518         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22519                      (match_operand:DI 2 "memory_operand" "m")]
22520                     UNSPEC_SP_TEST))
22521    (clobber (match_scratch:DI 3 "=&r"))]
22522   "TARGET_64BIT"
22523   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22524   [(set_attr "type" "multi")])
22525
22526 (define_insn "stack_tls_protect_test_si"
22527   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22528         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22529                      (match_operand:SI 2 "const_int_operand" "i")]
22530                     UNSPEC_SP_TLS_TEST))
22531    (clobber (match_scratch:SI 3 "=r"))]
22532   ""
22533   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22534   [(set_attr "type" "multi")])
22535
22536 (define_insn "stack_tls_protect_test_di"
22537   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22538         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22539                      (match_operand:DI 2 "const_int_operand" "i")]
22540                     UNSPEC_SP_TLS_TEST))
22541    (clobber (match_scratch:DI 3 "=r"))]
22542   "TARGET_64BIT"
22543   {
22544      /* The kernel uses a different segment register for performance reasons; a
22545         system call would not have to trash the userspace segment register,
22546         which would be expensive */
22547      if (ix86_cmodel != CM_KERNEL)
22548         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22549      else
22550         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22551   }
22552   [(set_attr "type" "multi")])
22553
22554 (define_mode_iterator CRC32MODE [QI HI SI])
22555 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22556 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22557
22558 (define_insn "sse4_2_crc32<mode>"
22559   [(set (match_operand:SI 0 "register_operand" "=r")
22560         (unspec:SI
22561           [(match_operand:SI 1 "register_operand" "0")
22562            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22563           UNSPEC_CRC32))]
22564   "TARGET_SSE4_2 || TARGET_CRC32"
22565   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22566   [(set_attr "type" "sselog1")
22567    (set_attr "prefix_rep" "1")
22568    (set_attr "prefix_extra" "1")
22569    (set (attr "prefix_data16")
22570      (if_then_else (match_operand:HI 2 "" "")
22571        (const_string "1")
22572        (const_string "*")))
22573    (set (attr "prefix_rex")
22574      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22575        (const_string "1")
22576        (const_string "*")))
22577    (set_attr "mode" "SI")])
22578
22579 (define_insn "sse4_2_crc32di"
22580   [(set (match_operand:DI 0 "register_operand" "=r")
22581         (unspec:DI
22582           [(match_operand:DI 1 "register_operand" "0")
22583            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22584           UNSPEC_CRC32))]
22585   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22586   "crc32q\t{%2, %0|%0, %2}"
22587   [(set_attr "type" "sselog1")
22588    (set_attr "prefix_rep" "1")
22589    (set_attr "prefix_extra" "1")
22590    (set_attr "mode" "DI")])
22591
22592 (define_expand "rdpmc"
22593   [(match_operand:DI 0 "register_operand" "")
22594    (match_operand:SI 1 "register_operand" "")]
22595   ""
22596 {
22597   rtx reg = gen_reg_rtx (DImode);
22598   rtx si;
22599
22600   /* Force operand 1 into ECX.  */
22601   rtx ecx = gen_rtx_REG (SImode, CX_REG);
22602   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
22603   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
22604                                 UNSPECV_RDPMC);
22605
22606   if (TARGET_64BIT)
22607     {
22608       rtvec vec = rtvec_alloc (2);
22609       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22610       rtx upper = gen_reg_rtx (DImode);
22611       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22612                                         gen_rtvec (1, const0_rtx),
22613                                         UNSPECV_RDPMC);
22614       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
22615       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22616       emit_insn (load);
22617       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22618                                    NULL, 1, OPTAB_DIRECT);
22619       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22620                                  OPTAB_DIRECT);
22621     }
22622   else
22623     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
22624   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22625   DONE;
22626 })
22627
22628 (define_insn "*rdpmc"
22629   [(set (match_operand:DI 0 "register_operand" "=A")
22630         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
22631                             UNSPECV_RDPMC))]
22632   "!TARGET_64BIT"
22633   "rdpmc"
22634   [(set_attr "type" "other")
22635    (set_attr "length" "2")])
22636
22637 (define_insn "*rdpmc_rex64"
22638   [(set (match_operand:DI 0 "register_operand" "=a")
22639         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
22640                             UNSPECV_RDPMC))
22641   (set (match_operand:DI 1 "register_operand" "=d")
22642        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
22643   "TARGET_64BIT"
22644   "rdpmc"
22645   [(set_attr "type" "other")
22646    (set_attr "length" "2")])
22647
22648 (define_expand "rdtsc"
22649   [(set (match_operand:DI 0 "register_operand" "")
22650         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22651   ""
22652 {
22653   if (TARGET_64BIT)
22654     {
22655       rtvec vec = rtvec_alloc (2);
22656       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22657       rtx upper = gen_reg_rtx (DImode);
22658       rtx lower = gen_reg_rtx (DImode);
22659       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
22660                                          gen_rtvec (1, const0_rtx),
22661                                          UNSPECV_RDTSC);
22662       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
22663       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
22664       emit_insn (load);
22665       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22666                                    NULL, 1, OPTAB_DIRECT);
22667       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
22668                                    OPTAB_DIRECT);
22669       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
22670       DONE;
22671     }
22672 })
22673
22674 (define_insn "*rdtsc"
22675   [(set (match_operand:DI 0 "register_operand" "=A")
22676         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22677   "!TARGET_64BIT"
22678   "rdtsc"
22679   [(set_attr "type" "other")
22680    (set_attr "length" "2")])
22681
22682 (define_insn "*rdtsc_rex64"
22683   [(set (match_operand:DI 0 "register_operand" "=a")
22684         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
22685    (set (match_operand:DI 1 "register_operand" "=d")
22686         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22687   "TARGET_64BIT"
22688   "rdtsc"
22689   [(set_attr "type" "other")
22690    (set_attr "length" "2")])
22691
22692 (define_expand "rdtscp"
22693   [(match_operand:DI 0 "register_operand" "")
22694    (match_operand:SI 1 "memory_operand" "")]
22695   ""
22696 {
22697   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22698                                     gen_rtvec (1, const0_rtx),
22699                                     UNSPECV_RDTSCP);
22700   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
22701                                     gen_rtvec (1, const0_rtx),
22702                                     UNSPECV_RDTSCP);
22703   rtx reg = gen_reg_rtx (DImode);
22704   rtx tmp = gen_reg_rtx (SImode);
22705
22706   if (TARGET_64BIT)
22707     {
22708       rtvec vec = rtvec_alloc (3);
22709       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22710       rtx upper = gen_reg_rtx (DImode);
22711       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22712       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22713       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22714       emit_insn (load);
22715       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22716                                    NULL, 1, OPTAB_DIRECT);
22717       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22718                                  OPTAB_DIRECT);
22719     }
22720   else
22721     {
22722       rtvec vec = rtvec_alloc (2);
22723       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22724       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22725       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22726       emit_insn (load);
22727     }
22728   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22729   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22730   DONE;
22731 })
22732
22733 (define_insn "*rdtscp"
22734   [(set (match_operand:DI 0 "register_operand" "=A")
22735         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22736    (set (match_operand:SI 1 "register_operand" "=c")
22737         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22738   "!TARGET_64BIT"
22739   "rdtscp"
22740   [(set_attr "type" "other")
22741    (set_attr "length" "3")])
22742
22743 (define_insn "*rdtscp_rex64"
22744   [(set (match_operand:DI 0 "register_operand" "=a")
22745         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22746    (set (match_operand:DI 1 "register_operand" "=d")
22747         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22748    (set (match_operand:SI 2 "register_operand" "=c")
22749         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22750   "TARGET_64BIT"
22751   "rdtscp"
22752   [(set_attr "type" "other")
22753    (set_attr "length" "3")])
22754
22755 (include "mmx.md")
22756 (include "sse.md")
22757 (include "sync.md")