OSDN Git Service

PR target/43067
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63
64 ;; UNSPEC usage:
65
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
79
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
89
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
95
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
106
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
126
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
131
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
143
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
151
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
163
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
166
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
172
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
177
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
183
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
193
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
198
199    ; For FMA4 support
200    (UNSPEC_FMA4_INTRINSIC       150)
201    (UNSPEC_FMA4_FMADDSUB        151)
202    (UNSPEC_FMA4_FMSUBADD        152)
203    (UNSPEC_XOP_UNSIGNED_CMP     151)
204    (UNSPEC_XOP_TRUEFALSE        152)
205    (UNSPEC_XOP_PERMUTE          153)
206    (UNSPEC_FRCZ                 154)
207
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_VPERMIL2             168)
223    (UNSPEC_VPERMIL2F128         169)
224    (UNSPEC_MASKLOAD             170)
225    (UNSPEC_MASKSTORE            171)
226    (UNSPEC_CAST                 172)
227    (UNSPEC_VTESTP               173)
228   ])
229
230 (define_constants
231   [(UNSPECV_BLOCKAGE            0)
232    (UNSPECV_STACK_PROBE         1)
233    (UNSPECV_EMMS                2)
234    (UNSPECV_LDMXCSR             3)
235    (UNSPECV_STMXCSR             4)
236    (UNSPECV_FEMMS               5)
237    (UNSPECV_CLFLUSH             6)
238    (UNSPECV_ALIGN               7)
239    (UNSPECV_MONITOR             8)
240    (UNSPECV_MWAIT               9)
241    (UNSPECV_CMPXCHG             10)
242    (UNSPECV_XCHG                12)
243    (UNSPECV_LOCK                13)
244    (UNSPECV_PROLOGUE_USE        14)
245    (UNSPECV_CLD                 15)
246    (UNSPECV_VZEROALL            16)
247    (UNSPECV_VZEROUPPER          17)
248    (UNSPECV_RDTSC               18)
249    (UNSPECV_RDTSCP              19)
250    (UNSPECV_RDPMC               20)
251    (UNSPECV_VSWAPMOV            21)
252    (UNSPECV_LLWP_INTRINSIC      22)
253    (UNSPECV_SLWP_INTRINSIC      23)
254    (UNSPECV_LWPVAL_INTRINSIC    24)
255    (UNSPECV_LWPINS_INTRINSIC    25)
256   ])
257
258 ;; Constants to represent pcomtrue/pcomfalse variants
259 (define_constants
260   [(PCOM_FALSE                  0)
261    (PCOM_TRUE                   1)
262    (COM_FALSE_S                 2)
263    (COM_FALSE_P                 3)
264    (COM_TRUE_S                  4)
265    (COM_TRUE_P                  5)
266   ])
267
268 ;; Constants used in the XOP pperm instruction
269 (define_constants
270   [(PPERM_SRC                   0x00)   /* copy source */
271    (PPERM_INVERT                0x20)   /* invert source */
272    (PPERM_REVERSE               0x40)   /* bit reverse source */
273    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
274    (PPERM_ZERO                  0x80)   /* all 0's */
275    (PPERM_ONES                  0xa0)   /* all 1's */
276    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
277    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
278    (PPERM_SRC1                  0x00)   /* use first source byte */
279    (PPERM_SRC2                  0x10)   /* use second source byte */
280    ])
281
282 ;; Registers by name.
283 (define_constants
284   [(AX_REG                       0)
285    (DX_REG                       1)
286    (CX_REG                       2)
287    (BX_REG                       3)
288    (SI_REG                       4)
289    (DI_REG                       5)
290    (BP_REG                       6)
291    (SP_REG                       7)
292    (ST0_REG                      8)
293    (ST1_REG                      9)
294    (ST2_REG                     10)
295    (ST3_REG                     11)
296    (ST4_REG                     12)
297    (ST5_REG                     13)
298    (ST6_REG                     14)
299    (ST7_REG                     15)
300    (FLAGS_REG                   17)
301    (FPSR_REG                    18)
302    (FPCR_REG                    19)
303    (XMM0_REG                    21)
304    (XMM1_REG                    22)
305    (XMM2_REG                    23)
306    (XMM3_REG                    24)
307    (XMM4_REG                    25)
308    (XMM5_REG                    26)
309    (XMM6_REG                    27)
310    (XMM7_REG                    28)
311    (MM0_REG                     29)
312    (MM1_REG                     30)
313    (MM2_REG                     31)
314    (MM3_REG                     32)
315    (MM4_REG                     33)
316    (MM5_REG                     34)
317    (MM6_REG                     35)
318    (MM7_REG                     36)
319    (R8_REG                      37)
320    (R9_REG                      38)
321    (R10_REG                     39)
322    (R11_REG                     40)
323    (R12_REG                     41)
324    (R13_REG                     42)
325    (XMM8_REG                    45)
326    (XMM9_REG                    46)
327    (XMM10_REG                   47)
328    (XMM11_REG                   48)
329    (XMM12_REG                   49)
330    (XMM13_REG                   50)
331    (XMM14_REG                   51)
332    (XMM15_REG                   52)
333   ])
334
335 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
336 ;; from i386.c.
337
338 ;; In C guard expressions, put expressions which may be compile-time
339 ;; constants first.  This allows for better optimization.  For
340 ;; example, write "TARGET_64BIT && reload_completed", not
341 ;; "reload_completed && TARGET_64BIT".
342
343 \f
344 ;; Processor type.
345 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346                     generic64,amdfam10"
347   (const (symbol_ref "ix86_schedule")))
348
349 ;; A basic instruction type.  Refinements due to arguments to be
350 ;; provided in other attributes.
351 (define_attr "type"
352   "other,multi,
353    alu,alu1,negnot,imov,imovx,lea,
354    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
355    icmp,test,ibr,setcc,icmov,
356    push,pop,call,callv,leave,
357    str,bitmanip,
358    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
359    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
360    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
361    ssemuladd,sse4arg,lwp,
362    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
363   (const_string "other"))
364
365 ;; Main data type used by the insn
366 (define_attr "mode"
367   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
368   (const_string "unknown"))
369
370 ;; The CPU unit operations uses.
371 (define_attr "unit" "integer,i387,sse,mmx,unknown"
372   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
373            (const_string "i387")
374          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
375                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
376                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377            (const_string "sse")
378          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379            (const_string "mmx")
380          (eq_attr "type" "other")
381            (const_string "unknown")]
382          (const_string "integer")))
383
384 ;; The (bounding maximum) length of an instruction immediate.
385 (define_attr "length_immediate" ""
386   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
387                           bitmanip")
388            (const_int 0)
389          (eq_attr "unit" "i387,sse,mmx")
390            (const_int 0)
391          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392                           imul,icmp,push,pop")
393            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
394          (eq_attr "type" "imov,test")
395            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
396          (eq_attr "type" "call")
397            (if_then_else (match_operand 0 "constant_call_address_operand" "")
398              (const_int 4)
399              (const_int 0))
400          (eq_attr "type" "callv")
401            (if_then_else (match_operand 1 "constant_call_address_operand" "")
402              (const_int 4)
403              (const_int 0))
404          ;; We don't know the size before shorten_branches.  Expect
405          ;; the instruction to fit for better scheduling.
406          (eq_attr "type" "ibr")
407            (const_int 1)
408          ]
409          (symbol_ref "/* Update immediate_length and other attributes! */
410                       gcc_unreachable (),1")))
411
412 ;; The (bounding maximum) length of an instruction address.
413 (define_attr "length_address" ""
414   (cond [(eq_attr "type" "str,other,multi,fxch")
415            (const_int 0)
416          (and (eq_attr "type" "call")
417               (match_operand 0 "constant_call_address_operand" ""))
418              (const_int 0)
419          (and (eq_attr "type" "callv")
420               (match_operand 1 "constant_call_address_operand" ""))
421              (const_int 0)
422          ]
423          (symbol_ref "ix86_attr_length_address_default (insn)")))
424
425 ;; Set when length prefix is used.
426 (define_attr "prefix_data16" ""
427   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428            (const_int 0)
429          (eq_attr "mode" "HI")
430            (const_int 1)
431          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
432            (const_int 1)
433         ]
434         (const_int 0)))
435
436 ;; Set when string REP prefix is used.
437 (define_attr "prefix_rep" ""
438   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439            (const_int 0)
440          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
441            (const_int 1)
442         ]
443         (const_int 0)))
444
445 ;; Set when 0f opcode prefix is used.
446 (define_attr "prefix_0f" ""
447   (if_then_else
448     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
449          (eq_attr "unit" "sse,mmx"))
450     (const_int 1)
451     (const_int 0)))
452
453 ;; Set when REX opcode prefix is used.
454 (define_attr "prefix_rex" ""
455   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456            (const_int 0)
457          (and (eq_attr "mode" "DI")
458               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
459                    (eq_attr "unit" "!mmx")))
460            (const_int 1)
461          (and (eq_attr "mode" "QI")
462               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
463                   (const_int 0)))
464            (const_int 1)
465          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
466              (const_int 0))
467            (const_int 1)
468          (and (eq_attr "type" "imovx")
469               (match_operand:QI 1 "ext_QIreg_operand" ""))
470            (const_int 1)
471         ]
472         (const_int 0)))
473
474 ;; There are also additional prefixes in 3DNOW, SSSE3.
475 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
476 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
477 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
478 (define_attr "prefix_extra" ""
479   (cond [(eq_attr "type" "ssemuladd,sse4arg")
480            (const_int 2)
481          (eq_attr "type" "sseiadd1,ssecvt1")
482            (const_int 1)
483         ]
484         (const_int 0)))
485
486 ;; Prefix used: original, VEX or maybe VEX.
487 (define_attr "prefix" "orig,vex,maybe_vex"
488   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489     (const_string "vex")
490     (const_string "orig")))
491
492 ;; VEX W bit is used.
493 (define_attr "prefix_vex_w" "" (const_int 0))
494
495 ;; The length of VEX prefix
496 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
497 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
498 ;; still prefix_0f 1, with prefix_extra 1.
499 (define_attr "length_vex" ""
500   (if_then_else (and (eq_attr "prefix_0f" "1")
501                      (eq_attr "prefix_extra" "0"))
502     (if_then_else (eq_attr "prefix_vex_w" "1")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
504       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
505     (if_then_else (eq_attr "prefix_vex_w" "1")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
507       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508
509 ;; Set when modrm byte is used.
510 (define_attr "modrm" ""
511   (cond [(eq_attr "type" "str,leave")
512            (const_int 0)
513          (eq_attr "unit" "i387")
514            (const_int 0)
515          (and (eq_attr "type" "incdec")
516               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
517                    (ior (match_operand:SI 1 "register_operand" "")
518                         (match_operand:HI 1 "register_operand" ""))))
519            (const_int 0)
520          (and (eq_attr "type" "push")
521               (not (match_operand 1 "memory_operand" "")))
522            (const_int 0)
523          (and (eq_attr "type" "pop")
524               (not (match_operand 0 "memory_operand" "")))
525            (const_int 0)
526          (and (eq_attr "type" "imov")
527               (and (not (eq_attr "mode" "DI"))
528                    (ior (and (match_operand 0 "register_operand" "")
529                              (match_operand 1 "immediate_operand" ""))
530                         (ior (and (match_operand 0 "ax_reg_operand" "")
531                                   (match_operand 1 "memory_displacement_only_operand" ""))
532                              (and (match_operand 0 "memory_displacement_only_operand" "")
533                                   (match_operand 1 "ax_reg_operand" ""))))))
534            (const_int 0)
535          (and (eq_attr "type" "call")
536               (match_operand 0 "constant_call_address_operand" ""))
537              (const_int 0)
538          (and (eq_attr "type" "callv")
539               (match_operand 1 "constant_call_address_operand" ""))
540              (const_int 0)
541          (and (eq_attr "type" "alu,alu1,icmp,test")
542               (match_operand 0 "ax_reg_operand" ""))
543              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
544          ]
545          (const_int 1)))
546
547 ;; The (bounding maximum) length of an instruction in bytes.
548 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
549 ;; Later we may want to split them and compute proper length as for
550 ;; other insns.
551 (define_attr "length" ""
552   (cond [(eq_attr "type" "other,multi,fistp,frndint")
553            (const_int 16)
554          (eq_attr "type" "fcmp")
555            (const_int 4)
556          (eq_attr "unit" "i387")
557            (plus (const_int 2)
558                  (plus (attr "prefix_data16")
559                        (attr "length_address")))
560          (ior (eq_attr "prefix" "vex")
561               (and (eq_attr "prefix" "maybe_vex")
562                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
563            (plus (attr "length_vex")
564                  (plus (attr "length_immediate")
565                        (plus (attr "modrm")
566                              (attr "length_address"))))]
567          (plus (plus (attr "modrm")
568                      (plus (attr "prefix_0f")
569                            (plus (attr "prefix_rex")
570                                  (plus (attr "prefix_extra")
571                                        (const_int 1)))))
572                (plus (attr "prefix_rep")
573                      (plus (attr "prefix_data16")
574                            (plus (attr "length_immediate")
575                                  (attr "length_address")))))))
576
577 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
578 ;; `store' if there is a simple memory reference therein, or `unknown'
579 ;; if the instruction is complex.
580
581 (define_attr "memory" "none,load,store,both,unknown"
582   (cond [(eq_attr "type" "other,multi,str,lwp")
583            (const_string "unknown")
584          (eq_attr "type" "lea,fcmov,fpspc")
585            (const_string "none")
586          (eq_attr "type" "fistp,leave")
587            (const_string "both")
588          (eq_attr "type" "frndint")
589            (const_string "load")
590          (eq_attr "type" "push")
591            (if_then_else (match_operand 1 "memory_operand" "")
592              (const_string "both")
593              (const_string "store"))
594          (eq_attr "type" "pop")
595            (if_then_else (match_operand 0 "memory_operand" "")
596              (const_string "both")
597              (const_string "load"))
598          (eq_attr "type" "setcc")
599            (if_then_else (match_operand 0 "memory_operand" "")
600              (const_string "store")
601              (const_string "none"))
602          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
603            (if_then_else (ior (match_operand 0 "memory_operand" "")
604                               (match_operand 1 "memory_operand" ""))
605              (const_string "load")
606              (const_string "none"))
607          (eq_attr "type" "ibr")
608            (if_then_else (match_operand 0 "memory_operand" "")
609              (const_string "load")
610              (const_string "none"))
611          (eq_attr "type" "call")
612            (if_then_else (match_operand 0 "constant_call_address_operand" "")
613              (const_string "none")
614              (const_string "load"))
615          (eq_attr "type" "callv")
616            (if_then_else (match_operand 1 "constant_call_address_operand" "")
617              (const_string "none")
618              (const_string "load"))
619          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
620               (match_operand 1 "memory_operand" ""))
621            (const_string "both")
622          (and (match_operand 0 "memory_operand" "")
623               (match_operand 1 "memory_operand" ""))
624            (const_string "both")
625          (match_operand 0 "memory_operand" "")
626            (const_string "store")
627          (match_operand 1 "memory_operand" "")
628            (const_string "load")
629          (and (eq_attr "type"
630                  "!alu1,negnot,ishift1,
631                    imov,imovx,icmp,test,bitmanip,
632                    fmov,fcmp,fsgn,
633                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
634                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
635               (match_operand 2 "memory_operand" ""))
636            (const_string "load")
637          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
638               (match_operand 3 "memory_operand" ""))
639            (const_string "load")
640         ]
641         (const_string "none")))
642
643 ;; Indicates if an instruction has both an immediate and a displacement.
644
645 (define_attr "imm_disp" "false,true,unknown"
646   (cond [(eq_attr "type" "other,multi")
647            (const_string "unknown")
648          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
649               (and (match_operand 0 "memory_displacement_operand" "")
650                    (match_operand 1 "immediate_operand" "")))
651            (const_string "true")
652          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
653               (and (match_operand 0 "memory_displacement_operand" "")
654                    (match_operand 2 "immediate_operand" "")))
655            (const_string "true")
656         ]
657         (const_string "false")))
658
659 ;; Indicates if an FP operation has an integer source.
660
661 (define_attr "fp_int_src" "false,true"
662   (const_string "false"))
663
664 ;; Defines rounding mode of an FP operation.
665
666 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
667   (const_string "any"))
668
669 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
670 (define_attr "use_carry" "0,1" (const_string "0"))
671
672 ;; Define attribute to indicate unaligned ssemov insns
673 (define_attr "movu" "0,1" (const_string "0"))
674
675 ;; Describe a user's asm statement.
676 (define_asm_attributes
677   [(set_attr "length" "128")
678    (set_attr "type" "multi")])
679
680 ;; All integer comparison codes.
681 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
682
683 ;; All floating-point comparison codes.
684 (define_code_iterator fp_cond [unordered ordered
685                                uneq unge ungt unle unlt ltgt])
686
687 (define_code_iterator plusminus [plus minus])
688
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698   [(plus "add") (ss_plus "adds") (us_plus "addus")
699    (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701   [(plus "adc") (minus "sbb")])
702
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705                         (minus "") (ss_minus "") (us_minus "")])
706
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
709
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
712
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin umax umin])
715
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
718                                  (umax "maxu") (umin "minu")])
719 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
720
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of abs neg operators
729 (define_code_iterator absneg [abs neg])
730
731 ;; Base name for x87 insn mnemonic.
732 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
733
734 ;; Used in signed and unsigned widening multiplications.
735 (define_code_iterator any_extend [sign_extend zero_extend])
736
737 ;; Various insn prefixes for signed and unsigned operations.
738 (define_code_attr u [(sign_extend "") (zero_extend "u")
739                      (div "") (udiv "u")])
740 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
741
742 ;; Used in signed and unsigned divisions.
743 (define_code_iterator any_div [div udiv])
744
745 ;; Instruction prefix for signed and unsigned operations.
746 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
747                              (div "i") (udiv "")])
748
749 ;; All single word integer modes.
750 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
751
752 ;; Single word integer modes without DImode.
753 (define_mode_iterator SWI124 [QI HI SI])
754
755 ;; Single word integer modes without QImode.
756 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
757
758 ;; Single word integer modes without QImode and HImode.
759 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
760
761 ;; All math-dependant single and double word integer modes.
762 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
763                              (HI "TARGET_HIMODE_MATH")
764                              SI DI (TI "TARGET_64BIT")])
765
766 ;; Math-dependant single word integer modes.
767 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
768                             (HI "TARGET_HIMODE_MATH")
769                             SI (DI "TARGET_64BIT")])
770
771 ;; Math-dependant single word integer modes without QImode.
772 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
773                                SI (DI "TARGET_64BIT")])
774
775 ;; Half mode for double word integer modes.
776 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
777                             (DI "TARGET_64BIT")])
778
779 ;; Double word integer modes.
780 (define_mode_attr DWI [(SI "DI") (DI "TI")])
781 (define_mode_attr dwi [(SI "di") (DI "ti")])
782
783 ;; Instruction suffix for integer modes.
784 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
785
786 ;; Register class for integer modes.
787 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
788
789 ;; Immediate operand constraint for integer modes.
790 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
791
792 ;; General operand constraint for word modes.
793 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
794
795 ;; Immediate operand constraint for double integer modes.
796 (define_mode_attr di [(SI "iF") (DI "e")])
797
798 ;; General operand predicate for integer modes.
799 (define_mode_attr general_operand
800         [(QI "general_operand")
801          (HI "general_operand")
802          (SI "general_operand")
803          (DI "x86_64_general_operand")
804          (TI "x86_64_general_operand")])
805
806 ;; General sign/zero extend operand predicate for integer modes.
807 (define_mode_attr general_szext_operand
808         [(QI "general_operand")
809          (HI "general_operand")
810          (SI "general_operand")
811          (DI "x86_64_szext_general_operand")])
812
813 ;; SSE and x87 SFmode and DFmode floating point modes
814 (define_mode_iterator MODEF [SF DF])
815
816 ;; All x87 floating point modes
817 (define_mode_iterator X87MODEF [SF DF XF])
818
819 ;; All integer modes handled by x87 fisttp operator.
820 (define_mode_iterator X87MODEI [HI SI DI])
821
822 ;; All integer modes handled by integer x87 operators.
823 (define_mode_iterator X87MODEI12 [HI SI])
824
825 ;; All integer modes handled by SSE cvtts?2si* operators.
826 (define_mode_iterator SSEMODEI24 [SI DI])
827
828 ;; SSE asm suffix for floating point modes
829 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
830
831 ;; SSE vector mode corresponding to a scalar mode
832 (define_mode_attr ssevecmode
833   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
834
835 ;; Instruction suffix for REX 64bit operators.
836 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
837
838 ;; This mode iterator allows :P to be used for patterns that operate on
839 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
840 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
841 \f
842 ;; Scheduling descriptions
843
844 (include "pentium.md")
845 (include "ppro.md")
846 (include "k6.md")
847 (include "athlon.md")
848 (include "geode.md")
849 (include "atom.md")
850
851 \f
852 ;; Operand and operator predicates and constraints
853
854 (include "predicates.md")
855 (include "constraints.md")
856
857 \f
858 ;; Compare and branch/compare and store instructions.
859
860 (define_expand "cbranch<mode>4"
861   [(set (reg:CC FLAGS_REG)
862         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
863                     (match_operand:SDWIM 2 "<general_operand>" "")))
864    (set (pc) (if_then_else
865                (match_operator 0 "comparison_operator"
866                 [(reg:CC FLAGS_REG) (const_int 0)])
867                (label_ref (match_operand 3 "" ""))
868                (pc)))]
869   ""
870 {
871   if (MEM_P (operands[1]) && MEM_P (operands[2]))
872     operands[1] = force_reg (<MODE>mode, operands[1]);
873   ix86_compare_op0 = operands[1];
874   ix86_compare_op1 = operands[2];
875   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
876   DONE;
877 })
878
879 (define_expand "cstore<mode>4"
880   [(set (reg:CC FLAGS_REG)
881         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
882                     (match_operand:SWIM 3 "<general_operand>" "")))
883    (set (match_operand:QI 0 "register_operand" "")
884         (match_operator 1 "comparison_operator"
885           [(reg:CC FLAGS_REG) (const_int 0)]))]
886   ""
887 {
888   if (MEM_P (operands[2]) && MEM_P (operands[3]))
889     operands[2] = force_reg (<MODE>mode, operands[2]);
890   ix86_compare_op0 = operands[2];
891   ix86_compare_op1 = operands[3];
892   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
893   DONE;
894 })
895
896 (define_expand "cmp<mode>_1"
897   [(set (reg:CC FLAGS_REG)
898         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
899                     (match_operand:SWI48 1 "<general_operand>" "")))]
900   ""
901   "")
902
903 (define_insn "*cmp<mode>_ccno_1"
904   [(set (reg FLAGS_REG)
905         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
906                  (match_operand:SWI 1 "const0_operand" "")))]
907   "ix86_match_ccmode (insn, CCNOmode)"
908   "@
909    test{<imodesuffix>}\t%0, %0
910    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
911   [(set_attr "type" "test,icmp")
912    (set_attr "length_immediate" "0,1")
913    (set_attr "mode" "<MODE>")])
914
915 (define_insn "*cmp<mode>_1"
916   [(set (reg FLAGS_REG)
917         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
918                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
919   "ix86_match_ccmode (insn, CCmode)"
920   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
921   [(set_attr "type" "icmp")
922    (set_attr "mode" "<MODE>")])
923
924 (define_insn "*cmp<mode>_minus_1"
925   [(set (reg FLAGS_REG)
926         (compare
927           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
928                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
929           (const_int 0)))]
930   "ix86_match_ccmode (insn, CCGOCmode)"
931   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
932   [(set_attr "type" "icmp")
933    (set_attr "mode" "<MODE>")])
934
935 (define_insn "*cmpqi_ext_1"
936   [(set (reg FLAGS_REG)
937         (compare
938           (match_operand:QI 0 "general_operand" "Qm")
939           (subreg:QI
940             (zero_extract:SI
941               (match_operand 1 "ext_register_operand" "Q")
942               (const_int 8)
943               (const_int 8)) 0)))]
944   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
945   "cmp{b}\t{%h1, %0|%0, %h1}"
946   [(set_attr "type" "icmp")
947    (set_attr "mode" "QI")])
948
949 (define_insn "*cmpqi_ext_1_rex64"
950   [(set (reg FLAGS_REG)
951         (compare
952           (match_operand:QI 0 "register_operand" "Q")
953           (subreg:QI
954             (zero_extract:SI
955               (match_operand 1 "ext_register_operand" "Q")
956               (const_int 8)
957               (const_int 8)) 0)))]
958   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
959   "cmp{b}\t{%h1, %0|%0, %h1}"
960   [(set_attr "type" "icmp")
961    (set_attr "mode" "QI")])
962
963 (define_insn "*cmpqi_ext_2"
964   [(set (reg FLAGS_REG)
965         (compare
966           (subreg:QI
967             (zero_extract:SI
968               (match_operand 0 "ext_register_operand" "Q")
969               (const_int 8)
970               (const_int 8)) 0)
971           (match_operand:QI 1 "const0_operand" "")))]
972   "ix86_match_ccmode (insn, CCNOmode)"
973   "test{b}\t%h0, %h0"
974   [(set_attr "type" "test")
975    (set_attr "length_immediate" "0")
976    (set_attr "mode" "QI")])
977
978 (define_expand "cmpqi_ext_3"
979   [(set (reg:CC FLAGS_REG)
980         (compare:CC
981           (subreg:QI
982             (zero_extract:SI
983               (match_operand 0 "ext_register_operand" "")
984               (const_int 8)
985               (const_int 8)) 0)
986           (match_operand:QI 1 "immediate_operand" "")))]
987   ""
988   "")
989
990 (define_insn "*cmpqi_ext_3_insn"
991   [(set (reg FLAGS_REG)
992         (compare
993           (subreg:QI
994             (zero_extract:SI
995               (match_operand 0 "ext_register_operand" "Q")
996               (const_int 8)
997               (const_int 8)) 0)
998           (match_operand:QI 1 "general_operand" "Qmn")))]
999   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1000   "cmp{b}\t{%1, %h0|%h0, %1}"
1001   [(set_attr "type" "icmp")
1002    (set_attr "modrm" "1")
1003    (set_attr "mode" "QI")])
1004
1005 (define_insn "*cmpqi_ext_3_insn_rex64"
1006   [(set (reg FLAGS_REG)
1007         (compare
1008           (subreg:QI
1009             (zero_extract:SI
1010               (match_operand 0 "ext_register_operand" "Q")
1011               (const_int 8)
1012               (const_int 8)) 0)
1013           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1014   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015   "cmp{b}\t{%1, %h0|%h0, %1}"
1016   [(set_attr "type" "icmp")
1017    (set_attr "modrm" "1")
1018    (set_attr "mode" "QI")])
1019
1020 (define_insn "*cmpqi_ext_4"
1021   [(set (reg FLAGS_REG)
1022         (compare
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 0 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)
1028           (subreg:QI
1029             (zero_extract:SI
1030               (match_operand 1 "ext_register_operand" "Q")
1031               (const_int 8)
1032               (const_int 8)) 0)))]
1033   "ix86_match_ccmode (insn, CCmode)"
1034   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1035   [(set_attr "type" "icmp")
1036    (set_attr "mode" "QI")])
1037
1038 ;; These implement float point compares.
1039 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1040 ;; which would allow mix and match FP modes on the compares.  Which is what
1041 ;; the old patterns did, but with many more of them.
1042
1043 (define_expand "cbranchxf4"
1044   [(set (reg:CC FLAGS_REG)
1045         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1046                     (match_operand:XF 2 "nonmemory_operand" "")))
1047    (set (pc) (if_then_else
1048               (match_operator 0 "ix86_fp_comparison_operator"
1049                [(reg:CC FLAGS_REG)
1050                 (const_int 0)])
1051               (label_ref (match_operand 3 "" ""))
1052               (pc)))]
1053   "TARGET_80387"
1054 {
1055   ix86_compare_op0 = operands[1];
1056   ix86_compare_op1 = operands[2];
1057   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1058   DONE;
1059 })
1060
1061 (define_expand "cstorexf4"
1062   [(set (reg:CC FLAGS_REG)
1063         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1064                     (match_operand:XF 3 "nonmemory_operand" "")))
1065    (set (match_operand:QI 0 "register_operand" "")
1066               (match_operator 1 "ix86_fp_comparison_operator"
1067                [(reg:CC FLAGS_REG)
1068                 (const_int 0)]))]
1069   "TARGET_80387"
1070 {
1071   ix86_compare_op0 = operands[2];
1072   ix86_compare_op1 = operands[3];
1073   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1074   DONE;
1075 })
1076
1077 (define_expand "cbranch<mode>4"
1078   [(set (reg:CC FLAGS_REG)
1079         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1080                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1081    (set (pc) (if_then_else
1082               (match_operator 0 "ix86_fp_comparison_operator"
1083                [(reg:CC FLAGS_REG)
1084                 (const_int 0)])
1085               (label_ref (match_operand 3 "" ""))
1086               (pc)))]
1087   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1088 {
1089   ix86_compare_op0 = operands[1];
1090   ix86_compare_op1 = operands[2];
1091   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1092   DONE;
1093 })
1094
1095 (define_expand "cstore<mode>4"
1096   [(set (reg:CC FLAGS_REG)
1097         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1098                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1099    (set (match_operand:QI 0 "register_operand" "")
1100               (match_operator 1 "ix86_fp_comparison_operator"
1101                [(reg:CC FLAGS_REG)
1102                 (const_int 0)]))]
1103   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1104 {
1105   ix86_compare_op0 = operands[2];
1106   ix86_compare_op1 = operands[3];
1107   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1108   DONE;
1109 })
1110
1111 (define_expand "cbranchcc4"
1112   [(set (pc) (if_then_else
1113               (match_operator 0 "comparison_operator"
1114                [(match_operand 1 "flags_reg_operand" "")
1115                 (match_operand 2 "const0_operand" "")])
1116               (label_ref (match_operand 3 "" ""))
1117               (pc)))]
1118   ""
1119 {
1120   ix86_compare_op0 = operands[1];
1121   ix86_compare_op1 = operands[2];
1122   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1123   DONE;
1124 })
1125
1126 (define_expand "cstorecc4"
1127   [(set (match_operand:QI 0 "register_operand" "")
1128               (match_operator 1 "comparison_operator"
1129                [(match_operand 2 "flags_reg_operand" "")
1130                 (match_operand 3 "const0_operand" "")]))]
1131   ""
1132 {
1133   ix86_compare_op0 = operands[2];
1134   ix86_compare_op1 = operands[3];
1135   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1136   DONE;
1137 })
1138
1139
1140 ;; FP compares, step 1:
1141 ;; Set the FP condition codes.
1142 ;;
1143 ;; CCFPmode     compare with exceptions
1144 ;; CCFPUmode    compare with no exceptions
1145
1146 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1147 ;; used to manage the reg stack popping would not be preserved.
1148
1149 (define_insn "*cmpfp_0"
1150   [(set (match_operand:HI 0 "register_operand" "=a")
1151         (unspec:HI
1152           [(compare:CCFP
1153              (match_operand 1 "register_operand" "f")
1154              (match_operand 2 "const0_operand" ""))]
1155         UNSPEC_FNSTSW))]
1156   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1157    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1158   "* return output_fp_compare (insn, operands, 0, 0);"
1159   [(set_attr "type" "multi")
1160    (set_attr "unit" "i387")
1161    (set (attr "mode")
1162      (cond [(match_operand:SF 1 "" "")
1163               (const_string "SF")
1164             (match_operand:DF 1 "" "")
1165               (const_string "DF")
1166            ]
1167            (const_string "XF")))])
1168
1169 (define_insn_and_split "*cmpfp_0_cc"
1170   [(set (reg:CCFP FLAGS_REG)
1171         (compare:CCFP
1172           (match_operand 1 "register_operand" "f")
1173           (match_operand 2 "const0_operand" "")))
1174    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1175   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1176    && TARGET_SAHF && !TARGET_CMOVE
1177    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1178   "#"
1179   "&& reload_completed"
1180   [(set (match_dup 0)
1181         (unspec:HI
1182           [(compare:CCFP (match_dup 1)(match_dup 2))]
1183         UNSPEC_FNSTSW))
1184    (set (reg:CC FLAGS_REG)
1185         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1186   ""
1187   [(set_attr "type" "multi")
1188    (set_attr "unit" "i387")
1189    (set (attr "mode")
1190      (cond [(match_operand:SF 1 "" "")
1191               (const_string "SF")
1192             (match_operand:DF 1 "" "")
1193               (const_string "DF")
1194            ]
1195            (const_string "XF")))])
1196
1197 (define_insn "*cmpfp_xf"
1198   [(set (match_operand:HI 0 "register_operand" "=a")
1199         (unspec:HI
1200           [(compare:CCFP
1201              (match_operand:XF 1 "register_operand" "f")
1202              (match_operand:XF 2 "register_operand" "f"))]
1203           UNSPEC_FNSTSW))]
1204   "TARGET_80387"
1205   "* return output_fp_compare (insn, operands, 0, 0);"
1206   [(set_attr "type" "multi")
1207    (set_attr "unit" "i387")
1208    (set_attr "mode" "XF")])
1209
1210 (define_insn_and_split "*cmpfp_xf_cc"
1211   [(set (reg:CCFP FLAGS_REG)
1212         (compare:CCFP
1213           (match_operand:XF 1 "register_operand" "f")
1214           (match_operand:XF 2 "register_operand" "f")))
1215    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1216   "TARGET_80387
1217    && TARGET_SAHF && !TARGET_CMOVE"
1218   "#"
1219   "&& reload_completed"
1220   [(set (match_dup 0)
1221         (unspec:HI
1222           [(compare:CCFP (match_dup 1)(match_dup 2))]
1223         UNSPEC_FNSTSW))
1224    (set (reg:CC FLAGS_REG)
1225         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1226   ""
1227   [(set_attr "type" "multi")
1228    (set_attr "unit" "i387")
1229    (set_attr "mode" "XF")])
1230
1231 (define_insn "*cmpfp_<mode>"
1232   [(set (match_operand:HI 0 "register_operand" "=a")
1233         (unspec:HI
1234           [(compare:CCFP
1235              (match_operand:MODEF 1 "register_operand" "f")
1236              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1237           UNSPEC_FNSTSW))]
1238   "TARGET_80387"
1239   "* return output_fp_compare (insn, operands, 0, 0);"
1240   [(set_attr "type" "multi")
1241    (set_attr "unit" "i387")
1242    (set_attr "mode" "<MODE>")])
1243
1244 (define_insn_and_split "*cmpfp_<mode>_cc"
1245   [(set (reg:CCFP FLAGS_REG)
1246         (compare:CCFP
1247           (match_operand:MODEF 1 "register_operand" "f")
1248           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1249    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250   "TARGET_80387
1251    && TARGET_SAHF && !TARGET_CMOVE"
1252   "#"
1253   "&& reload_completed"
1254   [(set (match_dup 0)
1255         (unspec:HI
1256           [(compare:CCFP (match_dup 1)(match_dup 2))]
1257         UNSPEC_FNSTSW))
1258    (set (reg:CC FLAGS_REG)
1259         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260   ""
1261   [(set_attr "type" "multi")
1262    (set_attr "unit" "i387")
1263    (set_attr "mode" "<MODE>")])
1264
1265 (define_insn "*cmpfp_u"
1266   [(set (match_operand:HI 0 "register_operand" "=a")
1267         (unspec:HI
1268           [(compare:CCFPU
1269              (match_operand 1 "register_operand" "f")
1270              (match_operand 2 "register_operand" "f"))]
1271           UNSPEC_FNSTSW))]
1272   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1273    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1274   "* return output_fp_compare (insn, operands, 0, 1);"
1275   [(set_attr "type" "multi")
1276    (set_attr "unit" "i387")
1277    (set (attr "mode")
1278      (cond [(match_operand:SF 1 "" "")
1279               (const_string "SF")
1280             (match_operand:DF 1 "" "")
1281               (const_string "DF")
1282            ]
1283            (const_string "XF")))])
1284
1285 (define_insn_and_split "*cmpfp_u_cc"
1286   [(set (reg:CCFPU FLAGS_REG)
1287         (compare:CCFPU
1288           (match_operand 1 "register_operand" "f")
1289           (match_operand 2 "register_operand" "f")))
1290    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1291   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1292    && TARGET_SAHF && !TARGET_CMOVE
1293    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1294   "#"
1295   "&& reload_completed"
1296   [(set (match_dup 0)
1297         (unspec:HI
1298           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1299         UNSPEC_FNSTSW))
1300    (set (reg:CC FLAGS_REG)
1301         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302   ""
1303   [(set_attr "type" "multi")
1304    (set_attr "unit" "i387")
1305    (set (attr "mode")
1306      (cond [(match_operand:SF 1 "" "")
1307               (const_string "SF")
1308             (match_operand:DF 1 "" "")
1309               (const_string "DF")
1310            ]
1311            (const_string "XF")))])
1312
1313 (define_insn "*cmpfp_<mode>"
1314   [(set (match_operand:HI 0 "register_operand" "=a")
1315         (unspec:HI
1316           [(compare:CCFP
1317              (match_operand 1 "register_operand" "f")
1318              (match_operator 3 "float_operator"
1319                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1320           UNSPEC_FNSTSW))]
1321   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1322    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1323    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1324   "* return output_fp_compare (insn, operands, 0, 0);"
1325   [(set_attr "type" "multi")
1326    (set_attr "unit" "i387")
1327    (set_attr "fp_int_src" "true")
1328    (set_attr "mode" "<MODE>")])
1329
1330 (define_insn_and_split "*cmpfp_<mode>_cc"
1331   [(set (reg:CCFP FLAGS_REG)
1332         (compare:CCFP
1333           (match_operand 1 "register_operand" "f")
1334           (match_operator 3 "float_operator"
1335             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1336    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1337   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1338    && TARGET_SAHF && !TARGET_CMOVE
1339    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1340    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1341   "#"
1342   "&& reload_completed"
1343   [(set (match_dup 0)
1344         (unspec:HI
1345           [(compare:CCFP
1346              (match_dup 1)
1347              (match_op_dup 3 [(match_dup 2)]))]
1348         UNSPEC_FNSTSW))
1349    (set (reg:CC FLAGS_REG)
1350         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351   ""
1352   [(set_attr "type" "multi")
1353    (set_attr "unit" "i387")
1354    (set_attr "fp_int_src" "true")
1355    (set_attr "mode" "<MODE>")])
1356
1357 ;; FP compares, step 2
1358 ;; Move the fpsw to ax.
1359
1360 (define_insn "x86_fnstsw_1"
1361   [(set (match_operand:HI 0 "register_operand" "=a")
1362         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1363   "TARGET_80387"
1364   "fnstsw\t%0"
1365   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1366    (set_attr "mode" "SI")
1367    (set_attr "unit" "i387")])
1368
1369 ;; FP compares, step 3
1370 ;; Get ax into flags, general case.
1371
1372 (define_insn "x86_sahf_1"
1373   [(set (reg:CC FLAGS_REG)
1374         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1375                    UNSPEC_SAHF))]
1376   "TARGET_SAHF"
1377 {
1378 #ifdef HAVE_AS_IX86_SAHF
1379   return "sahf";
1380 #else
1381   return ASM_BYTE "0x9e";
1382 #endif
1383 }
1384   [(set_attr "length" "1")
1385    (set_attr "athlon_decode" "vector")
1386    (set_attr "amdfam10_decode" "direct")
1387    (set_attr "mode" "SI")])
1388
1389 ;; Pentium Pro can do steps 1 through 3 in one go.
1390 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1391 (define_insn "*cmpfp_i_mixed"
1392   [(set (reg:CCFP FLAGS_REG)
1393         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1394                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1395   "TARGET_MIX_SSE_I387
1396    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1397    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1398   "* return output_fp_compare (insn, operands, 1, 0);"
1399   [(set_attr "type" "fcmp,ssecomi")
1400    (set_attr "prefix" "orig,maybe_vex")
1401    (set (attr "mode")
1402      (if_then_else (match_operand:SF 1 "" "")
1403         (const_string "SF")
1404         (const_string "DF")))
1405    (set (attr "prefix_rep")
1406         (if_then_else (eq_attr "type" "ssecomi")
1407                       (const_string "0")
1408                       (const_string "*")))
1409    (set (attr "prefix_data16")
1410         (cond [(eq_attr "type" "fcmp")
1411                  (const_string "*")
1412                (eq_attr "mode" "DF")
1413                  (const_string "1")
1414               ]
1415               (const_string "0")))
1416    (set_attr "athlon_decode" "vector")
1417    (set_attr "amdfam10_decode" "direct")])
1418
1419 (define_insn "*cmpfp_i_sse"
1420   [(set (reg:CCFP FLAGS_REG)
1421         (compare:CCFP (match_operand 0 "register_operand" "x")
1422                       (match_operand 1 "nonimmediate_operand" "xm")))]
1423   "TARGET_SSE_MATH
1424    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1425    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426   "* return output_fp_compare (insn, operands, 1, 0);"
1427   [(set_attr "type" "ssecomi")
1428    (set_attr "prefix" "maybe_vex")
1429    (set (attr "mode")
1430      (if_then_else (match_operand:SF 1 "" "")
1431         (const_string "SF")
1432         (const_string "DF")))
1433    (set_attr "prefix_rep" "0")
1434    (set (attr "prefix_data16")
1435         (if_then_else (eq_attr "mode" "DF")
1436                       (const_string "1")
1437                       (const_string "0")))
1438    (set_attr "athlon_decode" "vector")
1439    (set_attr "amdfam10_decode" "direct")])
1440
1441 (define_insn "*cmpfp_i_i387"
1442   [(set (reg:CCFP FLAGS_REG)
1443         (compare:CCFP (match_operand 0 "register_operand" "f")
1444                       (match_operand 1 "register_operand" "f")))]
1445   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1446    && TARGET_CMOVE
1447    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1448    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1449   "* return output_fp_compare (insn, operands, 1, 0);"
1450   [(set_attr "type" "fcmp")
1451    (set (attr "mode")
1452      (cond [(match_operand:SF 1 "" "")
1453               (const_string "SF")
1454             (match_operand:DF 1 "" "")
1455               (const_string "DF")
1456            ]
1457            (const_string "XF")))
1458    (set_attr "athlon_decode" "vector")
1459    (set_attr "amdfam10_decode" "direct")])
1460
1461 (define_insn "*cmpfp_iu_mixed"
1462   [(set (reg:CCFPU FLAGS_REG)
1463         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1464                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1465   "TARGET_MIX_SSE_I387
1466    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1467    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1468   "* return output_fp_compare (insn, operands, 1, 1);"
1469   [(set_attr "type" "fcmp,ssecomi")
1470    (set_attr "prefix" "orig,maybe_vex")
1471    (set (attr "mode")
1472      (if_then_else (match_operand:SF 1 "" "")
1473         (const_string "SF")
1474         (const_string "DF")))
1475    (set (attr "prefix_rep")
1476         (if_then_else (eq_attr "type" "ssecomi")
1477                       (const_string "0")
1478                       (const_string "*")))
1479    (set (attr "prefix_data16")
1480         (cond [(eq_attr "type" "fcmp")
1481                  (const_string "*")
1482                (eq_attr "mode" "DF")
1483                  (const_string "1")
1484               ]
1485               (const_string "0")))
1486    (set_attr "athlon_decode" "vector")
1487    (set_attr "amdfam10_decode" "direct")])
1488
1489 (define_insn "*cmpfp_iu_sse"
1490   [(set (reg:CCFPU FLAGS_REG)
1491         (compare:CCFPU (match_operand 0 "register_operand" "x")
1492                        (match_operand 1 "nonimmediate_operand" "xm")))]
1493   "TARGET_SSE_MATH
1494    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1495    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1496   "* return output_fp_compare (insn, operands, 1, 1);"
1497   [(set_attr "type" "ssecomi")
1498    (set_attr "prefix" "maybe_vex")
1499    (set (attr "mode")
1500      (if_then_else (match_operand:SF 1 "" "")
1501         (const_string "SF")
1502         (const_string "DF")))
1503    (set_attr "prefix_rep" "0")
1504    (set (attr "prefix_data16")
1505         (if_then_else (eq_attr "mode" "DF")
1506                       (const_string "1")
1507                       (const_string "0")))
1508    (set_attr "athlon_decode" "vector")
1509    (set_attr "amdfam10_decode" "direct")])
1510
1511 (define_insn "*cmpfp_iu_387"
1512   [(set (reg:CCFPU FLAGS_REG)
1513         (compare:CCFPU (match_operand 0 "register_operand" "f")
1514                        (match_operand 1 "register_operand" "f")))]
1515   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1516    && TARGET_CMOVE
1517    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1518    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1519   "* return output_fp_compare (insn, operands, 1, 1);"
1520   [(set_attr "type" "fcmp")
1521    (set (attr "mode")
1522      (cond [(match_operand:SF 1 "" "")
1523               (const_string "SF")
1524             (match_operand:DF 1 "" "")
1525               (const_string "DF")
1526            ]
1527            (const_string "XF")))
1528    (set_attr "athlon_decode" "vector")
1529    (set_attr "amdfam10_decode" "direct")])
1530 \f
1531 ;; Move instructions.
1532
1533 ;; General case of fullword move.
1534
1535 (define_expand "movsi"
1536   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1537         (match_operand:SI 1 "general_operand" ""))]
1538   ""
1539   "ix86_expand_move (SImode, operands); DONE;")
1540
1541 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1542 ;; general_operand.
1543 ;;
1544 ;; %%% We don't use a post-inc memory reference because x86 is not a
1545 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1546 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1547 ;; targets without our curiosities, and it is just as easy to represent
1548 ;; this differently.
1549
1550 (define_insn "*pushsi2"
1551   [(set (match_operand:SI 0 "push_operand" "=<")
1552         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1553   "!TARGET_64BIT"
1554   "push{l}\t%1"
1555   [(set_attr "type" "push")
1556    (set_attr "mode" "SI")])
1557
1558 ;; For 64BIT abi we always round up to 8 bytes.
1559 (define_insn "*pushsi2_rex64"
1560   [(set (match_operand:SI 0 "push_operand" "=X")
1561         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1562   "TARGET_64BIT"
1563   "push{q}\t%q1"
1564   [(set_attr "type" "push")
1565    (set_attr "mode" "SI")])
1566
1567 (define_insn "*pushsi2_prologue"
1568   [(set (match_operand:SI 0 "push_operand" "=<")
1569         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1570    (clobber (mem:BLK (scratch)))]
1571   "!TARGET_64BIT"
1572   "push{l}\t%1"
1573   [(set_attr "type" "push")
1574    (set_attr "mode" "SI")])
1575
1576 (define_insn "*popsi1_epilogue"
1577   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1578         (mem:SI (reg:SI SP_REG)))
1579    (set (reg:SI SP_REG)
1580         (plus:SI (reg:SI SP_REG) (const_int 4)))
1581    (clobber (mem:BLK (scratch)))]
1582   "!TARGET_64BIT"
1583   "pop{l}\t%0"
1584   [(set_attr "type" "pop")
1585    (set_attr "mode" "SI")])
1586
1587 (define_insn "popsi1"
1588   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1589         (mem:SI (reg:SI SP_REG)))
1590    (set (reg:SI SP_REG)
1591         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1592   "!TARGET_64BIT"
1593   "pop{l}\t%0"
1594   [(set_attr "type" "pop")
1595    (set_attr "mode" "SI")])
1596
1597 (define_insn "*movsi_xor"
1598   [(set (match_operand:SI 0 "register_operand" "=r")
1599         (match_operand:SI 1 "const0_operand" ""))
1600    (clobber (reg:CC FLAGS_REG))]
1601   "reload_completed"
1602   "xor{l}\t%0, %0"
1603   [(set_attr "type" "alu1")
1604    (set_attr "mode" "SI")
1605    (set_attr "length_immediate" "0")])
1606
1607 (define_insn "*movsi_or"
1608   [(set (match_operand:SI 0 "register_operand" "=r")
1609         (match_operand:SI 1 "immediate_operand" "i"))
1610    (clobber (reg:CC FLAGS_REG))]
1611   "reload_completed
1612    && operands[1] == constm1_rtx"
1613 {
1614   operands[1] = constm1_rtx;
1615   return "or{l}\t{%1, %0|%0, %1}";
1616 }
1617   [(set_attr "type" "alu1")
1618    (set_attr "mode" "SI")
1619    (set_attr "length_immediate" "1")])
1620
1621 (define_insn "*movsi_1"
1622   [(set (match_operand:SI 0 "nonimmediate_operand"
1623                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1624         (match_operand:SI 1 "general_operand"
1625                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1626   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627 {
1628   switch (get_attr_type (insn))
1629     {
1630     case TYPE_SSELOG1:
1631       if (get_attr_mode (insn) == MODE_TI)
1632         return "%vpxor\t%0, %d0";
1633       return "%vxorps\t%0, %d0";
1634
1635     case TYPE_SSEMOV:
1636       switch (get_attr_mode (insn))
1637         {
1638         case MODE_TI:
1639           return "%vmovdqa\t{%1, %0|%0, %1}";
1640         case MODE_V4SF:
1641           return "%vmovaps\t{%1, %0|%0, %1}";
1642         case MODE_SI:
1643           return "%vmovd\t{%1, %0|%0, %1}";
1644         case MODE_SF:
1645           return "%vmovss\t{%1, %0|%0, %1}";
1646         default:
1647           gcc_unreachable ();
1648         }
1649
1650     case TYPE_MMX:
1651       return "pxor\t%0, %0";
1652
1653     case TYPE_MMXMOV:
1654       if (get_attr_mode (insn) == MODE_DI)
1655         return "movq\t{%1, %0|%0, %1}";
1656       return "movd\t{%1, %0|%0, %1}";
1657
1658     case TYPE_LEA:
1659       return "lea{l}\t{%1, %0|%0, %1}";
1660
1661     default:
1662       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1663       return "mov{l}\t{%1, %0|%0, %1}";
1664     }
1665 }
1666   [(set (attr "type")
1667      (cond [(eq_attr "alternative" "2")
1668               (const_string "mmx")
1669             (eq_attr "alternative" "3,4,5")
1670               (const_string "mmxmov")
1671             (eq_attr "alternative" "6")
1672               (const_string "sselog1")
1673             (eq_attr "alternative" "7,8,9,10,11")
1674               (const_string "ssemov")
1675             (match_operand:DI 1 "pic_32bit_operand" "")
1676               (const_string "lea")
1677            ]
1678            (const_string "imov")))
1679    (set (attr "prefix")
1680      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1681        (const_string "orig")
1682        (const_string "maybe_vex")))
1683    (set (attr "prefix_data16")
1684      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1685        (const_string "1")
1686        (const_string "*")))
1687    (set (attr "mode")
1688      (cond [(eq_attr "alternative" "2,3")
1689               (const_string "DI")
1690             (eq_attr "alternative" "6,7")
1691               (if_then_else
1692                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1693                 (const_string "V4SF")
1694                 (const_string "TI"))
1695             (and (eq_attr "alternative" "8,9,10,11")
1696                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1697               (const_string "SF")
1698            ]
1699            (const_string "SI")))])
1700
1701 ;; Stores and loads of ax to arbitrary constant address.
1702 ;; We fake an second form of instruction to force reload to load address
1703 ;; into register when rax is not available
1704 (define_insn "*movabssi_1_rex64"
1705   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1706         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1707   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1708   "@
1709    movabs{l}\t{%1, %P0|%P0, %1}
1710    mov{l}\t{%1, %a0|%a0, %1}"
1711   [(set_attr "type" "imov")
1712    (set_attr "modrm" "0,*")
1713    (set_attr "length_address" "8,0")
1714    (set_attr "length_immediate" "0,*")
1715    (set_attr "memory" "store")
1716    (set_attr "mode" "SI")])
1717
1718 (define_insn "*movabssi_2_rex64"
1719   [(set (match_operand:SI 0 "register_operand" "=a,r")
1720         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1721   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1722   "@
1723    movabs{l}\t{%P1, %0|%0, %P1}
1724    mov{l}\t{%a1, %0|%0, %a1}"
1725   [(set_attr "type" "imov")
1726    (set_attr "modrm" "0,*")
1727    (set_attr "length_address" "8,0")
1728    (set_attr "length_immediate" "0")
1729    (set_attr "memory" "load")
1730    (set_attr "mode" "SI")])
1731
1732 (define_insn "*swapsi"
1733   [(set (match_operand:SI 0 "register_operand" "+r")
1734         (match_operand:SI 1 "register_operand" "+r"))
1735    (set (match_dup 1)
1736         (match_dup 0))]
1737   ""
1738   "xchg{l}\t%1, %0"
1739   [(set_attr "type" "imov")
1740    (set_attr "mode" "SI")
1741    (set_attr "pent_pair" "np")
1742    (set_attr "athlon_decode" "vector")
1743    (set_attr "amdfam10_decode" "double")])
1744
1745 (define_expand "movhi"
1746   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1747         (match_operand:HI 1 "general_operand" ""))]
1748   ""
1749   "ix86_expand_move (HImode, operands); DONE;")
1750
1751 (define_insn "*pushhi2"
1752   [(set (match_operand:HI 0 "push_operand" "=X")
1753         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1754   "!TARGET_64BIT"
1755   "push{l}\t%k1"
1756   [(set_attr "type" "push")
1757    (set_attr "mode" "SI")])
1758
1759 ;; For 64BIT abi we always round up to 8 bytes.
1760 (define_insn "*pushhi2_rex64"
1761   [(set (match_operand:HI 0 "push_operand" "=X")
1762         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1763   "TARGET_64BIT"
1764   "push{q}\t%q1"
1765   [(set_attr "type" "push")
1766    (set_attr "mode" "DI")])
1767
1768 (define_insn "*movhi_1"
1769   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1770         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1771   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1772 {
1773   switch (get_attr_type (insn))
1774     {
1775     case TYPE_IMOVX:
1776       /* movzwl is faster than movw on p2 due to partial word stalls,
1777          though not as fast as an aligned movl.  */
1778       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1779     default:
1780       if (get_attr_mode (insn) == MODE_SI)
1781         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1782       else
1783         return "mov{w}\t{%1, %0|%0, %1}";
1784     }
1785 }
1786   [(set (attr "type")
1787      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1788               (const_string "imov")
1789             (and (eq_attr "alternative" "0")
1790                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1791                           (const_int 0))
1792                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1793                           (const_int 0))))
1794               (const_string "imov")
1795             (and (eq_attr "alternative" "1,2")
1796                  (match_operand:HI 1 "aligned_operand" ""))
1797               (const_string "imov")
1798             (and (ne (symbol_ref "TARGET_MOVX")
1799                      (const_int 0))
1800                  (eq_attr "alternative" "0,2"))
1801               (const_string "imovx")
1802            ]
1803            (const_string "imov")))
1804     (set (attr "mode")
1805       (cond [(eq_attr "type" "imovx")
1806                (const_string "SI")
1807              (and (eq_attr "alternative" "1,2")
1808                   (match_operand:HI 1 "aligned_operand" ""))
1809                (const_string "SI")
1810              (and (eq_attr "alternative" "0")
1811                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1812                            (const_int 0))
1813                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1814                            (const_int 0))))
1815                (const_string "SI")
1816             ]
1817             (const_string "HI")))])
1818
1819 ;; Stores and loads of ax to arbitrary constant address.
1820 ;; We fake an second form of instruction to force reload to load address
1821 ;; into register when rax is not available
1822 (define_insn "*movabshi_1_rex64"
1823   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1824         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1825   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1826   "@
1827    movabs{w}\t{%1, %P0|%P0, %1}
1828    mov{w}\t{%1, %a0|%a0, %1}"
1829   [(set_attr "type" "imov")
1830    (set_attr "modrm" "0,*")
1831    (set_attr "length_address" "8,0")
1832    (set_attr "length_immediate" "0,*")
1833    (set_attr "memory" "store")
1834    (set_attr "mode" "HI")])
1835
1836 (define_insn "*movabshi_2_rex64"
1837   [(set (match_operand:HI 0 "register_operand" "=a,r")
1838         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1839   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1840   "@
1841    movabs{w}\t{%P1, %0|%0, %P1}
1842    mov{w}\t{%a1, %0|%0, %a1}"
1843   [(set_attr "type" "imov")
1844    (set_attr "modrm" "0,*")
1845    (set_attr "length_address" "8,0")
1846    (set_attr "length_immediate" "0")
1847    (set_attr "memory" "load")
1848    (set_attr "mode" "HI")])
1849
1850 (define_insn "*swaphi_1"
1851   [(set (match_operand:HI 0 "register_operand" "+r")
1852         (match_operand:HI 1 "register_operand" "+r"))
1853    (set (match_dup 1)
1854         (match_dup 0))]
1855   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1856   "xchg{l}\t%k1, %k0"
1857   [(set_attr "type" "imov")
1858    (set_attr "mode" "SI")
1859    (set_attr "pent_pair" "np")
1860    (set_attr "athlon_decode" "vector")
1861    (set_attr "amdfam10_decode" "double")])
1862
1863 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1864 (define_insn "*swaphi_2"
1865   [(set (match_operand:HI 0 "register_operand" "+r")
1866         (match_operand:HI 1 "register_operand" "+r"))
1867    (set (match_dup 1)
1868         (match_dup 0))]
1869   "TARGET_PARTIAL_REG_STALL"
1870   "xchg{w}\t%1, %0"
1871   [(set_attr "type" "imov")
1872    (set_attr "mode" "HI")
1873    (set_attr "pent_pair" "np")
1874    (set_attr "athlon_decode" "vector")])
1875
1876 (define_expand "movstricthi"
1877   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1878         (match_operand:HI 1 "general_operand" ""))]
1879   ""
1880 {
1881   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1882     FAIL;
1883   /* Don't generate memory->memory moves, go through a register */
1884   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1885     operands[1] = force_reg (HImode, operands[1]);
1886 })
1887
1888 (define_insn "*movstricthi_1"
1889   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1890         (match_operand:HI 1 "general_operand" "rn,m"))]
1891   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1892    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1893   "mov{w}\t{%1, %0|%0, %1}"
1894   [(set_attr "type" "imov")
1895    (set_attr "mode" "HI")])
1896
1897 (define_insn "*movstricthi_xor"
1898   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1899         (match_operand:HI 1 "const0_operand" ""))
1900    (clobber (reg:CC FLAGS_REG))]
1901   "reload_completed"
1902   "xor{w}\t%0, %0"
1903   [(set_attr "type" "alu1")
1904    (set_attr "mode" "HI")
1905    (set_attr "length_immediate" "0")])
1906
1907 (define_expand "movqi"
1908   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1909         (match_operand:QI 1 "general_operand" ""))]
1910   ""
1911   "ix86_expand_move (QImode, operands); DONE;")
1912
1913 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1914 ;; "push a byte".  But actually we use pushl, which has the effect
1915 ;; of rounding the amount pushed up to a word.
1916
1917 (define_insn "*pushqi2"
1918   [(set (match_operand:QI 0 "push_operand" "=X")
1919         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1920   "!TARGET_64BIT"
1921   "push{l}\t%k1"
1922   [(set_attr "type" "push")
1923    (set_attr "mode" "SI")])
1924
1925 ;; For 64BIT abi we always round up to 8 bytes.
1926 (define_insn "*pushqi2_rex64"
1927   [(set (match_operand:QI 0 "push_operand" "=X")
1928         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1929   "TARGET_64BIT"
1930   "push{q}\t%q1"
1931   [(set_attr "type" "push")
1932    (set_attr "mode" "DI")])
1933
1934 ;; Situation is quite tricky about when to choose full sized (SImode) move
1935 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1936 ;; partial register dependency machines (such as AMD Athlon), where QImode
1937 ;; moves issue extra dependency and for partial register stalls machines
1938 ;; that don't use QImode patterns (and QImode move cause stall on the next
1939 ;; instruction).
1940 ;;
1941 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1942 ;; register stall machines with, where we use QImode instructions, since
1943 ;; partial register stall can be caused there.  Then we use movzx.
1944 (define_insn "*movqi_1"
1945   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1946         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1947   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 {
1949   switch (get_attr_type (insn))
1950     {
1951     case TYPE_IMOVX:
1952       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1953       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1954     default:
1955       if (get_attr_mode (insn) == MODE_SI)
1956         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1957       else
1958         return "mov{b}\t{%1, %0|%0, %1}";
1959     }
1960 }
1961   [(set (attr "type")
1962      (cond [(and (eq_attr "alternative" "5")
1963                  (not (match_operand:QI 1 "aligned_operand" "")))
1964               (const_string "imovx")
1965             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1966               (const_string "imov")
1967             (and (eq_attr "alternative" "3")
1968                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1969                           (const_int 0))
1970                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1971                           (const_int 0))))
1972               (const_string "imov")
1973             (eq_attr "alternative" "3,5")
1974               (const_string "imovx")
1975             (and (ne (symbol_ref "TARGET_MOVX")
1976                      (const_int 0))
1977                  (eq_attr "alternative" "2"))
1978               (const_string "imovx")
1979            ]
1980            (const_string "imov")))
1981    (set (attr "mode")
1982       (cond [(eq_attr "alternative" "3,4,5")
1983                (const_string "SI")
1984              (eq_attr "alternative" "6")
1985                (const_string "QI")
1986              (eq_attr "type" "imovx")
1987                (const_string "SI")
1988              (and (eq_attr "type" "imov")
1989                   (and (eq_attr "alternative" "0,1")
1990                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1991                                 (const_int 0))
1992                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1993                                      (const_int 0))
1994                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1995                                      (const_int 0))))))
1996                (const_string "SI")
1997              ;; Avoid partial register stalls when not using QImode arithmetic
1998              (and (eq_attr "type" "imov")
1999                   (and (eq_attr "alternative" "0,1")
2000                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2001                                 (const_int 0))
2002                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2003                                 (const_int 0)))))
2004                (const_string "SI")
2005            ]
2006            (const_string "QI")))])
2007
2008 (define_insn "*swapqi_1"
2009   [(set (match_operand:QI 0 "register_operand" "+r")
2010         (match_operand:QI 1 "register_operand" "+r"))
2011    (set (match_dup 1)
2012         (match_dup 0))]
2013   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2014   "xchg{l}\t%k1, %k0"
2015   [(set_attr "type" "imov")
2016    (set_attr "mode" "SI")
2017    (set_attr "pent_pair" "np")
2018    (set_attr "athlon_decode" "vector")
2019    (set_attr "amdfam10_decode" "vector")])
2020
2021 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2022 (define_insn "*swapqi_2"
2023   [(set (match_operand:QI 0 "register_operand" "+q")
2024         (match_operand:QI 1 "register_operand" "+q"))
2025    (set (match_dup 1)
2026         (match_dup 0))]
2027   "TARGET_PARTIAL_REG_STALL"
2028   "xchg{b}\t%1, %0"
2029   [(set_attr "type" "imov")
2030    (set_attr "mode" "QI")
2031    (set_attr "pent_pair" "np")
2032    (set_attr "athlon_decode" "vector")])
2033
2034 (define_expand "movstrictqi"
2035   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2036         (match_operand:QI 1 "general_operand" ""))]
2037   ""
2038 {
2039   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2040     FAIL;
2041   /* Don't generate memory->memory moves, go through a register.  */
2042   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2043     operands[1] = force_reg (QImode, operands[1]);
2044 })
2045
2046 (define_insn "*movstrictqi_1"
2047   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2048         (match_operand:QI 1 "general_operand" "*qn,m"))]
2049   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2050    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2051   "mov{b}\t{%1, %0|%0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "mode" "QI")])
2054
2055 (define_insn "*movstrictqi_xor"
2056   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2057         (match_operand:QI 1 "const0_operand" ""))
2058    (clobber (reg:CC FLAGS_REG))]
2059   "reload_completed"
2060   "xor{b}\t%0, %0"
2061   [(set_attr "type" "alu1")
2062    (set_attr "mode" "QI")
2063    (set_attr "length_immediate" "0")])
2064
2065 (define_insn "*movsi_extv_1"
2066   [(set (match_operand:SI 0 "register_operand" "=R")
2067         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2068                          (const_int 8)
2069                          (const_int 8)))]
2070   ""
2071   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2072   [(set_attr "type" "imovx")
2073    (set_attr "mode" "SI")])
2074
2075 (define_insn "*movhi_extv_1"
2076   [(set (match_operand:HI 0 "register_operand" "=R")
2077         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2078                          (const_int 8)
2079                          (const_int 8)))]
2080   ""
2081   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2082   [(set_attr "type" "imovx")
2083    (set_attr "mode" "SI")])
2084
2085 (define_insn "*movqi_extv_1"
2086   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2087         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2088                          (const_int 8)
2089                          (const_int 8)))]
2090   "!TARGET_64BIT"
2091 {
2092   switch (get_attr_type (insn))
2093     {
2094     case TYPE_IMOVX:
2095       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2096     default:
2097       return "mov{b}\t{%h1, %0|%0, %h1}";
2098     }
2099 }
2100   [(set (attr "type")
2101      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2102                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2103                              (ne (symbol_ref "TARGET_MOVX")
2104                                  (const_int 0))))
2105         (const_string "imovx")
2106         (const_string "imov")))
2107    (set (attr "mode")
2108      (if_then_else (eq_attr "type" "imovx")
2109         (const_string "SI")
2110         (const_string "QI")))])
2111
2112 (define_insn "*movqi_extv_1_rex64"
2113   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2114         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2115                          (const_int 8)
2116                          (const_int 8)))]
2117   "TARGET_64BIT"
2118 {
2119   switch (get_attr_type (insn))
2120     {
2121     case TYPE_IMOVX:
2122       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2123     default:
2124       return "mov{b}\t{%h1, %0|%0, %h1}";
2125     }
2126 }
2127   [(set (attr "type")
2128      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2129                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2130                              (ne (symbol_ref "TARGET_MOVX")
2131                                  (const_int 0))))
2132         (const_string "imovx")
2133         (const_string "imov")))
2134    (set (attr "mode")
2135      (if_then_else (eq_attr "type" "imovx")
2136         (const_string "SI")
2137         (const_string "QI")))])
2138
2139 ;; Stores and loads of ax to arbitrary constant address.
2140 ;; We fake an second form of instruction to force reload to load address
2141 ;; into register when rax is not available
2142 (define_insn "*movabsqi_1_rex64"
2143   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2144         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2145   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2146   "@
2147    movabs{b}\t{%1, %P0|%P0, %1}
2148    mov{b}\t{%1, %a0|%a0, %1}"
2149   [(set_attr "type" "imov")
2150    (set_attr "modrm" "0,*")
2151    (set_attr "length_address" "8,0")
2152    (set_attr "length_immediate" "0,*")
2153    (set_attr "memory" "store")
2154    (set_attr "mode" "QI")])
2155
2156 (define_insn "*movabsqi_2_rex64"
2157   [(set (match_operand:QI 0 "register_operand" "=a,r")
2158         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2159   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2160   "@
2161    movabs{b}\t{%P1, %0|%0, %P1}
2162    mov{b}\t{%a1, %0|%0, %a1}"
2163   [(set_attr "type" "imov")
2164    (set_attr "modrm" "0,*")
2165    (set_attr "length_address" "8,0")
2166    (set_attr "length_immediate" "0")
2167    (set_attr "memory" "load")
2168    (set_attr "mode" "QI")])
2169
2170 (define_insn "*movdi_extzv_1"
2171   [(set (match_operand:DI 0 "register_operand" "=R")
2172         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2173                          (const_int 8)
2174                          (const_int 8)))]
2175   "TARGET_64BIT"
2176   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2177   [(set_attr "type" "imovx")
2178    (set_attr "mode" "SI")])
2179
2180 (define_insn "*movsi_extzv_1"
2181   [(set (match_operand:SI 0 "register_operand" "=R")
2182         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2183                          (const_int 8)
2184                          (const_int 8)))]
2185   ""
2186   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2187   [(set_attr "type" "imovx")
2188    (set_attr "mode" "SI")])
2189
2190 (define_insn "*movqi_extzv_2"
2191   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2192         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2193                                     (const_int 8)
2194                                     (const_int 8)) 0))]
2195   "!TARGET_64BIT"
2196 {
2197   switch (get_attr_type (insn))
2198     {
2199     case TYPE_IMOVX:
2200       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2201     default:
2202       return "mov{b}\t{%h1, %0|%0, %h1}";
2203     }
2204 }
2205   [(set (attr "type")
2206      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2207                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2208                              (ne (symbol_ref "TARGET_MOVX")
2209                                  (const_int 0))))
2210         (const_string "imovx")
2211         (const_string "imov")))
2212    (set (attr "mode")
2213      (if_then_else (eq_attr "type" "imovx")
2214         (const_string "SI")
2215         (const_string "QI")))])
2216
2217 (define_insn "*movqi_extzv_2_rex64"
2218   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2219         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2220                                     (const_int 8)
2221                                     (const_int 8)) 0))]
2222   "TARGET_64BIT"
2223 {
2224   switch (get_attr_type (insn))
2225     {
2226     case TYPE_IMOVX:
2227       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2228     default:
2229       return "mov{b}\t{%h1, %0|%0, %h1}";
2230     }
2231 }
2232   [(set (attr "type")
2233      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2234                         (ne (symbol_ref "TARGET_MOVX")
2235                             (const_int 0)))
2236         (const_string "imovx")
2237         (const_string "imov")))
2238    (set (attr "mode")
2239      (if_then_else (eq_attr "type" "imovx")
2240         (const_string "SI")
2241         (const_string "QI")))])
2242
2243 (define_insn "movsi_insv_1"
2244   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2245                          (const_int 8)
2246                          (const_int 8))
2247         (match_operand:SI 1 "general_operand" "Qmn"))]
2248   "!TARGET_64BIT"
2249   "mov{b}\t{%b1, %h0|%h0, %b1}"
2250   [(set_attr "type" "imov")
2251    (set_attr "mode" "QI")])
2252
2253 (define_insn "*movsi_insv_1_rex64"
2254   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2255                          (const_int 8)
2256                          (const_int 8))
2257         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2258   "TARGET_64BIT"
2259   "mov{b}\t{%b1, %h0|%h0, %b1}"
2260   [(set_attr "type" "imov")
2261    (set_attr "mode" "QI")])
2262
2263 (define_insn "movdi_insv_1_rex64"
2264   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2265                          (const_int 8)
2266                          (const_int 8))
2267         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2268   "TARGET_64BIT"
2269   "mov{b}\t{%b1, %h0|%h0, %b1}"
2270   [(set_attr "type" "imov")
2271    (set_attr "mode" "QI")])
2272
2273 (define_insn "*movqi_insv_2"
2274   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2275                          (const_int 8)
2276                          (const_int 8))
2277         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2278                      (const_int 8)))]
2279   ""
2280   "mov{b}\t{%h1, %h0|%h0, %h1}"
2281   [(set_attr "type" "imov")
2282    (set_attr "mode" "QI")])
2283
2284 (define_expand "movdi"
2285   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2286         (match_operand:DI 1 "general_operand" ""))]
2287   ""
2288   "ix86_expand_move (DImode, operands); DONE;")
2289
2290 (define_insn "*pushdi"
2291   [(set (match_operand:DI 0 "push_operand" "=<")
2292         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2293   "!TARGET_64BIT"
2294   "#")
2295
2296 (define_insn "*pushdi2_rex64"
2297   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2298         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2299   "TARGET_64BIT"
2300   "@
2301    push{q}\t%1
2302    #"
2303   [(set_attr "type" "push,multi")
2304    (set_attr "mode" "DI")])
2305
2306 ;; Convert impossible pushes of immediate to existing instructions.
2307 ;; First try to get scratch register and go through it.  In case this
2308 ;; fails, push sign extended lower part first and then overwrite
2309 ;; upper part by 32bit move.
2310 (define_peephole2
2311   [(match_scratch:DI 2 "r")
2312    (set (match_operand:DI 0 "push_operand" "")
2313         (match_operand:DI 1 "immediate_operand" ""))]
2314   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2315    && !x86_64_immediate_operand (operands[1], DImode)"
2316   [(set (match_dup 2) (match_dup 1))
2317    (set (match_dup 0) (match_dup 2))]
2318   "")
2319
2320 ;; We need to define this as both peepholer and splitter for case
2321 ;; peephole2 pass is not run.
2322 ;; "&& 1" is needed to keep it from matching the previous pattern.
2323 (define_peephole2
2324   [(set (match_operand:DI 0 "push_operand" "")
2325         (match_operand:DI 1 "immediate_operand" ""))]
2326   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2327    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2328   [(set (match_dup 0) (match_dup 1))
2329    (set (match_dup 2) (match_dup 3))]
2330   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2331    operands[1] = gen_lowpart (DImode, operands[2]);
2332    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2333                                                     GEN_INT (4)));
2334   ")
2335
2336 (define_split
2337   [(set (match_operand:DI 0 "push_operand" "")
2338         (match_operand:DI 1 "immediate_operand" ""))]
2339   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2340                     ? epilogue_completed : reload_completed)
2341    && !symbolic_operand (operands[1], DImode)
2342    && !x86_64_immediate_operand (operands[1], DImode)"
2343   [(set (match_dup 0) (match_dup 1))
2344    (set (match_dup 2) (match_dup 3))]
2345   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2346    operands[1] = gen_lowpart (DImode, operands[2]);
2347    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2348                                                     GEN_INT (4)));
2349   ")
2350
2351 (define_insn "*pushdi2_prologue_rex64"
2352   [(set (match_operand:DI 0 "push_operand" "=<")
2353         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2354    (clobber (mem:BLK (scratch)))]
2355   "TARGET_64BIT"
2356   "push{q}\t%1"
2357   [(set_attr "type" "push")
2358    (set_attr "mode" "DI")])
2359
2360 (define_insn "*popdi1_epilogue_rex64"
2361   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2362         (mem:DI (reg:DI SP_REG)))
2363    (set (reg:DI SP_REG)
2364         (plus:DI (reg:DI SP_REG) (const_int 8)))
2365    (clobber (mem:BLK (scratch)))]
2366   "TARGET_64BIT"
2367   "pop{q}\t%0"
2368   [(set_attr "type" "pop")
2369    (set_attr "mode" "DI")])
2370
2371 (define_insn "popdi1"
2372   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2373         (mem:DI (reg:DI SP_REG)))
2374    (set (reg:DI SP_REG)
2375         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2376   "TARGET_64BIT"
2377   "pop{q}\t%0"
2378   [(set_attr "type" "pop")
2379    (set_attr "mode" "DI")])
2380
2381 (define_insn "*movdi_xor_rex64"
2382   [(set (match_operand:DI 0 "register_operand" "=r")
2383         (match_operand:DI 1 "const0_operand" ""))
2384    (clobber (reg:CC FLAGS_REG))]
2385   "TARGET_64BIT
2386    && reload_completed"
2387   "xor{l}\t%k0, %k0";
2388   [(set_attr "type" "alu1")
2389    (set_attr "mode" "SI")
2390    (set_attr "length_immediate" "0")])
2391
2392 (define_insn "*movdi_or_rex64"
2393   [(set (match_operand:DI 0 "register_operand" "=r")
2394         (match_operand:DI 1 "const_int_operand" "i"))
2395    (clobber (reg:CC FLAGS_REG))]
2396   "TARGET_64BIT
2397    && reload_completed
2398    && operands[1] == constm1_rtx"
2399 {
2400   operands[1] = constm1_rtx;
2401   return "or{q}\t{%1, %0|%0, %1}";
2402 }
2403   [(set_attr "type" "alu1")
2404    (set_attr "mode" "DI")
2405    (set_attr "length_immediate" "1")])
2406
2407 (define_insn "*movdi_2"
2408   [(set (match_operand:DI 0 "nonimmediate_operand"
2409                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2410         (match_operand:DI 1 "general_operand"
2411                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2412   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2413   "@
2414    #
2415    #
2416    pxor\t%0, %0
2417    movq\t{%1, %0|%0, %1}
2418    movq\t{%1, %0|%0, %1}
2419    %vpxor\t%0, %d0
2420    %vmovq\t{%1, %0|%0, %1}
2421    %vmovdqa\t{%1, %0|%0, %1}
2422    %vmovq\t{%1, %0|%0, %1}
2423    xorps\t%0, %0
2424    movlps\t{%1, %0|%0, %1}
2425    movaps\t{%1, %0|%0, %1}
2426    movlps\t{%1, %0|%0, %1}"
2427   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2428    (set (attr "prefix")
2429      (if_then_else (eq_attr "alternative" "5,6,7,8")
2430        (const_string "vex")
2431        (const_string "orig")))
2432    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2433
2434 (define_split
2435   [(set (match_operand:DI 0 "push_operand" "")
2436         (match_operand:DI 1 "general_operand" ""))]
2437   "!TARGET_64BIT && reload_completed
2438    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2439   [(const_int 0)]
2440   "ix86_split_long_move (operands); DONE;")
2441
2442 ;; %%% This multiword shite has got to go.
2443 (define_split
2444   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2445         (match_operand:DI 1 "general_operand" ""))]
2446   "!TARGET_64BIT && reload_completed
2447    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2448    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2449   [(const_int 0)]
2450   "ix86_split_long_move (operands); DONE;")
2451
2452 (define_insn "*movdi_1_rex64"
2453   [(set (match_operand:DI 0 "nonimmediate_operand"
2454           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2455         (match_operand:DI 1 "general_operand"
2456           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2457   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2458 {
2459   switch (get_attr_type (insn))
2460     {
2461     case TYPE_SSECVT:
2462       if (SSE_REG_P (operands[0]))
2463         return "movq2dq\t{%1, %0|%0, %1}";
2464       else
2465         return "movdq2q\t{%1, %0|%0, %1}";
2466
2467     case TYPE_SSEMOV:
2468       if (TARGET_AVX)
2469         {
2470           if (get_attr_mode (insn) == MODE_TI)
2471             return "vmovdqa\t{%1, %0|%0, %1}";
2472           else
2473             return "vmovq\t{%1, %0|%0, %1}";
2474         }
2475
2476       if (get_attr_mode (insn) == MODE_TI)
2477         return "movdqa\t{%1, %0|%0, %1}";
2478       /* FALLTHRU */
2479
2480     case TYPE_MMXMOV:
2481       /* Moves from and into integer register is done using movd
2482          opcode with REX prefix.  */
2483       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2484         return "movd\t{%1, %0|%0, %1}";
2485       return "movq\t{%1, %0|%0, %1}";
2486
2487     case TYPE_SSELOG1:
2488       return "%vpxor\t%0, %d0";
2489
2490     case TYPE_MMX:
2491       return "pxor\t%0, %0";
2492
2493     case TYPE_MULTI:
2494       return "#";
2495
2496     case TYPE_LEA:
2497       return "lea{q}\t{%a1, %0|%0, %a1}";
2498
2499     default:
2500       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2501       if (get_attr_mode (insn) == MODE_SI)
2502         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2503       else if (which_alternative == 2)
2504         return "movabs{q}\t{%1, %0|%0, %1}";
2505       else
2506         return "mov{q}\t{%1, %0|%0, %1}";
2507     }
2508 }
2509   [(set (attr "type")
2510      (cond [(eq_attr "alternative" "5")
2511               (const_string "mmx")
2512             (eq_attr "alternative" "6,7,8,9,10")
2513               (const_string "mmxmov")
2514             (eq_attr "alternative" "11")
2515               (const_string "sselog1")
2516             (eq_attr "alternative" "12,13,14,15,16")
2517               (const_string "ssemov")
2518             (eq_attr "alternative" "17,18")
2519               (const_string "ssecvt")
2520             (eq_attr "alternative" "4")
2521               (const_string "multi")
2522             (match_operand:DI 1 "pic_32bit_operand" "")
2523               (const_string "lea")
2524            ]
2525            (const_string "imov")))
2526    (set (attr "modrm")
2527      (if_then_else
2528        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2529          (const_string "0")
2530          (const_string "*")))
2531    (set (attr "length_immediate")
2532      (if_then_else
2533        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2534          (const_string "8")
2535          (const_string "*")))
2536    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2537    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2538    (set (attr "prefix")
2539      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2540        (const_string "maybe_vex")
2541        (const_string "orig")))
2542    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2543
2544 ;; Stores and loads of ax to arbitrary constant address.
2545 ;; We fake an second form of instruction to force reload to load address
2546 ;; into register when rax is not available
2547 (define_insn "*movabsdi_1_rex64"
2548   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2549         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2550   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2551   "@
2552    movabs{q}\t{%1, %P0|%P0, %1}
2553    mov{q}\t{%1, %a0|%a0, %1}"
2554   [(set_attr "type" "imov")
2555    (set_attr "modrm" "0,*")
2556    (set_attr "length_address" "8,0")
2557    (set_attr "length_immediate" "0,*")
2558    (set_attr "memory" "store")
2559    (set_attr "mode" "DI")])
2560
2561 (define_insn "*movabsdi_2_rex64"
2562   [(set (match_operand:DI 0 "register_operand" "=a,r")
2563         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2564   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2565   "@
2566    movabs{q}\t{%P1, %0|%0, %P1}
2567    mov{q}\t{%a1, %0|%0, %a1}"
2568   [(set_attr "type" "imov")
2569    (set_attr "modrm" "0,*")
2570    (set_attr "length_address" "8,0")
2571    (set_attr "length_immediate" "0")
2572    (set_attr "memory" "load")
2573    (set_attr "mode" "DI")])
2574
2575 ;; Convert impossible stores of immediate to existing instructions.
2576 ;; First try to get scratch register and go through it.  In case this
2577 ;; fails, move by 32bit parts.
2578 (define_peephole2
2579   [(match_scratch:DI 2 "r")
2580    (set (match_operand:DI 0 "memory_operand" "")
2581         (match_operand:DI 1 "immediate_operand" ""))]
2582   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2583    && !x86_64_immediate_operand (operands[1], DImode)"
2584   [(set (match_dup 2) (match_dup 1))
2585    (set (match_dup 0) (match_dup 2))]
2586   "")
2587
2588 ;; We need to define this as both peepholer and splitter for case
2589 ;; peephole2 pass is not run.
2590 ;; "&& 1" is needed to keep it from matching the previous pattern.
2591 (define_peephole2
2592   [(set (match_operand:DI 0 "memory_operand" "")
2593         (match_operand:DI 1 "immediate_operand" ""))]
2594   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2595    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2596   [(set (match_dup 2) (match_dup 3))
2597    (set (match_dup 4) (match_dup 5))]
2598   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2599
2600 (define_split
2601   [(set (match_operand:DI 0 "memory_operand" "")
2602         (match_operand:DI 1 "immediate_operand" ""))]
2603   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2604                     ? epilogue_completed : reload_completed)
2605    && !symbolic_operand (operands[1], DImode)
2606    && !x86_64_immediate_operand (operands[1], DImode)"
2607   [(set (match_dup 2) (match_dup 3))
2608    (set (match_dup 4) (match_dup 5))]
2609   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2610
2611 (define_insn "*swapdi_rex64"
2612   [(set (match_operand:DI 0 "register_operand" "+r")
2613         (match_operand:DI 1 "register_operand" "+r"))
2614    (set (match_dup 1)
2615         (match_dup 0))]
2616   "TARGET_64BIT"
2617   "xchg{q}\t%1, %0"
2618   [(set_attr "type" "imov")
2619    (set_attr "mode" "DI")
2620    (set_attr "pent_pair" "np")
2621    (set_attr "athlon_decode" "vector")
2622    (set_attr "amdfam10_decode" "double")])
2623
2624 (define_expand "movoi"
2625   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2626         (match_operand:OI 1 "general_operand" ""))]
2627   "TARGET_AVX"
2628   "ix86_expand_move (OImode, operands); DONE;")
2629
2630 (define_insn "*movoi_internal"
2631   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2632         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2633   "TARGET_AVX
2634    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2635 {
2636   switch (which_alternative)
2637     {
2638     case 0:
2639       return "vxorps\t%0, %0, %0";
2640     case 1:
2641     case 2:
2642       if (misaligned_operand (operands[0], OImode)
2643           || misaligned_operand (operands[1], OImode))
2644         return "vmovdqu\t{%1, %0|%0, %1}";
2645       else
2646         return "vmovdqa\t{%1, %0|%0, %1}";
2647     default:
2648       gcc_unreachable ();
2649     }
2650 }
2651   [(set_attr "type" "sselog1,ssemov,ssemov")
2652    (set_attr "prefix" "vex")
2653    (set_attr "mode" "OI")])
2654
2655 (define_expand "movti"
2656   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2657         (match_operand:TI 1 "nonimmediate_operand" ""))]
2658   "TARGET_SSE || TARGET_64BIT"
2659 {
2660   if (TARGET_64BIT)
2661     ix86_expand_move (TImode, operands);
2662   else if (push_operand (operands[0], TImode))
2663     ix86_expand_push (TImode, operands[1]);
2664   else
2665     ix86_expand_vector_move (TImode, operands);
2666   DONE;
2667 })
2668
2669 (define_insn "*movti_internal"
2670   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2671         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2672   "TARGET_SSE && !TARGET_64BIT
2673    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2674 {
2675   switch (which_alternative)
2676     {
2677     case 0:
2678       if (get_attr_mode (insn) == MODE_V4SF)
2679         return "%vxorps\t%0, %d0";
2680       else
2681         return "%vpxor\t%0, %d0";
2682     case 1:
2683     case 2:
2684       /* TDmode values are passed as TImode on the stack.  Moving them
2685          to stack may result in unaligned memory access.  */
2686       if (misaligned_operand (operands[0], TImode)
2687           || misaligned_operand (operands[1], TImode))
2688         {
2689           if (get_attr_mode (insn) == MODE_V4SF)
2690             return "%vmovups\t{%1, %0|%0, %1}";
2691          else
2692            return "%vmovdqu\t{%1, %0|%0, %1}";
2693         }
2694       else
2695         {
2696           if (get_attr_mode (insn) == MODE_V4SF)
2697             return "%vmovaps\t{%1, %0|%0, %1}";
2698          else
2699            return "%vmovdqa\t{%1, %0|%0, %1}";
2700         }
2701     default:
2702       gcc_unreachable ();
2703     }
2704 }
2705   [(set_attr "type" "sselog1,ssemov,ssemov")
2706    (set_attr "prefix" "maybe_vex")
2707    (set (attr "mode")
2708         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2709                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2710                  (const_string "V4SF")
2711                (and (eq_attr "alternative" "2")
2712                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2713                         (const_int 0)))
2714                  (const_string "V4SF")]
2715               (const_string "TI")))])
2716
2717 (define_insn "*movti_rex64"
2718   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2719         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2720   "TARGET_64BIT
2721    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2722 {
2723   switch (which_alternative)
2724     {
2725     case 0:
2726     case 1:
2727       return "#";
2728     case 2:
2729       if (get_attr_mode (insn) == MODE_V4SF)
2730         return "%vxorps\t%0, %d0";
2731       else
2732         return "%vpxor\t%0, %d0";
2733     case 3:
2734     case 4:
2735       /* TDmode values are passed as TImode on the stack.  Moving them
2736          to stack may result in unaligned memory access.  */
2737       if (misaligned_operand (operands[0], TImode)
2738           || misaligned_operand (operands[1], TImode))
2739         {
2740           if (get_attr_mode (insn) == MODE_V4SF)
2741             return "%vmovups\t{%1, %0|%0, %1}";
2742          else
2743            return "%vmovdqu\t{%1, %0|%0, %1}";
2744         }
2745       else
2746         {
2747           if (get_attr_mode (insn) == MODE_V4SF)
2748             return "%vmovaps\t{%1, %0|%0, %1}";
2749          else
2750            return "%vmovdqa\t{%1, %0|%0, %1}";
2751         }
2752     default:
2753       gcc_unreachable ();
2754     }
2755 }
2756   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2757    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2758    (set (attr "mode")
2759         (cond [(eq_attr "alternative" "2,3")
2760                  (if_then_else
2761                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2762                        (const_int 0))
2763                    (const_string "V4SF")
2764                    (const_string "TI"))
2765                (eq_attr "alternative" "4")
2766                  (if_then_else
2767                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2768                             (const_int 0))
2769                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2770                             (const_int 0)))
2771                    (const_string "V4SF")
2772                    (const_string "TI"))]
2773                (const_string "DI")))])
2774
2775 (define_split
2776   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2777         (match_operand:TI 1 "general_operand" ""))]
2778   "reload_completed && !SSE_REG_P (operands[0])
2779    && !SSE_REG_P (operands[1])"
2780   [(const_int 0)]
2781   "ix86_split_long_move (operands); DONE;")
2782
2783 ;; This expands to what emit_move_complex would generate if we didn't
2784 ;; have a movti pattern.  Having this avoids problems with reload on
2785 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2786 ;; to have around all the time.
2787 (define_expand "movcdi"
2788   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2789         (match_operand:CDI 1 "general_operand" ""))]
2790   ""
2791 {
2792   if (push_operand (operands[0], CDImode))
2793     emit_move_complex_push (CDImode, operands[0], operands[1]);
2794   else
2795     emit_move_complex_parts (operands[0], operands[1]);
2796   DONE;
2797 })
2798
2799 (define_expand "movsf"
2800   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2801         (match_operand:SF 1 "general_operand" ""))]
2802   ""
2803   "ix86_expand_move (SFmode, operands); DONE;")
2804
2805 (define_insn "*pushsf"
2806   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2807         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2808   "!TARGET_64BIT"
2809 {
2810   /* Anything else should be already split before reg-stack.  */
2811   gcc_assert (which_alternative == 1);
2812   return "push{l}\t%1";
2813 }
2814   [(set_attr "type" "multi,push,multi")
2815    (set_attr "unit" "i387,*,*")
2816    (set_attr "mode" "SF,SI,SF")])
2817
2818 (define_insn "*pushsf_rex64"
2819   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2820         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2821   "TARGET_64BIT"
2822 {
2823   /* Anything else should be already split before reg-stack.  */
2824   gcc_assert (which_alternative == 1);
2825   return "push{q}\t%q1";
2826 }
2827   [(set_attr "type" "multi,push,multi")
2828    (set_attr "unit" "i387,*,*")
2829    (set_attr "mode" "SF,DI,SF")])
2830
2831 (define_split
2832   [(set (match_operand:SF 0 "push_operand" "")
2833         (match_operand:SF 1 "memory_operand" ""))]
2834   "reload_completed
2835    && MEM_P (operands[1])
2836    && (operands[2] = find_constant_src (insn))"
2837   [(set (match_dup 0)
2838         (match_dup 2))])
2839
2840 ;; %%% Kill this when call knows how to work this out.
2841 (define_split
2842   [(set (match_operand:SF 0 "push_operand" "")
2843         (match_operand:SF 1 "any_fp_register_operand" ""))]
2844   "!TARGET_64BIT"
2845   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2846    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2847
2848 (define_split
2849   [(set (match_operand:SF 0 "push_operand" "")
2850         (match_operand:SF 1 "any_fp_register_operand" ""))]
2851   "TARGET_64BIT"
2852   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2853    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2854
2855 (define_insn "*movsf_1"
2856   [(set (match_operand:SF 0 "nonimmediate_operand"
2857           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2858         (match_operand:SF 1 "general_operand"
2859           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2860   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2861    && (reload_in_progress || reload_completed
2862        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2863        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2864            && standard_80387_constant_p (operands[1]))
2865        || GET_CODE (operands[1]) != CONST_DOUBLE
2866        || memory_operand (operands[0], SFmode))"
2867 {
2868   switch (which_alternative)
2869     {
2870     case 0:
2871     case 1:
2872       return output_387_reg_move (insn, operands);
2873
2874     case 2:
2875       return standard_80387_constant_opcode (operands[1]);
2876
2877     case 3:
2878     case 4:
2879       return "mov{l}\t{%1, %0|%0, %1}";
2880     case 5:
2881       if (get_attr_mode (insn) == MODE_TI)
2882         return "%vpxor\t%0, %d0";
2883       else
2884         return "%vxorps\t%0, %d0";
2885     case 6:
2886       if (get_attr_mode (insn) == MODE_V4SF)
2887         return "%vmovaps\t{%1, %0|%0, %1}";
2888       else
2889         return "%vmovss\t{%1, %d0|%d0, %1}";
2890     case 7:
2891       if (TARGET_AVX)
2892         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2893                                    : "vmovss\t{%1, %0|%0, %1}";
2894       else
2895         return "movss\t{%1, %0|%0, %1}";
2896     case 8:
2897       return "%vmovss\t{%1, %0|%0, %1}";
2898
2899     case 9: case 10: case 14: case 15:
2900       return "movd\t{%1, %0|%0, %1}";
2901     case 12: case 13:
2902       return "%vmovd\t{%1, %0|%0, %1}";
2903
2904     case 11:
2905       return "movq\t{%1, %0|%0, %1}";
2906
2907     default:
2908       gcc_unreachable ();
2909     }
2910 }
2911   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2912    (set (attr "prefix")
2913      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2914        (const_string "maybe_vex")
2915        (const_string "orig")))
2916    (set (attr "mode")
2917         (cond [(eq_attr "alternative" "3,4,9,10")
2918                  (const_string "SI")
2919                (eq_attr "alternative" "5")
2920                  (if_then_else
2921                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2922                                  (const_int 0))
2923                              (ne (symbol_ref "TARGET_SSE2")
2924                                  (const_int 0)))
2925                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2926                             (const_int 0)))
2927                    (const_string "TI")
2928                    (const_string "V4SF"))
2929                /* For architectures resolving dependencies on
2930                   whole SSE registers use APS move to break dependency
2931                   chains, otherwise use short move to avoid extra work.
2932
2933                   Do the same for architectures resolving dependencies on
2934                   the parts.  While in DF mode it is better to always handle
2935                   just register parts, the SF mode is different due to lack
2936                   of instructions to load just part of the register.  It is
2937                   better to maintain the whole registers in single format
2938                   to avoid problems on using packed logical operations.  */
2939                (eq_attr "alternative" "6")
2940                  (if_then_else
2941                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2942                             (const_int 0))
2943                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2944                             (const_int 0)))
2945                    (const_string "V4SF")
2946                    (const_string "SF"))
2947                (eq_attr "alternative" "11")
2948                  (const_string "DI")]
2949                (const_string "SF")))])
2950
2951 (define_insn "*swapsf"
2952   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2953         (match_operand:SF 1 "fp_register_operand" "+f"))
2954    (set (match_dup 1)
2955         (match_dup 0))]
2956   "reload_completed || TARGET_80387"
2957 {
2958   if (STACK_TOP_P (operands[0]))
2959     return "fxch\t%1";
2960   else
2961     return "fxch\t%0";
2962 }
2963   [(set_attr "type" "fxch")
2964    (set_attr "mode" "SF")])
2965
2966 (define_expand "movdf"
2967   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2968         (match_operand:DF 1 "general_operand" ""))]
2969   ""
2970   "ix86_expand_move (DFmode, operands); DONE;")
2971
2972 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2973 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2974 ;; On the average, pushdf using integers can be still shorter.  Allow this
2975 ;; pattern for optimize_size too.
2976
2977 (define_insn "*pushdf_nointeger"
2978   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2979         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2980   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2981 {
2982   /* This insn should be already split before reg-stack.  */
2983   gcc_unreachable ();
2984 }
2985   [(set_attr "type" "multi")
2986    (set_attr "unit" "i387,*,*,*")
2987    (set_attr "mode" "DF,SI,SI,DF")])
2988
2989 (define_insn "*pushdf_integer"
2990   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2991         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2992   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2993 {
2994   /* This insn should be already split before reg-stack.  */
2995   gcc_unreachable ();
2996 }
2997   [(set_attr "type" "multi")
2998    (set_attr "unit" "i387,*,*")
2999    (set_attr "mode" "DF,SI,DF")])
3000
3001 ;; %%% Kill this when call knows how to work this out.
3002 (define_split
3003   [(set (match_operand:DF 0 "push_operand" "")
3004         (match_operand:DF 1 "any_fp_register_operand" ""))]
3005   "reload_completed"
3006   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3007    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3008   "")
3009
3010 (define_split
3011   [(set (match_operand:DF 0 "push_operand" "")
3012         (match_operand:DF 1 "general_operand" ""))]
3013   "reload_completed"
3014   [(const_int 0)]
3015   "ix86_split_long_move (operands); DONE;")
3016
3017 ;; Moving is usually shorter when only FP registers are used. This separate
3018 ;; movdf pattern avoids the use of integer registers for FP operations
3019 ;; when optimizing for size.
3020
3021 (define_insn "*movdf_nointeger"
3022   [(set (match_operand:DF 0 "nonimmediate_operand"
3023                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3024         (match_operand:DF 1 "general_operand"
3025                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3026   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027    && ((optimize_function_for_size_p (cfun)
3028        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3029    && (reload_in_progress || reload_completed
3030        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3031        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3032            && optimize_function_for_size_p (cfun)
3033            && !memory_operand (operands[0], DFmode)
3034            && standard_80387_constant_p (operands[1]))
3035        || GET_CODE (operands[1]) != CONST_DOUBLE
3036        || ((optimize_function_for_size_p (cfun)
3037             || !TARGET_MEMORY_MISMATCH_STALL
3038             || reload_in_progress || reload_completed)
3039            && memory_operand (operands[0], DFmode)))"
3040 {
3041   switch (which_alternative)
3042     {
3043     case 0:
3044     case 1:
3045       return output_387_reg_move (insn, operands);
3046
3047     case 2:
3048       return standard_80387_constant_opcode (operands[1]);
3049
3050     case 3:
3051     case 4:
3052       return "#";
3053     case 5:
3054       switch (get_attr_mode (insn))
3055         {
3056         case MODE_V4SF:
3057           return "%vxorps\t%0, %d0";
3058         case MODE_V2DF:
3059           return "%vxorpd\t%0, %d0";
3060         case MODE_TI:
3061           return "%vpxor\t%0, %d0";
3062         default:
3063           gcc_unreachable ();
3064         }
3065     case 6:
3066     case 7:
3067     case 8:
3068       switch (get_attr_mode (insn))
3069         {
3070         case MODE_V4SF:
3071           return "%vmovaps\t{%1, %0|%0, %1}";
3072         case MODE_V2DF:
3073           return "%vmovapd\t{%1, %0|%0, %1}";
3074         case MODE_TI:
3075           return "%vmovdqa\t{%1, %0|%0, %1}";
3076         case MODE_DI:
3077           return "%vmovq\t{%1, %0|%0, %1}";
3078         case MODE_DF:
3079           if (TARGET_AVX)
3080             {
3081               if (REG_P (operands[0]) && REG_P (operands[1]))
3082                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3083               else
3084                 return "vmovsd\t{%1, %0|%0, %1}";
3085             }
3086           else
3087             return "movsd\t{%1, %0|%0, %1}";
3088         case MODE_V1DF:
3089           if (TARGET_AVX)
3090             {
3091               if (REG_P (operands[0]))
3092                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3093               else
3094                 return "vmovlpd\t{%1, %0|%0, %1}";
3095             }
3096           else
3097             return "movlpd\t{%1, %0|%0, %1}";
3098         case MODE_V2SF:
3099           if (TARGET_AVX)
3100             {
3101               if (REG_P (operands[0]))
3102                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3103               else
3104                 return "vmovlps\t{%1, %0|%0, %1}";
3105             }
3106           else
3107             return "movlps\t{%1, %0|%0, %1}";
3108         default:
3109           gcc_unreachable ();
3110         }
3111
3112     default:
3113       gcc_unreachable ();
3114     }
3115 }
3116   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3117    (set (attr "prefix")
3118      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3119        (const_string "orig")
3120        (const_string "maybe_vex")))
3121    (set (attr "prefix_data16")
3122      (if_then_else (eq_attr "mode" "V1DF")
3123        (const_string "1")
3124        (const_string "*")))
3125    (set (attr "mode")
3126         (cond [(eq_attr "alternative" "0,1,2")
3127                  (const_string "DF")
3128                (eq_attr "alternative" "3,4")
3129                  (const_string "SI")
3130
3131                /* For SSE1, we have many fewer alternatives.  */
3132                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3133                  (cond [(eq_attr "alternative" "5,6")
3134                           (const_string "V4SF")
3135                        ]
3136                    (const_string "V2SF"))
3137
3138                /* xorps is one byte shorter.  */
3139                (eq_attr "alternative" "5")
3140                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141                             (const_int 0))
3142                           (const_string "V4SF")
3143                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3144                             (const_int 0))
3145                           (const_string "TI")
3146                        ]
3147                        (const_string "V2DF"))
3148
3149                /* For architectures resolving dependencies on
3150                   whole SSE registers use APD move to break dependency
3151                   chains, otherwise use short move to avoid extra work.
3152
3153                   movaps encodes one byte shorter.  */
3154                (eq_attr "alternative" "6")
3155                  (cond
3156                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157                         (const_int 0))
3158                       (const_string "V4SF")
3159                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160                         (const_int 0))
3161                       (const_string "V2DF")
3162                    ]
3163                    (const_string "DF"))
3164                /* For architectures resolving dependencies on register
3165                   parts we may avoid extra work to zero out upper part
3166                   of register.  */
3167                (eq_attr "alternative" "7")
3168                  (if_then_else
3169                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170                        (const_int 0))
3171                    (const_string "V1DF")
3172                    (const_string "DF"))
3173               ]
3174               (const_string "DF")))])
3175
3176 (define_insn "*movdf_integer_rex64"
3177   [(set (match_operand:DF 0 "nonimmediate_operand"
3178                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3179         (match_operand:DF 1 "general_operand"
3180                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3181   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3182    && (reload_in_progress || reload_completed
3183        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185            && optimize_function_for_size_p (cfun)
3186            && standard_80387_constant_p (operands[1]))
3187        || GET_CODE (operands[1]) != CONST_DOUBLE
3188        || memory_operand (operands[0], DFmode))"
3189 {
3190   switch (which_alternative)
3191     {
3192     case 0:
3193     case 1:
3194       return output_387_reg_move (insn, operands);
3195
3196     case 2:
3197       return standard_80387_constant_opcode (operands[1]);
3198
3199     case 3:
3200     case 4:
3201       return "#";
3202
3203     case 5:
3204       switch (get_attr_mode (insn))
3205         {
3206         case MODE_V4SF:
3207           return "%vxorps\t%0, %d0";
3208         case MODE_V2DF:
3209           return "%vxorpd\t%0, %d0";
3210         case MODE_TI:
3211           return "%vpxor\t%0, %d0";
3212         default:
3213           gcc_unreachable ();
3214         }
3215     case 6:
3216     case 7:
3217     case 8:
3218       switch (get_attr_mode (insn))
3219         {
3220         case MODE_V4SF:
3221           return "%vmovaps\t{%1, %0|%0, %1}";
3222         case MODE_V2DF:
3223           return "%vmovapd\t{%1, %0|%0, %1}";
3224         case MODE_TI:
3225           return "%vmovdqa\t{%1, %0|%0, %1}";
3226         case MODE_DI:
3227           return "%vmovq\t{%1, %0|%0, %1}";
3228         case MODE_DF:
3229           if (TARGET_AVX)
3230             {
3231               if (REG_P (operands[0]) && REG_P (operands[1]))
3232                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3233               else
3234                 return "vmovsd\t{%1, %0|%0, %1}";
3235             }
3236           else
3237             return "movsd\t{%1, %0|%0, %1}";
3238         case MODE_V1DF:
3239           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3240         case MODE_V2SF:
3241           return "%vmovlps\t{%1, %d0|%d0, %1}";
3242         default:
3243           gcc_unreachable ();
3244         }
3245
3246     case 9:
3247     case 10:
3248     return "%vmovd\t{%1, %0|%0, %1}";
3249
3250     default:
3251       gcc_unreachable();
3252     }
3253 }
3254   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3255    (set (attr "prefix")
3256      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3257        (const_string "orig")
3258        (const_string "maybe_vex")))
3259    (set (attr "prefix_data16")
3260      (if_then_else (eq_attr "mode" "V1DF")
3261        (const_string "1")
3262        (const_string "*")))
3263    (set (attr "mode")
3264         (cond [(eq_attr "alternative" "0,1,2")
3265                  (const_string "DF")
3266                (eq_attr "alternative" "3,4,9,10")
3267                  (const_string "DI")
3268
3269                /* For SSE1, we have many fewer alternatives.  */
3270                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3271                  (cond [(eq_attr "alternative" "5,6")
3272                           (const_string "V4SF")
3273                        ]
3274                    (const_string "V2SF"))
3275
3276                /* xorps is one byte shorter.  */
3277                (eq_attr "alternative" "5")
3278                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3279                             (const_int 0))
3280                           (const_string "V4SF")
3281                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3282                             (const_int 0))
3283                           (const_string "TI")
3284                        ]
3285                        (const_string "V2DF"))
3286
3287                /* For architectures resolving dependencies on
3288                   whole SSE registers use APD move to break dependency
3289                   chains, otherwise use short move to avoid extra work.
3290
3291                   movaps encodes one byte shorter.  */
3292                (eq_attr "alternative" "6")
3293                  (cond
3294                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3295                         (const_int 0))
3296                       (const_string "V4SF")
3297                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3298                         (const_int 0))
3299                       (const_string "V2DF")
3300                    ]
3301                    (const_string "DF"))
3302                /* For architectures resolving dependencies on register
3303                   parts we may avoid extra work to zero out upper part
3304                   of register.  */
3305                (eq_attr "alternative" "7")
3306                  (if_then_else
3307                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3308                        (const_int 0))
3309                    (const_string "V1DF")
3310                    (const_string "DF"))
3311               ]
3312               (const_string "DF")))])
3313
3314 (define_insn "*movdf_integer"
3315   [(set (match_operand:DF 0 "nonimmediate_operand"
3316                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3317         (match_operand:DF 1 "general_operand"
3318                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3319   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3320    && optimize_function_for_speed_p (cfun)
3321    && TARGET_INTEGER_DFMODE_MOVES
3322    && (reload_in_progress || reload_completed
3323        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3324        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3325            && optimize_function_for_size_p (cfun)
3326            && standard_80387_constant_p (operands[1]))
3327        || GET_CODE (operands[1]) != CONST_DOUBLE
3328        || memory_operand (operands[0], DFmode))"
3329 {
3330   switch (which_alternative)
3331     {
3332     case 0:
3333     case 1:
3334       return output_387_reg_move (insn, operands);
3335
3336     case 2:
3337       return standard_80387_constant_opcode (operands[1]);
3338
3339     case 3:
3340     case 4:
3341       return "#";
3342
3343     case 5:
3344       switch (get_attr_mode (insn))
3345         {
3346         case MODE_V4SF:
3347           return "xorps\t%0, %0";
3348         case MODE_V2DF:
3349           return "xorpd\t%0, %0";
3350         case MODE_TI:
3351           return "pxor\t%0, %0";
3352         default:
3353           gcc_unreachable ();
3354         }
3355     case 6:
3356     case 7:
3357     case 8:
3358       switch (get_attr_mode (insn))
3359         {
3360         case MODE_V4SF:
3361           return "movaps\t{%1, %0|%0, %1}";
3362         case MODE_V2DF:
3363           return "movapd\t{%1, %0|%0, %1}";
3364         case MODE_TI:
3365           return "movdqa\t{%1, %0|%0, %1}";
3366         case MODE_DI:
3367           return "movq\t{%1, %0|%0, %1}";
3368         case MODE_DF:
3369           return "movsd\t{%1, %0|%0, %1}";
3370         case MODE_V1DF:
3371           return "movlpd\t{%1, %0|%0, %1}";
3372         case MODE_V2SF:
3373           return "movlps\t{%1, %0|%0, %1}";
3374         default:
3375           gcc_unreachable ();
3376         }
3377
3378     default:
3379       gcc_unreachable();
3380     }
3381 }
3382   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3383    (set (attr "prefix_data16")
3384      (if_then_else (eq_attr "mode" "V1DF")
3385        (const_string "1")
3386        (const_string "*")))
3387    (set (attr "mode")
3388         (cond [(eq_attr "alternative" "0,1,2")
3389                  (const_string "DF")
3390                (eq_attr "alternative" "3,4")
3391                  (const_string "SI")
3392
3393                /* For SSE1, we have many fewer alternatives.  */
3394                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3395                  (cond [(eq_attr "alternative" "5,6")
3396                           (const_string "V4SF")
3397                        ]
3398                    (const_string "V2SF"))
3399
3400                /* xorps is one byte shorter.  */
3401                (eq_attr "alternative" "5")
3402                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3403                             (const_int 0))
3404                           (const_string "V4SF")
3405                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3406                             (const_int 0))
3407                           (const_string "TI")
3408                        ]
3409                        (const_string "V2DF"))
3410
3411                /* For architectures resolving dependencies on
3412                   whole SSE registers use APD move to break dependency
3413                   chains, otherwise use short move to avoid extra work.
3414
3415                   movaps encodes one byte shorter.  */
3416                (eq_attr "alternative" "6")
3417                  (cond
3418                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3419                         (const_int 0))
3420                       (const_string "V4SF")
3421                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3422                         (const_int 0))
3423                       (const_string "V2DF")
3424                    ]
3425                    (const_string "DF"))
3426                /* For architectures resolving dependencies on register
3427                   parts we may avoid extra work to zero out upper part
3428                   of register.  */
3429                (eq_attr "alternative" "7")
3430                  (if_then_else
3431                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3432                        (const_int 0))
3433                    (const_string "V1DF")
3434                    (const_string "DF"))
3435               ]
3436               (const_string "DF")))])
3437
3438 (define_split
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3440         (match_operand:DF 1 "general_operand" ""))]
3441   "reload_completed
3442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3443    && ! (ANY_FP_REG_P (operands[0]) ||
3444          (GET_CODE (operands[0]) == SUBREG
3445           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3446    && ! (ANY_FP_REG_P (operands[1]) ||
3447          (GET_CODE (operands[1]) == SUBREG
3448           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3449   [(const_int 0)]
3450   "ix86_split_long_move (operands); DONE;")
3451
3452 (define_insn "*swapdf"
3453   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3454         (match_operand:DF 1 "fp_register_operand" "+f"))
3455    (set (match_dup 1)
3456         (match_dup 0))]
3457   "reload_completed || TARGET_80387"
3458 {
3459   if (STACK_TOP_P (operands[0]))
3460     return "fxch\t%1";
3461   else
3462     return "fxch\t%0";
3463 }
3464   [(set_attr "type" "fxch")
3465    (set_attr "mode" "DF")])
3466
3467 (define_expand "movxf"
3468   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3469         (match_operand:XF 1 "general_operand" ""))]
3470   ""
3471   "ix86_expand_move (XFmode, operands); DONE;")
3472
3473 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3474 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3475 ;; Pushing using integer instructions is longer except for constants
3476 ;; and direct memory references.
3477 ;; (assuming that any given constant is pushed only once, but this ought to be
3478 ;;  handled elsewhere).
3479
3480 (define_insn "*pushxf_nointeger"
3481   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3482         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3483   "optimize_function_for_size_p (cfun)"
3484 {
3485   /* This insn should be already split before reg-stack.  */
3486   gcc_unreachable ();
3487 }
3488   [(set_attr "type" "multi")
3489    (set_attr "unit" "i387,*,*")
3490    (set_attr "mode" "XF,SI,SI")])
3491
3492 (define_insn "*pushxf_integer"
3493   [(set (match_operand:XF 0 "push_operand" "=<,<")
3494         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3495   "optimize_function_for_speed_p (cfun)"
3496 {
3497   /* This insn should be already split before reg-stack.  */
3498   gcc_unreachable ();
3499 }
3500   [(set_attr "type" "multi")
3501    (set_attr "unit" "i387,*")
3502    (set_attr "mode" "XF,SI")])
3503
3504 (define_split
3505   [(set (match_operand 0 "push_operand" "")
3506         (match_operand 1 "general_operand" ""))]
3507   "reload_completed
3508    && (GET_MODE (operands[0]) == XFmode
3509        || GET_MODE (operands[0]) == DFmode)
3510    && !ANY_FP_REG_P (operands[1])"
3511   [(const_int 0)]
3512   "ix86_split_long_move (operands); DONE;")
3513
3514 (define_split
3515   [(set (match_operand:XF 0 "push_operand" "")
3516         (match_operand:XF 1 "any_fp_register_operand" ""))]
3517   ""
3518   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3519    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3520   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521
3522 ;; Do not use integer registers when optimizing for size
3523 (define_insn "*movxf_nointeger"
3524   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3525         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3526   "optimize_function_for_size_p (cfun)
3527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528    && (reload_in_progress || reload_completed
3529        || standard_80387_constant_p (operands[1])
3530        || GET_CODE (operands[1]) != CONST_DOUBLE
3531        || memory_operand (operands[0], XFmode))"
3532 {
3533   switch (which_alternative)
3534     {
3535     case 0:
3536     case 1:
3537       return output_387_reg_move (insn, operands);
3538
3539     case 2:
3540       return standard_80387_constant_opcode (operands[1]);
3541
3542     case 3: case 4:
3543       return "#";
3544     default:
3545       gcc_unreachable ();
3546     }
3547 }
3548   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3549    (set_attr "mode" "XF,XF,XF,SI,SI")])
3550
3551 (define_insn "*movxf_integer"
3552   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3553         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3554   "optimize_function_for_speed_p (cfun)
3555    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3556    && (reload_in_progress || reload_completed
3557        || GET_CODE (operands[1]) != CONST_DOUBLE
3558        || memory_operand (operands[0], XFmode))"
3559 {
3560   switch (which_alternative)
3561     {
3562     case 0:
3563     case 1:
3564       return output_387_reg_move (insn, operands);
3565
3566     case 2:
3567       return standard_80387_constant_opcode (operands[1]);
3568
3569     case 3: case 4:
3570       return "#";
3571
3572     default:
3573       gcc_unreachable ();
3574     }
3575 }
3576   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3577    (set_attr "mode" "XF,XF,XF,SI,SI")])
3578
3579 (define_expand "movtf"
3580   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3581         (match_operand:TF 1 "nonimmediate_operand" ""))]
3582   "TARGET_SSE2"
3583 {
3584   ix86_expand_move (TFmode, operands);
3585   DONE;
3586 })
3587
3588 (define_insn "*movtf_internal"
3589   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3590         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3591   "TARGET_SSE2
3592    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3593 {
3594   switch (which_alternative)
3595     {
3596     case 0:
3597     case 1:
3598       if (get_attr_mode (insn) == MODE_V4SF)
3599         return "%vmovaps\t{%1, %0|%0, %1}";
3600       else
3601         return "%vmovdqa\t{%1, %0|%0, %1}";
3602     case 2:
3603       if (get_attr_mode (insn) == MODE_V4SF)
3604         return "%vxorps\t%0, %d0";
3605       else
3606         return "%vpxor\t%0, %d0";
3607     case 3:
3608     case 4:
3609         return "#";
3610     default:
3611       gcc_unreachable ();
3612     }
3613 }
3614   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3615    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3616    (set (attr "mode")
3617         (cond [(eq_attr "alternative" "0,2")
3618                  (if_then_else
3619                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3620                        (const_int 0))
3621                    (const_string "V4SF")
3622                    (const_string "TI"))
3623                (eq_attr "alternative" "1")
3624                  (if_then_else
3625                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3626                             (const_int 0))
3627                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3628                             (const_int 0)))
3629                    (const_string "V4SF")
3630                    (const_string "TI"))]
3631                (const_string "DI")))])
3632
3633 (define_insn "*pushtf_sse"
3634   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3635         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3636   "TARGET_SSE2"
3637 {
3638   /* This insn should be already split before reg-stack.  */
3639   gcc_unreachable ();
3640 }
3641   [(set_attr "type" "multi")
3642    (set_attr "unit" "sse,*,*")
3643    (set_attr "mode" "TF,SI,SI")])
3644
3645 (define_split
3646   [(set (match_operand:TF 0 "push_operand" "")
3647         (match_operand:TF 1 "general_operand" ""))]
3648   "TARGET_SSE2 && reload_completed
3649    && !SSE_REG_P (operands[1])"
3650   [(const_int 0)]
3651   "ix86_split_long_move (operands); DONE;")
3652
3653 (define_split
3654   [(set (match_operand:TF 0 "push_operand" "")
3655         (match_operand:TF 1 "any_fp_register_operand" ""))]
3656   "TARGET_SSE2"
3657   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3658    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3659   "")
3660
3661 (define_split
3662   [(set (match_operand 0 "nonimmediate_operand" "")
3663         (match_operand 1 "general_operand" ""))]
3664   "reload_completed
3665    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3666    && GET_MODE (operands[0]) == XFmode
3667    && ! (ANY_FP_REG_P (operands[0]) ||
3668          (GET_CODE (operands[0]) == SUBREG
3669           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3670    && ! (ANY_FP_REG_P (operands[1]) ||
3671          (GET_CODE (operands[1]) == SUBREG
3672           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3673   [(const_int 0)]
3674   "ix86_split_long_move (operands); DONE;")
3675
3676 (define_split
3677   [(set (match_operand 0 "register_operand" "")
3678         (match_operand 1 "memory_operand" ""))]
3679   "reload_completed
3680    && MEM_P (operands[1])
3681    && (GET_MODE (operands[0]) == TFmode
3682        || GET_MODE (operands[0]) == XFmode
3683        || GET_MODE (operands[0]) == SFmode
3684        || GET_MODE (operands[0]) == DFmode)
3685    && (operands[2] = find_constant_src (insn))"
3686   [(set (match_dup 0) (match_dup 2))]
3687 {
3688   rtx c = operands[2];
3689   rtx r = operands[0];
3690
3691   if (GET_CODE (r) == SUBREG)
3692     r = SUBREG_REG (r);
3693
3694   if (SSE_REG_P (r))
3695     {
3696       if (!standard_sse_constant_p (c))
3697         FAIL;
3698     }
3699   else if (FP_REG_P (r))
3700     {
3701       if (!standard_80387_constant_p (c))
3702         FAIL;
3703     }
3704   else if (MMX_REG_P (r))
3705     FAIL;
3706 })
3707
3708 (define_split
3709   [(set (match_operand 0 "register_operand" "")
3710         (float_extend (match_operand 1 "memory_operand" "")))]
3711   "reload_completed
3712    && MEM_P (operands[1])
3713    && (GET_MODE (operands[0]) == TFmode
3714        || GET_MODE (operands[0]) == XFmode
3715        || GET_MODE (operands[0]) == SFmode
3716        || GET_MODE (operands[0]) == DFmode)
3717    && (operands[2] = find_constant_src (insn))"
3718   [(set (match_dup 0) (match_dup 2))]
3719 {
3720   rtx c = operands[2];
3721   rtx r = operands[0];
3722
3723   if (GET_CODE (r) == SUBREG)
3724     r = SUBREG_REG (r);
3725
3726   if (SSE_REG_P (r))
3727     {
3728       if (!standard_sse_constant_p (c))
3729         FAIL;
3730     }
3731   else if (FP_REG_P (r))
3732     {
3733       if (!standard_80387_constant_p (c))
3734         FAIL;
3735     }
3736   else if (MMX_REG_P (r))
3737     FAIL;
3738 })
3739
3740 (define_insn "swapxf"
3741   [(set (match_operand:XF 0 "register_operand" "+f")
3742         (match_operand:XF 1 "register_operand" "+f"))
3743    (set (match_dup 1)
3744         (match_dup 0))]
3745   "TARGET_80387"
3746 {
3747   if (STACK_TOP_P (operands[0]))
3748     return "fxch\t%1";
3749   else
3750     return "fxch\t%0";
3751 }
3752   [(set_attr "type" "fxch")
3753    (set_attr "mode" "XF")])
3754
3755 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3756 (define_split
3757   [(set (match_operand:X87MODEF 0 "register_operand" "")
3758         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3759   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3760    && (standard_80387_constant_p (operands[1]) == 8
3761        || standard_80387_constant_p (operands[1]) == 9)"
3762   [(set (match_dup 0)(match_dup 1))
3763    (set (match_dup 0)
3764         (neg:X87MODEF (match_dup 0)))]
3765 {
3766   REAL_VALUE_TYPE r;
3767
3768   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3769   if (real_isnegzero (&r))
3770     operands[1] = CONST0_RTX (<MODE>mode);
3771   else
3772     operands[1] = CONST1_RTX (<MODE>mode);
3773 })
3774
3775 (define_split
3776   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3777         (match_operand:TF 1 "general_operand" ""))]
3778   "reload_completed
3779    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3780   [(const_int 0)]
3781   "ix86_split_long_move (operands); DONE;")
3782 \f
3783 ;; Zero extension instructions
3784
3785 (define_expand "zero_extendhisi2"
3786   [(set (match_operand:SI 0 "register_operand" "")
3787      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3788   ""
3789 {
3790   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3791     {
3792       operands[1] = force_reg (HImode, operands[1]);
3793       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3794       DONE;
3795     }
3796 })
3797
3798 (define_insn "zero_extendhisi2_and"
3799   [(set (match_operand:SI 0 "register_operand" "=r")
3800      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3801    (clobber (reg:CC FLAGS_REG))]
3802   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3803   "#"
3804   [(set_attr "type" "alu1")
3805    (set_attr "mode" "SI")])
3806
3807 (define_split
3808   [(set (match_operand:SI 0 "register_operand" "")
3809         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3810    (clobber (reg:CC FLAGS_REG))]
3811   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3812    && optimize_function_for_speed_p (cfun)"
3813   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3814               (clobber (reg:CC FLAGS_REG))])]
3815   "")
3816
3817 (define_insn "*zero_extendhisi2_movzwl"
3818   [(set (match_operand:SI 0 "register_operand" "=r")
3819      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3820   "!TARGET_ZERO_EXTEND_WITH_AND
3821    || optimize_function_for_size_p (cfun)"
3822   "movz{wl|x}\t{%1, %0|%0, %1}"
3823   [(set_attr "type" "imovx")
3824    (set_attr "mode" "SI")])
3825
3826 (define_expand "zero_extendqihi2"
3827   [(parallel
3828     [(set (match_operand:HI 0 "register_operand" "")
3829        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3830      (clobber (reg:CC FLAGS_REG))])]
3831   ""
3832   "")
3833
3834 (define_insn "*zero_extendqihi2_and"
3835   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3836      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3837    (clobber (reg:CC FLAGS_REG))]
3838   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3839   "#"
3840   [(set_attr "type" "alu1")
3841    (set_attr "mode" "HI")])
3842
3843 (define_insn "*zero_extendqihi2_movzbw_and"
3844   [(set (match_operand:HI 0 "register_operand" "=r,r")
3845      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3846    (clobber (reg:CC FLAGS_REG))]
3847   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3848   "#"
3849   [(set_attr "type" "imovx,alu1")
3850    (set_attr "mode" "HI")])
3851
3852 ; zero extend to SImode here to avoid partial register stalls
3853 (define_insn "*zero_extendqihi2_movzbl"
3854   [(set (match_operand:HI 0 "register_operand" "=r")
3855      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3856   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3857    && reload_completed"
3858   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3859   [(set_attr "type" "imovx")
3860    (set_attr "mode" "SI")])
3861
3862 ;; For the movzbw case strip only the clobber
3863 (define_split
3864   [(set (match_operand:HI 0 "register_operand" "")
3865         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3866    (clobber (reg:CC FLAGS_REG))]
3867   "reload_completed
3868    && (!TARGET_ZERO_EXTEND_WITH_AND
3869        || optimize_function_for_size_p (cfun))
3870    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3871   [(set (match_operand:HI 0 "register_operand" "")
3872         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3873
3874 ;; When source and destination does not overlap, clear destination
3875 ;; first and then do the movb
3876 (define_split
3877   [(set (match_operand:HI 0 "register_operand" "")
3878         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3879    (clobber (reg:CC FLAGS_REG))]
3880   "reload_completed
3881    && ANY_QI_REG_P (operands[0])
3882    && (TARGET_ZERO_EXTEND_WITH_AND
3883        && optimize_function_for_speed_p (cfun))
3884    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3885   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3886 {
3887   operands[2] = gen_lowpart (QImode, operands[0]);
3888   ix86_expand_clear (operands[0]);
3889 })
3890
3891 ;; Rest is handled by single and.
3892 (define_split
3893   [(set (match_operand:HI 0 "register_operand" "")
3894         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3895    (clobber (reg:CC FLAGS_REG))]
3896   "reload_completed
3897    && true_regnum (operands[0]) == true_regnum (operands[1])"
3898   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3899               (clobber (reg:CC FLAGS_REG))])]
3900   "")
3901
3902 (define_expand "zero_extendqisi2"
3903   [(parallel
3904     [(set (match_operand:SI 0 "register_operand" "")
3905        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3906      (clobber (reg:CC FLAGS_REG))])]
3907   ""
3908   "")
3909
3910 (define_insn "*zero_extendqisi2_and"
3911   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3912      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3913    (clobber (reg:CC FLAGS_REG))]
3914   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3915   "#"
3916   [(set_attr "type" "alu1")
3917    (set_attr "mode" "SI")])
3918
3919 (define_insn "*zero_extendqisi2_movzbl_and"
3920   [(set (match_operand:SI 0 "register_operand" "=r,r")
3921      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3922    (clobber (reg:CC FLAGS_REG))]
3923   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3924   "#"
3925   [(set_attr "type" "imovx,alu1")
3926    (set_attr "mode" "SI")])
3927
3928 (define_insn "*zero_extendqisi2_movzbl"
3929   [(set (match_operand:SI 0 "register_operand" "=r")
3930      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3931   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3932    && reload_completed"
3933   "movz{bl|x}\t{%1, %0|%0, %1}"
3934   [(set_attr "type" "imovx")
3935    (set_attr "mode" "SI")])
3936
3937 ;; For the movzbl case strip only the clobber
3938 (define_split
3939   [(set (match_operand:SI 0 "register_operand" "")
3940         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3941    (clobber (reg:CC FLAGS_REG))]
3942   "reload_completed
3943    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3944    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3945   [(set (match_dup 0)
3946         (zero_extend:SI (match_dup 1)))])
3947
3948 ;; When source and destination does not overlap, clear destination
3949 ;; first and then do the movb
3950 (define_split
3951   [(set (match_operand:SI 0 "register_operand" "")
3952         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3953    (clobber (reg:CC FLAGS_REG))]
3954   "reload_completed
3955    && ANY_QI_REG_P (operands[0])
3956    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3957    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3958    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3959   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3960 {
3961   operands[2] = gen_lowpart (QImode, operands[0]);
3962   ix86_expand_clear (operands[0]);
3963 })
3964
3965 ;; Rest is handled by single and.
3966 (define_split
3967   [(set (match_operand:SI 0 "register_operand" "")
3968         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3969    (clobber (reg:CC FLAGS_REG))]
3970   "reload_completed
3971    && true_regnum (operands[0]) == true_regnum (operands[1])"
3972   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3973               (clobber (reg:CC FLAGS_REG))])]
3974   "")
3975
3976 ;; %%% Kill me once multi-word ops are sane.
3977 (define_expand "zero_extendsidi2"
3978   [(set (match_operand:DI 0 "register_operand" "")
3979      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3980   ""
3981 {
3982   if (!TARGET_64BIT)
3983     {
3984       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3985       DONE;
3986     }
3987 })
3988
3989 (define_insn "zero_extendsidi2_32"
3990   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3991         (zero_extend:DI
3992          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3993    (clobber (reg:CC FLAGS_REG))]
3994   "!TARGET_64BIT"
3995   "@
3996    #
3997    #
3998    #
3999    movd\t{%1, %0|%0, %1}
4000    movd\t{%1, %0|%0, %1}
4001    %vmovd\t{%1, %0|%0, %1}
4002    %vmovd\t{%1, %0|%0, %1}"
4003   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4004    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4005    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4006
4007 (define_insn "zero_extendsidi2_rex64"
4008   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4009      (zero_extend:DI
4010        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4011   "TARGET_64BIT"
4012   "@
4013    mov\t{%k1, %k0|%k0, %k1}
4014    #
4015    movd\t{%1, %0|%0, %1}
4016    movd\t{%1, %0|%0, %1}
4017    %vmovd\t{%1, %0|%0, %1}
4018    %vmovd\t{%1, %0|%0, %1}"
4019   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4020    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4021    (set_attr "prefix_0f" "0,*,*,*,*,*")
4022    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4023
4024 (define_split
4025   [(set (match_operand:DI 0 "memory_operand" "")
4026      (zero_extend:DI (match_dup 0)))]
4027   "TARGET_64BIT"
4028   [(set (match_dup 4) (const_int 0))]
4029   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4030
4031 (define_split
4032   [(set (match_operand:DI 0 "register_operand" "")
4033         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4034    (clobber (reg:CC FLAGS_REG))]
4035   "!TARGET_64BIT && reload_completed
4036    && true_regnum (operands[0]) == true_regnum (operands[1])"
4037   [(set (match_dup 4) (const_int 0))]
4038   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4039
4040 (define_split
4041   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4042         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4043    (clobber (reg:CC FLAGS_REG))]
4044   "!TARGET_64BIT && reload_completed
4045    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4046   [(set (match_dup 3) (match_dup 1))
4047    (set (match_dup 4) (const_int 0))]
4048   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4049
4050 (define_insn "zero_extendhidi2"
4051   [(set (match_operand:DI 0 "register_operand" "=r")
4052      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4053   "TARGET_64BIT"
4054   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4055   [(set_attr "type" "imovx")
4056    (set_attr "mode" "SI")])
4057
4058 (define_insn "zero_extendqidi2"
4059   [(set (match_operand:DI 0 "register_operand" "=r")
4060      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4061   "TARGET_64BIT"
4062   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4063   [(set_attr "type" "imovx")
4064    (set_attr "mode" "SI")])
4065 \f
4066 ;; Sign extension instructions
4067
4068 (define_expand "extendsidi2"
4069   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4070                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4071               (clobber (reg:CC FLAGS_REG))
4072               (clobber (match_scratch:SI 2 ""))])]
4073   ""
4074 {
4075   if (TARGET_64BIT)
4076     {
4077       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4078       DONE;
4079     }
4080 })
4081
4082 (define_insn "*extendsidi2_1"
4083   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4084         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4085    (clobber (reg:CC FLAGS_REG))
4086    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4087   "!TARGET_64BIT"
4088   "#")
4089
4090 (define_insn "extendsidi2_rex64"
4091   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4092         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4093   "TARGET_64BIT"
4094   "@
4095    {cltq|cdqe}
4096    movs{lq|x}\t{%1, %0|%0, %1}"
4097   [(set_attr "type" "imovx")
4098    (set_attr "mode" "DI")
4099    (set_attr "prefix_0f" "0")
4100    (set_attr "modrm" "0,1")])
4101
4102 (define_insn "extendhidi2"
4103   [(set (match_operand:DI 0 "register_operand" "=r")
4104         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4105   "TARGET_64BIT"
4106   "movs{wq|x}\t{%1, %0|%0, %1}"
4107   [(set_attr "type" "imovx")
4108    (set_attr "mode" "DI")])
4109
4110 (define_insn "extendqidi2"
4111   [(set (match_operand:DI 0 "register_operand" "=r")
4112         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4113   "TARGET_64BIT"
4114   "movs{bq|x}\t{%1, %0|%0, %1}"
4115    [(set_attr "type" "imovx")
4116     (set_attr "mode" "DI")])
4117
4118 ;; Extend to memory case when source register does die.
4119 (define_split
4120   [(set (match_operand:DI 0 "memory_operand" "")
4121         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4122    (clobber (reg:CC FLAGS_REG))
4123    (clobber (match_operand:SI 2 "register_operand" ""))]
4124   "(reload_completed
4125     && dead_or_set_p (insn, operands[1])
4126     && !reg_mentioned_p (operands[1], operands[0]))"
4127   [(set (match_dup 3) (match_dup 1))
4128    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4129               (clobber (reg:CC FLAGS_REG))])
4130    (set (match_dup 4) (match_dup 1))]
4131   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4132
4133 ;; Extend to memory case when source register does not die.
4134 (define_split
4135   [(set (match_operand:DI 0 "memory_operand" "")
4136         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4137    (clobber (reg:CC FLAGS_REG))
4138    (clobber (match_operand:SI 2 "register_operand" ""))]
4139   "reload_completed"
4140   [(const_int 0)]
4141 {
4142   split_di (&operands[0], 1, &operands[3], &operands[4]);
4143
4144   emit_move_insn (operands[3], operands[1]);
4145
4146   /* Generate a cltd if possible and doing so it profitable.  */
4147   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4148       && true_regnum (operands[1]) == AX_REG
4149       && true_regnum (operands[2]) == DX_REG)
4150     {
4151       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4152     }
4153   else
4154     {
4155       emit_move_insn (operands[2], operands[1]);
4156       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4157     }
4158   emit_move_insn (operands[4], operands[2]);
4159   DONE;
4160 })
4161
4162 ;; Extend to register case.  Optimize case where source and destination
4163 ;; registers match and cases where we can use cltd.
4164 (define_split
4165   [(set (match_operand:DI 0 "register_operand" "")
4166         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4167    (clobber (reg:CC FLAGS_REG))
4168    (clobber (match_scratch:SI 2 ""))]
4169   "reload_completed"
4170   [(const_int 0)]
4171 {
4172   split_di (&operands[0], 1, &operands[3], &operands[4]);
4173
4174   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4175     emit_move_insn (operands[3], operands[1]);
4176
4177   /* Generate a cltd if possible and doing so it profitable.  */
4178   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4179       && true_regnum (operands[3]) == AX_REG)
4180     {
4181       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4182       DONE;
4183     }
4184
4185   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4186     emit_move_insn (operands[4], operands[1]);
4187
4188   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4189   DONE;
4190 })
4191
4192 (define_insn "extendhisi2"
4193   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4194         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4195   ""
4196 {
4197   switch (get_attr_prefix_0f (insn))
4198     {
4199     case 0:
4200       return "{cwtl|cwde}";
4201     default:
4202       return "movs{wl|x}\t{%1, %0|%0, %1}";
4203     }
4204 }
4205   [(set_attr "type" "imovx")
4206    (set_attr "mode" "SI")
4207    (set (attr "prefix_0f")
4208      ;; movsx is short decodable while cwtl is vector decoded.
4209      (if_then_else (and (eq_attr "cpu" "!k6")
4210                         (eq_attr "alternative" "0"))
4211         (const_string "0")
4212         (const_string "1")))
4213    (set (attr "modrm")
4214      (if_then_else (eq_attr "prefix_0f" "0")
4215         (const_string "0")
4216         (const_string "1")))])
4217
4218 (define_insn "*extendhisi2_zext"
4219   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4220         (zero_extend:DI
4221           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4222   "TARGET_64BIT"
4223 {
4224   switch (get_attr_prefix_0f (insn))
4225     {
4226     case 0:
4227       return "{cwtl|cwde}";
4228     default:
4229       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4230     }
4231 }
4232   [(set_attr "type" "imovx")
4233    (set_attr "mode" "SI")
4234    (set (attr "prefix_0f")
4235      ;; movsx is short decodable while cwtl is vector decoded.
4236      (if_then_else (and (eq_attr "cpu" "!k6")
4237                         (eq_attr "alternative" "0"))
4238         (const_string "0")
4239         (const_string "1")))
4240    (set (attr "modrm")
4241      (if_then_else (eq_attr "prefix_0f" "0")
4242         (const_string "0")
4243         (const_string "1")))])
4244
4245 (define_insn "extendqihi2"
4246   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4247         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4248   ""
4249 {
4250   switch (get_attr_prefix_0f (insn))
4251     {
4252     case 0:
4253       return "{cbtw|cbw}";
4254     default:
4255       return "movs{bw|x}\t{%1, %0|%0, %1}";
4256     }
4257 }
4258   [(set_attr "type" "imovx")
4259    (set_attr "mode" "HI")
4260    (set (attr "prefix_0f")
4261      ;; movsx is short decodable while cwtl is vector decoded.
4262      (if_then_else (and (eq_attr "cpu" "!k6")
4263                         (eq_attr "alternative" "0"))
4264         (const_string "0")
4265         (const_string "1")))
4266    (set (attr "modrm")
4267      (if_then_else (eq_attr "prefix_0f" "0")
4268         (const_string "0")
4269         (const_string "1")))])
4270
4271 (define_insn "extendqisi2"
4272   [(set (match_operand:SI 0 "register_operand" "=r")
4273         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4274   ""
4275   "movs{bl|x}\t{%1, %0|%0, %1}"
4276    [(set_attr "type" "imovx")
4277     (set_attr "mode" "SI")])
4278
4279 (define_insn "*extendqisi2_zext"
4280   [(set (match_operand:DI 0 "register_operand" "=r")
4281         (zero_extend:DI
4282           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4283   "TARGET_64BIT"
4284   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4285    [(set_attr "type" "imovx")
4286     (set_attr "mode" "SI")])
4287 \f
4288 ;; Conversions between float and double.
4289
4290 ;; These are all no-ops in the model used for the 80387.  So just
4291 ;; emit moves.
4292
4293 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4294 (define_insn "*dummy_extendsfdf2"
4295   [(set (match_operand:DF 0 "push_operand" "=<")
4296         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4297   "0"
4298   "#")
4299
4300 (define_split
4301   [(set (match_operand:DF 0 "push_operand" "")
4302         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4303   ""
4304   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4305    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4306
4307 (define_insn "*dummy_extendsfxf2"
4308   [(set (match_operand:XF 0 "push_operand" "=<")
4309         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4310   "0"
4311   "#")
4312
4313 (define_split
4314   [(set (match_operand:XF 0 "push_operand" "")
4315         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4316   ""
4317   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4318    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4319   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4320
4321 (define_split
4322   [(set (match_operand:XF 0 "push_operand" "")
4323         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4324   ""
4325   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4326    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4327   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4328
4329 (define_expand "extendsfdf2"
4330   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4331         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4332   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4333 {
4334   /* ??? Needed for compress_float_constant since all fp constants
4335      are LEGITIMATE_CONSTANT_P.  */
4336   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4337     {
4338       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4339           && standard_80387_constant_p (operands[1]) > 0)
4340         {
4341           operands[1] = simplify_const_unary_operation
4342             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4343           emit_move_insn_1 (operands[0], operands[1]);
4344           DONE;
4345         }
4346       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4347     }
4348 })
4349
4350 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4351    cvtss2sd:
4352       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4353       cvtps2pd xmm2,xmm1
4354    We do the conversion post reload to avoid producing of 128bit spills
4355    that might lead to ICE on 32bit target.  The sequence unlikely combine
4356    anyway.  */
4357 (define_split
4358   [(set (match_operand:DF 0 "register_operand" "")
4359         (float_extend:DF
4360           (match_operand:SF 1 "nonimmediate_operand" "")))]
4361   "TARGET_USE_VECTOR_FP_CONVERTS
4362    && optimize_insn_for_speed_p ()
4363    && reload_completed && SSE_REG_P (operands[0])"
4364    [(set (match_dup 2)
4365          (float_extend:V2DF
4366            (vec_select:V2SF
4367              (match_dup 3)
4368              (parallel [(const_int 0) (const_int 1)]))))]
4369 {
4370   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4371   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4372   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4373      Try to avoid move when unpacking can be done in source.  */
4374   if (REG_P (operands[1]))
4375     {
4376       /* If it is unsafe to overwrite upper half of source, we need
4377          to move to destination and unpack there.  */
4378       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4380           && true_regnum (operands[0]) != true_regnum (operands[1]))
4381         {
4382           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4383           emit_move_insn (tmp, operands[1]);
4384         }
4385       else
4386         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4387       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4388                                              operands[3]));
4389     }
4390   else
4391     emit_insn (gen_vec_setv4sf_0 (operands[3],
4392                                   CONST0_RTX (V4SFmode), operands[1]));
4393 })
4394
4395 (define_insn "*extendsfdf2_mixed"
4396   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4397         (float_extend:DF
4398           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4399   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4400 {
4401   switch (which_alternative)
4402     {
4403     case 0:
4404     case 1:
4405       return output_387_reg_move (insn, operands);
4406
4407     case 2:
4408       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4409
4410     default:
4411       gcc_unreachable ();
4412     }
4413 }
4414   [(set_attr "type" "fmov,fmov,ssecvt")
4415    (set_attr "prefix" "orig,orig,maybe_vex")
4416    (set_attr "mode" "SF,XF,DF")])
4417
4418 (define_insn "*extendsfdf2_sse"
4419   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4420         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4421   "TARGET_SSE2 && TARGET_SSE_MATH"
4422   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4423   [(set_attr "type" "ssecvt")
4424    (set_attr "prefix" "maybe_vex")
4425    (set_attr "mode" "DF")])
4426
4427 (define_insn "*extendsfdf2_i387"
4428   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4429         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4430   "TARGET_80387"
4431   "* return output_387_reg_move (insn, operands);"
4432   [(set_attr "type" "fmov")
4433    (set_attr "mode" "SF,XF")])
4434
4435 (define_expand "extend<mode>xf2"
4436   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4437         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4438   "TARGET_80387"
4439 {
4440   /* ??? Needed for compress_float_constant since all fp constants
4441      are LEGITIMATE_CONSTANT_P.  */
4442   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4443     {
4444       if (standard_80387_constant_p (operands[1]) > 0)
4445         {
4446           operands[1] = simplify_const_unary_operation
4447             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4448           emit_move_insn_1 (operands[0], operands[1]);
4449           DONE;
4450         }
4451       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4452     }
4453 })
4454
4455 (define_insn "*extend<mode>xf2_i387"
4456   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4457         (float_extend:XF
4458           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4459   "TARGET_80387"
4460   "* return output_387_reg_move (insn, operands);"
4461   [(set_attr "type" "fmov")
4462    (set_attr "mode" "<MODE>,XF")])
4463
4464 ;; %%% This seems bad bad news.
4465 ;; This cannot output into an f-reg because there is no way to be sure
4466 ;; of truncating in that case.  Otherwise this is just like a simple move
4467 ;; insn.  So we pretend we can output to a reg in order to get better
4468 ;; register preferencing, but we really use a stack slot.
4469
4470 ;; Conversion from DFmode to SFmode.
4471
4472 (define_expand "truncdfsf2"
4473   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4474         (float_truncate:SF
4475           (match_operand:DF 1 "nonimmediate_operand" "")))]
4476   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4477 {
4478   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4479     ;
4480   else if (flag_unsafe_math_optimizations)
4481     ;
4482   else
4483     {
4484       enum ix86_stack_slot slot = (virtuals_instantiated
4485                                    ? SLOT_TEMP
4486                                    : SLOT_VIRTUAL);
4487       rtx temp = assign_386_stack_local (SFmode, slot);
4488       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4489       DONE;
4490     }
4491 })
4492
4493 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4494    cvtsd2ss:
4495       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4496       cvtpd2ps xmm2,xmm1
4497    We do the conversion post reload to avoid producing of 128bit spills
4498    that might lead to ICE on 32bit target.  The sequence unlikely combine
4499    anyway.  */
4500 (define_split
4501   [(set (match_operand:SF 0 "register_operand" "")
4502         (float_truncate:SF
4503           (match_operand:DF 1 "nonimmediate_operand" "")))]
4504   "TARGET_USE_VECTOR_FP_CONVERTS
4505    && optimize_insn_for_speed_p ()
4506    && reload_completed && SSE_REG_P (operands[0])"
4507    [(set (match_dup 2)
4508          (vec_concat:V4SF
4509            (float_truncate:V2SF
4510              (match_dup 4))
4511            (match_dup 3)))]
4512 {
4513   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4514   operands[3] = CONST0_RTX (V2SFmode);
4515   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4516   /* Use movsd for loading from memory, unpcklpd for registers.
4517      Try to avoid move when unpacking can be done in source, or SSE3
4518      movddup is available.  */
4519   if (REG_P (operands[1]))
4520     {
4521       if (!TARGET_SSE3
4522           && true_regnum (operands[0]) != true_regnum (operands[1])
4523           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4524               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4525         {
4526           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4527           emit_move_insn (tmp, operands[1]);
4528           operands[1] = tmp;
4529         }
4530       else if (!TARGET_SSE3)
4531         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4532       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4533     }
4534   else
4535     emit_insn (gen_sse2_loadlpd (operands[4],
4536                                  CONST0_RTX (V2DFmode), operands[1]));
4537 })
4538
4539 (define_expand "truncdfsf2_with_temp"
4540   [(parallel [(set (match_operand:SF 0 "" "")
4541                    (float_truncate:SF (match_operand:DF 1 "" "")))
4542               (clobber (match_operand:SF 2 "" ""))])]
4543   "")
4544
4545 (define_insn "*truncdfsf_fast_mixed"
4546   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4547         (float_truncate:SF
4548           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4549   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4550 {
4551   switch (which_alternative)
4552     {
4553     case 0:
4554       return output_387_reg_move (insn, operands);
4555     case 1:
4556       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4557     default:
4558       gcc_unreachable ();
4559     }
4560 }
4561   [(set_attr "type" "fmov,ssecvt")
4562    (set_attr "prefix" "orig,maybe_vex")
4563    (set_attr "mode" "SF")])
4564
4565 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4566 ;; because nothing we do here is unsafe.
4567 (define_insn "*truncdfsf_fast_sse"
4568   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4569         (float_truncate:SF
4570           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4571   "TARGET_SSE2 && TARGET_SSE_MATH"
4572   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4573   [(set_attr "type" "ssecvt")
4574    (set_attr "prefix" "maybe_vex")
4575    (set_attr "mode" "SF")])
4576
4577 (define_insn "*truncdfsf_fast_i387"
4578   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4579         (float_truncate:SF
4580           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4581   "TARGET_80387 && flag_unsafe_math_optimizations"
4582   "* return output_387_reg_move (insn, operands);"
4583   [(set_attr "type" "fmov")
4584    (set_attr "mode" "SF")])
4585
4586 (define_insn "*truncdfsf_mixed"
4587   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4588         (float_truncate:SF
4589           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4590    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4591   "TARGET_MIX_SSE_I387"
4592 {
4593   switch (which_alternative)
4594     {
4595     case 0:
4596       return output_387_reg_move (insn, operands);
4597     case 1:
4598       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4599
4600     default:
4601       return "#";
4602     }
4603 }
4604   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4605    (set_attr "unit" "*,*,i387,i387,i387")
4606    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4607    (set_attr "mode" "SF")])
4608
4609 (define_insn "*truncdfsf_i387"
4610   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4611         (float_truncate:SF
4612           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4613    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4614   "TARGET_80387"
4615 {
4616   switch (which_alternative)
4617     {
4618     case 0:
4619       return output_387_reg_move (insn, operands);
4620
4621     default:
4622       return "#";
4623     }
4624 }
4625   [(set_attr "type" "fmov,multi,multi,multi")
4626    (set_attr "unit" "*,i387,i387,i387")
4627    (set_attr "mode" "SF")])
4628
4629 (define_insn "*truncdfsf2_i387_1"
4630   [(set (match_operand:SF 0 "memory_operand" "=m")
4631         (float_truncate:SF
4632           (match_operand:DF 1 "register_operand" "f")))]
4633   "TARGET_80387
4634    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4635    && !TARGET_MIX_SSE_I387"
4636   "* return output_387_reg_move (insn, operands);"
4637   [(set_attr "type" "fmov")
4638    (set_attr "mode" "SF")])
4639
4640 (define_split
4641   [(set (match_operand:SF 0 "register_operand" "")
4642         (float_truncate:SF
4643          (match_operand:DF 1 "fp_register_operand" "")))
4644    (clobber (match_operand 2 "" ""))]
4645   "reload_completed"
4646   [(set (match_dup 2) (match_dup 1))
4647    (set (match_dup 0) (match_dup 2))]
4648 {
4649   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4650 })
4651
4652 ;; Conversion from XFmode to {SF,DF}mode
4653
4654 (define_expand "truncxf<mode>2"
4655   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4656                    (float_truncate:MODEF
4657                      (match_operand:XF 1 "register_operand" "")))
4658               (clobber (match_dup 2))])]
4659   "TARGET_80387"
4660 {
4661   if (flag_unsafe_math_optimizations)
4662     {
4663       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4664       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4665       if (reg != operands[0])
4666         emit_move_insn (operands[0], reg);
4667       DONE;
4668     }
4669   else
4670     {
4671      enum ix86_stack_slot slot = (virtuals_instantiated
4672                                   ? SLOT_TEMP
4673                                   : SLOT_VIRTUAL);
4674       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4675     }
4676 })
4677
4678 (define_insn "*truncxfsf2_mixed"
4679   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4680         (float_truncate:SF
4681           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4682    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4683   "TARGET_80387"
4684 {
4685   gcc_assert (!which_alternative);
4686   return output_387_reg_move (insn, operands);
4687 }
4688   [(set_attr "type" "fmov,multi,multi,multi")
4689    (set_attr "unit" "*,i387,i387,i387")
4690    (set_attr "mode" "SF")])
4691
4692 (define_insn "*truncxfdf2_mixed"
4693   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4694         (float_truncate:DF
4695           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4696    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4697   "TARGET_80387"
4698 {
4699   gcc_assert (!which_alternative);
4700   return output_387_reg_move (insn, operands);
4701 }
4702   [(set_attr "type" "fmov,multi,multi,multi")
4703    (set_attr "unit" "*,i387,i387,i387")
4704    (set_attr "mode" "DF")])
4705
4706 (define_insn "truncxf<mode>2_i387_noop"
4707   [(set (match_operand:MODEF 0 "register_operand" "=f")
4708         (float_truncate:MODEF
4709           (match_operand:XF 1 "register_operand" "f")))]
4710   "TARGET_80387 && flag_unsafe_math_optimizations"
4711   "* return output_387_reg_move (insn, operands);"
4712   [(set_attr "type" "fmov")
4713    (set_attr "mode" "<MODE>")])
4714
4715 (define_insn "*truncxf<mode>2_i387"
4716   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4717         (float_truncate:MODEF
4718           (match_operand:XF 1 "register_operand" "f")))]
4719   "TARGET_80387"
4720   "* return output_387_reg_move (insn, operands);"
4721   [(set_attr "type" "fmov")
4722    (set_attr "mode" "<MODE>")])
4723
4724 (define_split
4725   [(set (match_operand:MODEF 0 "register_operand" "")
4726         (float_truncate:MODEF
4727           (match_operand:XF 1 "register_operand" "")))
4728    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4729   "TARGET_80387 && reload_completed"
4730   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4731    (set (match_dup 0) (match_dup 2))]
4732   "")
4733
4734 (define_split
4735   [(set (match_operand:MODEF 0 "memory_operand" "")
4736         (float_truncate:MODEF
4737           (match_operand:XF 1 "register_operand" "")))
4738    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4739   "TARGET_80387"
4740   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4741   "")
4742 \f
4743 ;; Signed conversion to DImode.
4744
4745 (define_expand "fix_truncxfdi2"
4746   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4748               (clobber (reg:CC FLAGS_REG))])]
4749   "TARGET_80387"
4750 {
4751   if (TARGET_FISTTP)
4752    {
4753      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4754      DONE;
4755    }
4756 })
4757
4758 (define_expand "fix_trunc<mode>di2"
4759   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4760                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4761               (clobber (reg:CC FLAGS_REG))])]
4762   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4763 {
4764   if (TARGET_FISTTP
4765       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4766    {
4767      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4768      DONE;
4769    }
4770   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4771    {
4772      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4773      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4774      if (out != operands[0])
4775         emit_move_insn (operands[0], out);
4776      DONE;
4777    }
4778 })
4779
4780 ;; Signed conversion to SImode.
4781
4782 (define_expand "fix_truncxfsi2"
4783   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4784                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4785               (clobber (reg:CC FLAGS_REG))])]
4786   "TARGET_80387"
4787 {
4788   if (TARGET_FISTTP)
4789    {
4790      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4791      DONE;
4792    }
4793 })
4794
4795 (define_expand "fix_trunc<mode>si2"
4796   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4797                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4798               (clobber (reg:CC FLAGS_REG))])]
4799   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4800 {
4801   if (TARGET_FISTTP
4802       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4803    {
4804      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4805      DONE;
4806    }
4807   if (SSE_FLOAT_MODE_P (<MODE>mode))
4808    {
4809      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4810      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4811      if (out != operands[0])
4812         emit_move_insn (operands[0], out);
4813      DONE;
4814    }
4815 })
4816
4817 ;; Signed conversion to HImode.
4818
4819 (define_expand "fix_trunc<mode>hi2"
4820   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4821                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4822               (clobber (reg:CC FLAGS_REG))])]
4823   "TARGET_80387
4824    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4825 {
4826   if (TARGET_FISTTP)
4827    {
4828      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4829      DONE;
4830    }
4831 })
4832
4833 ;; Unsigned conversion to SImode.
4834
4835 (define_expand "fixuns_trunc<mode>si2"
4836   [(parallel
4837     [(set (match_operand:SI 0 "register_operand" "")
4838           (unsigned_fix:SI
4839             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4840      (use (match_dup 2))
4841      (clobber (match_scratch:<ssevecmode> 3 ""))
4842      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4843   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4844 {
4845   enum machine_mode mode = <MODE>mode;
4846   enum machine_mode vecmode = <ssevecmode>mode;
4847   REAL_VALUE_TYPE TWO31r;
4848   rtx two31;
4849
4850   if (optimize_insn_for_size_p ())
4851     FAIL;
4852
4853   real_ldexp (&TWO31r, &dconst1, 31);
4854   two31 = const_double_from_real_value (TWO31r, mode);
4855   two31 = ix86_build_const_vector (mode, true, two31);
4856   operands[2] = force_reg (vecmode, two31);
4857 })
4858
4859 (define_insn_and_split "*fixuns_trunc<mode>_1"
4860   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4861         (unsigned_fix:SI
4862           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4863    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4864    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4865    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4866   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4867    && optimize_function_for_speed_p (cfun)"
4868   "#"
4869   "&& reload_completed"
4870   [(const_int 0)]
4871 {
4872   ix86_split_convert_uns_si_sse (operands);
4873   DONE;
4874 })
4875
4876 ;; Unsigned conversion to HImode.
4877 ;; Without these patterns, we'll try the unsigned SI conversion which
4878 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4879
4880 (define_expand "fixuns_trunc<mode>hi2"
4881   [(set (match_dup 2)
4882         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4883    (set (match_operand:HI 0 "nonimmediate_operand" "")
4884         (subreg:HI (match_dup 2) 0))]
4885   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4886   "operands[2] = gen_reg_rtx (SImode);")
4887
4888 ;; When SSE is available, it is always faster to use it!
4889 (define_insn "fix_trunc<mode>di_sse"
4890   [(set (match_operand:DI 0 "register_operand" "=r,r")
4891         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4892   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4893    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4894   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4895   [(set_attr "type" "sseicvt")
4896    (set_attr "prefix" "maybe_vex")
4897    (set_attr "prefix_rex" "1")
4898    (set_attr "mode" "<MODE>")
4899    (set_attr "athlon_decode" "double,vector")
4900    (set_attr "amdfam10_decode" "double,double")])
4901
4902 (define_insn "fix_trunc<mode>si_sse"
4903   [(set (match_operand:SI 0 "register_operand" "=r,r")
4904         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4905   "SSE_FLOAT_MODE_P (<MODE>mode)
4906    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4907   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4908   [(set_attr "type" "sseicvt")
4909    (set_attr "prefix" "maybe_vex")
4910    (set_attr "mode" "<MODE>")
4911    (set_attr "athlon_decode" "double,vector")
4912    (set_attr "amdfam10_decode" "double,double")])
4913
4914 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4915 (define_peephole2
4916   [(set (match_operand:MODEF 0 "register_operand" "")
4917         (match_operand:MODEF 1 "memory_operand" ""))
4918    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4919         (fix:SSEMODEI24 (match_dup 0)))]
4920   "TARGET_SHORTEN_X87_SSE
4921    && peep2_reg_dead_p (2, operands[0])"
4922   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4923   "")
4924
4925 ;; Avoid vector decoded forms of the instruction.
4926 (define_peephole2
4927   [(match_scratch:DF 2 "Y2")
4928    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4929         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4930   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4931   [(set (match_dup 2) (match_dup 1))
4932    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4933   "")
4934
4935 (define_peephole2
4936   [(match_scratch:SF 2 "x")
4937    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4938         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4939   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4940   [(set (match_dup 2) (match_dup 1))
4941    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4942   "")
4943
4944 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4945   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4946         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4947   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4948    && TARGET_FISTTP
4949    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4950          && (TARGET_64BIT || <MODE>mode != DImode))
4951         && TARGET_SSE_MATH)
4952    && can_create_pseudo_p ()"
4953   "#"
4954   "&& 1"
4955   [(const_int 0)]
4956 {
4957   if (memory_operand (operands[0], VOIDmode))
4958     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4959   else
4960     {
4961       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4962       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4963                                                             operands[1],
4964                                                             operands[2]));
4965     }
4966   DONE;
4967 }
4968   [(set_attr "type" "fisttp")
4969    (set_attr "mode" "<MODE>")])
4970
4971 (define_insn "fix_trunc<mode>_i387_fisttp"
4972   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4973         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4974    (clobber (match_scratch:XF 2 "=&1f"))]
4975   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976    && TARGET_FISTTP
4977    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4978          && (TARGET_64BIT || <MODE>mode != DImode))
4979         && TARGET_SSE_MATH)"
4980   "* return output_fix_trunc (insn, operands, 1);"
4981   [(set_attr "type" "fisttp")
4982    (set_attr "mode" "<MODE>")])
4983
4984 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4985   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4986         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4987    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4988    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4989   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990    && TARGET_FISTTP
4991    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4992         && (TARGET_64BIT || <MODE>mode != DImode))
4993         && TARGET_SSE_MATH)"
4994   "#"
4995   [(set_attr "type" "fisttp")
4996    (set_attr "mode" "<MODE>")])
4997
4998 (define_split
4999   [(set (match_operand:X87MODEI 0 "register_operand" "")
5000         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5001    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5002    (clobber (match_scratch 3 ""))]
5003   "reload_completed"
5004   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5005               (clobber (match_dup 3))])
5006    (set (match_dup 0) (match_dup 2))]
5007   "")
5008
5009 (define_split
5010   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5011         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5012    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5013    (clobber (match_scratch 3 ""))]
5014   "reload_completed"
5015   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5016               (clobber (match_dup 3))])]
5017   "")
5018
5019 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5020 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5021 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5022 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5023 ;; function in i386.c.
5024 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5025   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5026         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5027    (clobber (reg:CC FLAGS_REG))]
5028   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029    && !TARGET_FISTTP
5030    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031          && (TARGET_64BIT || <MODE>mode != DImode))
5032    && can_create_pseudo_p ()"
5033   "#"
5034   "&& 1"
5035   [(const_int 0)]
5036 {
5037   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5038
5039   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5040   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5041   if (memory_operand (operands[0], VOIDmode))
5042     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5043                                          operands[2], operands[3]));
5044   else
5045     {
5046       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5047       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5048                                                      operands[2], operands[3],
5049                                                      operands[4]));
5050     }
5051   DONE;
5052 }
5053   [(set_attr "type" "fistp")
5054    (set_attr "i387_cw" "trunc")
5055    (set_attr "mode" "<MODE>")])
5056
5057 (define_insn "fix_truncdi_i387"
5058   [(set (match_operand:DI 0 "memory_operand" "=m")
5059         (fix:DI (match_operand 1 "register_operand" "f")))
5060    (use (match_operand:HI 2 "memory_operand" "m"))
5061    (use (match_operand:HI 3 "memory_operand" "m"))
5062    (clobber (match_scratch:XF 4 "=&1f"))]
5063   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5064    && !TARGET_FISTTP
5065    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5066   "* return output_fix_trunc (insn, operands, 0);"
5067   [(set_attr "type" "fistp")
5068    (set_attr "i387_cw" "trunc")
5069    (set_attr "mode" "DI")])
5070
5071 (define_insn "fix_truncdi_i387_with_temp"
5072   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5073         (fix:DI (match_operand 1 "register_operand" "f,f")))
5074    (use (match_operand:HI 2 "memory_operand" "m,m"))
5075    (use (match_operand:HI 3 "memory_operand" "m,m"))
5076    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5077    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5078   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5079    && !TARGET_FISTTP
5080    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5081   "#"
5082   [(set_attr "type" "fistp")
5083    (set_attr "i387_cw" "trunc")
5084    (set_attr "mode" "DI")])
5085
5086 (define_split
5087   [(set (match_operand:DI 0 "register_operand" "")
5088         (fix:DI (match_operand 1 "register_operand" "")))
5089    (use (match_operand:HI 2 "memory_operand" ""))
5090    (use (match_operand:HI 3 "memory_operand" ""))
5091    (clobber (match_operand:DI 4 "memory_operand" ""))
5092    (clobber (match_scratch 5 ""))]
5093   "reload_completed"
5094   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5095               (use (match_dup 2))
5096               (use (match_dup 3))
5097               (clobber (match_dup 5))])
5098    (set (match_dup 0) (match_dup 4))]
5099   "")
5100
5101 (define_split
5102   [(set (match_operand:DI 0 "memory_operand" "")
5103         (fix:DI (match_operand 1 "register_operand" "")))
5104    (use (match_operand:HI 2 "memory_operand" ""))
5105    (use (match_operand:HI 3 "memory_operand" ""))
5106    (clobber (match_operand:DI 4 "memory_operand" ""))
5107    (clobber (match_scratch 5 ""))]
5108   "reload_completed"
5109   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5110               (use (match_dup 2))
5111               (use (match_dup 3))
5112               (clobber (match_dup 5))])]
5113   "")
5114
5115 (define_insn "fix_trunc<mode>_i387"
5116   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5117         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5118    (use (match_operand:HI 2 "memory_operand" "m"))
5119    (use (match_operand:HI 3 "memory_operand" "m"))]
5120   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121    && !TARGET_FISTTP
5122    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5123   "* return output_fix_trunc (insn, operands, 0);"
5124   [(set_attr "type" "fistp")
5125    (set_attr "i387_cw" "trunc")
5126    (set_attr "mode" "<MODE>")])
5127
5128 (define_insn "fix_trunc<mode>_i387_with_temp"
5129   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5130         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5131    (use (match_operand:HI 2 "memory_operand" "m,m"))
5132    (use (match_operand:HI 3 "memory_operand" "m,m"))
5133    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5134   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5135    && !TARGET_FISTTP
5136    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5137   "#"
5138   [(set_attr "type" "fistp")
5139    (set_attr "i387_cw" "trunc")
5140    (set_attr "mode" "<MODE>")])
5141
5142 (define_split
5143   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5144         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5145    (use (match_operand:HI 2 "memory_operand" ""))
5146    (use (match_operand:HI 3 "memory_operand" ""))
5147    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5148   "reload_completed"
5149   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5150               (use (match_dup 2))
5151               (use (match_dup 3))])
5152    (set (match_dup 0) (match_dup 4))]
5153   "")
5154
5155 (define_split
5156   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5157         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5158    (use (match_operand:HI 2 "memory_operand" ""))
5159    (use (match_operand:HI 3 "memory_operand" ""))
5160    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5161   "reload_completed"
5162   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5163               (use (match_dup 2))
5164               (use (match_dup 3))])]
5165   "")
5166
5167 (define_insn "x86_fnstcw_1"
5168   [(set (match_operand:HI 0 "memory_operand" "=m")
5169         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5170   "TARGET_80387"
5171   "fnstcw\t%0"
5172   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5173    (set_attr "mode" "HI")
5174    (set_attr "unit" "i387")])
5175
5176 (define_insn "x86_fldcw_1"
5177   [(set (reg:HI FPCR_REG)
5178         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5179   "TARGET_80387"
5180   "fldcw\t%0"
5181   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5182    (set_attr "mode" "HI")
5183    (set_attr "unit" "i387")
5184    (set_attr "athlon_decode" "vector")
5185    (set_attr "amdfam10_decode" "vector")])
5186 \f
5187 ;; Conversion between fixed point and floating point.
5188
5189 ;; Even though we only accept memory inputs, the backend _really_
5190 ;; wants to be able to do this between registers.
5191
5192 (define_expand "floathi<mode>2"
5193   [(set (match_operand:X87MODEF 0 "register_operand" "")
5194         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5195   "TARGET_80387
5196    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5197        || TARGET_MIX_SSE_I387)"
5198   "")
5199
5200 ;; Pre-reload splitter to add memory clobber to the pattern.
5201 (define_insn_and_split "*floathi<mode>2_1"
5202   [(set (match_operand:X87MODEF 0 "register_operand" "")
5203         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5204   "TARGET_80387
5205    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5206        || TARGET_MIX_SSE_I387)
5207    && can_create_pseudo_p ()"
5208   "#"
5209   "&& 1"
5210   [(parallel [(set (match_dup 0)
5211               (float:X87MODEF (match_dup 1)))
5212    (clobber (match_dup 2))])]
5213   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5214
5215 (define_insn "*floathi<mode>2_i387_with_temp"
5216   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5217         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5218   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5219   "TARGET_80387
5220    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5221        || TARGET_MIX_SSE_I387)"
5222   "#"
5223   [(set_attr "type" "fmov,multi")
5224    (set_attr "mode" "<MODE>")
5225    (set_attr "unit" "*,i387")
5226    (set_attr "fp_int_src" "true")])
5227
5228 (define_insn "*floathi<mode>2_i387"
5229   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5230         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5231   "TARGET_80387
5232    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5233        || TARGET_MIX_SSE_I387)"
5234   "fild%Z1\t%1"
5235   [(set_attr "type" "fmov")
5236    (set_attr "mode" "<MODE>")
5237    (set_attr "fp_int_src" "true")])
5238
5239 (define_split
5240   [(set (match_operand:X87MODEF 0 "register_operand" "")
5241         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5242    (clobber (match_operand:HI 2 "memory_operand" ""))]
5243   "TARGET_80387
5244    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5245        || TARGET_MIX_SSE_I387)
5246    && reload_completed"
5247   [(set (match_dup 2) (match_dup 1))
5248    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5249   "")
5250
5251 (define_split
5252   [(set (match_operand:X87MODEF 0 "register_operand" "")
5253         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5254    (clobber (match_operand:HI 2 "memory_operand" ""))]
5255    "TARGET_80387
5256     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5257         || TARGET_MIX_SSE_I387)
5258     && reload_completed"
5259   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5260   "")
5261
5262 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5263   [(set (match_operand:X87MODEF 0 "register_operand" "")
5264         (float:X87MODEF
5265           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5266   "TARGET_80387
5267    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5268        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5269 {
5270   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5271         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5272       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5273     {
5274       rtx reg = gen_reg_rtx (XFmode);
5275       rtx insn;
5276
5277       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5278
5279       if (<X87MODEF:MODE>mode == SFmode)
5280         insn = gen_truncxfsf2 (operands[0], reg);
5281       else if (<X87MODEF:MODE>mode == DFmode)
5282         insn = gen_truncxfdf2 (operands[0], reg);
5283       else
5284         gcc_unreachable ();
5285
5286       emit_insn (insn);
5287       DONE;
5288     }
5289 })
5290
5291 ;; Pre-reload splitter to add memory clobber to the pattern.
5292 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5293   [(set (match_operand:X87MODEF 0 "register_operand" "")
5294         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5295   "((TARGET_80387
5296      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5297      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5298            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5299          || TARGET_MIX_SSE_I387))
5300     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5301         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5302         && ((<SSEMODEI24:MODE>mode == SImode
5303              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5304              && optimize_function_for_speed_p (cfun)
5305              && flag_trapping_math)
5306             || !(TARGET_INTER_UNIT_CONVERSIONS
5307                  || optimize_function_for_size_p (cfun)))))
5308    && can_create_pseudo_p ()"
5309   "#"
5310   "&& 1"
5311   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5312               (clobber (match_dup 2))])]
5313 {
5314   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5315
5316   /* Avoid store forwarding (partial memory) stall penalty
5317      by passing DImode value through XMM registers.  */
5318   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5319       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5320       && optimize_function_for_speed_p (cfun))
5321     {
5322       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5323                                                             operands[1],
5324                                                             operands[2]));
5325       DONE;
5326     }
5327 })
5328
5329 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5330   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5331         (float:MODEF
5332           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5333    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5334   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5335    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5336   "#"
5337   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5338    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5339    (set_attr "unit" "*,i387,*,*,*")
5340    (set_attr "athlon_decode" "*,*,double,direct,double")
5341    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5342    (set_attr "fp_int_src" "true")])
5343
5344 (define_insn "*floatsi<mode>2_vector_mixed"
5345   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5346         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5347   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5348    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5349   "@
5350    fild%Z1\t%1
5351    #"
5352   [(set_attr "type" "fmov,sseicvt")
5353    (set_attr "mode" "<MODE>,<ssevecmode>")
5354    (set_attr "unit" "i387,*")
5355    (set_attr "athlon_decode" "*,direct")
5356    (set_attr "amdfam10_decode" "*,double")
5357    (set_attr "fp_int_src" "true")])
5358
5359 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5360   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5361         (float:MODEF
5362           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5363   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5364   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5366   "#"
5367   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5368    (set_attr "mode" "<MODEF:MODE>")
5369    (set_attr "unit" "*,i387,*,*")
5370    (set_attr "athlon_decode" "*,*,double,direct")
5371    (set_attr "amdfam10_decode" "*,*,vector,double")
5372    (set_attr "fp_int_src" "true")])
5373
5374 (define_split
5375   [(set (match_operand:MODEF 0 "register_operand" "")
5376         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5377    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5378   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5379    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5380    && TARGET_INTER_UNIT_CONVERSIONS
5381    && reload_completed
5382    && (SSE_REG_P (operands[0])
5383        || (GET_CODE (operands[0]) == SUBREG
5384            && SSE_REG_P (operands[0])))"
5385   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5386   "")
5387
5388 (define_split
5389   [(set (match_operand:MODEF 0 "register_operand" "")
5390         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5391    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5392   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5393    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5394    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5395    && reload_completed
5396    && (SSE_REG_P (operands[0])
5397        || (GET_CODE (operands[0]) == SUBREG
5398            && SSE_REG_P (operands[0])))"
5399   [(set (match_dup 2) (match_dup 1))
5400    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5401   "")
5402
5403 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5404   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5405         (float:MODEF
5406           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5407   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5409    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5410   "@
5411    fild%Z1\t%1
5412    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5413    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5414   [(set_attr "type" "fmov,sseicvt,sseicvt")
5415    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5416    (set_attr "mode" "<MODEF:MODE>")
5417    (set (attr "prefix_rex")
5418      (if_then_else
5419        (and (eq_attr "prefix" "maybe_vex")
5420             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5421        (const_string "1")
5422        (const_string "*")))
5423    (set_attr "unit" "i387,*,*")
5424    (set_attr "athlon_decode" "*,double,direct")
5425    (set_attr "amdfam10_decode" "*,vector,double")
5426    (set_attr "fp_int_src" "true")])
5427
5428 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5429   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5430         (float:MODEF
5431           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5432   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5433    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5434    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5435   "@
5436    fild%Z1\t%1
5437    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5438   [(set_attr "type" "fmov,sseicvt")
5439    (set_attr "prefix" "orig,maybe_vex")
5440    (set_attr "mode" "<MODEF:MODE>")
5441    (set (attr "prefix_rex")
5442      (if_then_else
5443        (and (eq_attr "prefix" "maybe_vex")
5444             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5445        (const_string "1")
5446        (const_string "*")))
5447    (set_attr "athlon_decode" "*,direct")
5448    (set_attr "amdfam10_decode" "*,double")
5449    (set_attr "fp_int_src" "true")])
5450
5451 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5452   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5453         (float:MODEF
5454           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5455    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5456   "TARGET_SSE2 && TARGET_SSE_MATH
5457    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5458   "#"
5459   [(set_attr "type" "sseicvt")
5460    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5461    (set_attr "athlon_decode" "double,direct,double")
5462    (set_attr "amdfam10_decode" "vector,double,double")
5463    (set_attr "fp_int_src" "true")])
5464
5465 (define_insn "*floatsi<mode>2_vector_sse"
5466   [(set (match_operand:MODEF 0 "register_operand" "=x")
5467         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5468   "TARGET_SSE2 && TARGET_SSE_MATH
5469    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5470   "#"
5471   [(set_attr "type" "sseicvt")
5472    (set_attr "mode" "<MODE>")
5473    (set_attr "athlon_decode" "direct")
5474    (set_attr "amdfam10_decode" "double")
5475    (set_attr "fp_int_src" "true")])
5476
5477 (define_split
5478   [(set (match_operand:MODEF 0 "register_operand" "")
5479         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5480    (clobber (match_operand:SI 2 "memory_operand" ""))]
5481   "TARGET_SSE2 && TARGET_SSE_MATH
5482    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5483    && reload_completed
5484    && (SSE_REG_P (operands[0])
5485        || (GET_CODE (operands[0]) == SUBREG
5486            && SSE_REG_P (operands[0])))"
5487   [(const_int 0)]
5488 {
5489   rtx op1 = operands[1];
5490
5491   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5492                                      <MODE>mode, 0);
5493   if (GET_CODE (op1) == SUBREG)
5494     op1 = SUBREG_REG (op1);
5495
5496   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5497     {
5498       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5499       emit_insn (gen_sse2_loadld (operands[4],
5500                                   CONST0_RTX (V4SImode), operands[1]));
5501     }
5502   /* We can ignore possible trapping value in the
5503      high part of SSE register for non-trapping math. */
5504   else if (SSE_REG_P (op1) && !flag_trapping_math)
5505     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5506   else
5507     {
5508       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5509       emit_move_insn (operands[2], operands[1]);
5510       emit_insn (gen_sse2_loadld (operands[4],
5511                                   CONST0_RTX (V4SImode), operands[2]));
5512     }
5513   emit_insn
5514     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5515   DONE;
5516 })
5517
5518 (define_split
5519   [(set (match_operand:MODEF 0 "register_operand" "")
5520         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5521    (clobber (match_operand:SI 2 "memory_operand" ""))]
5522   "TARGET_SSE2 && TARGET_SSE_MATH
5523    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5524    && reload_completed
5525    && (SSE_REG_P (operands[0])
5526        || (GET_CODE (operands[0]) == SUBREG
5527            && SSE_REG_P (operands[0])))"
5528   [(const_int 0)]
5529 {
5530   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5531                                      <MODE>mode, 0);
5532   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5533
5534   emit_insn (gen_sse2_loadld (operands[4],
5535                               CONST0_RTX (V4SImode), operands[1]));
5536   emit_insn
5537     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5538   DONE;
5539 })
5540
5541 (define_split
5542   [(set (match_operand:MODEF 0 "register_operand" "")
5543         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5544   "TARGET_SSE2 && TARGET_SSE_MATH
5545    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5546    && reload_completed
5547    && (SSE_REG_P (operands[0])
5548        || (GET_CODE (operands[0]) == SUBREG
5549            && SSE_REG_P (operands[0])))"
5550   [(const_int 0)]
5551 {
5552   rtx op1 = operands[1];
5553
5554   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5555                                      <MODE>mode, 0);
5556   if (GET_CODE (op1) == SUBREG)
5557     op1 = SUBREG_REG (op1);
5558
5559   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5560     {
5561       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562       emit_insn (gen_sse2_loadld (operands[4],
5563                                   CONST0_RTX (V4SImode), operands[1]));
5564     }
5565   /* We can ignore possible trapping value in the
5566      high part of SSE register for non-trapping math. */
5567   else if (SSE_REG_P (op1) && !flag_trapping_math)
5568     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5569   else
5570     gcc_unreachable ();
5571   emit_insn
5572     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5573   DONE;
5574 })
5575
5576 (define_split
5577   [(set (match_operand:MODEF 0 "register_operand" "")
5578         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5579   "TARGET_SSE2 && TARGET_SSE_MATH
5580    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5581    && reload_completed
5582    && (SSE_REG_P (operands[0])
5583        || (GET_CODE (operands[0]) == SUBREG
5584            && SSE_REG_P (operands[0])))"
5585   [(const_int 0)]
5586 {
5587   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5588                                      <MODE>mode, 0);
5589   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5590
5591   emit_insn (gen_sse2_loadld (operands[4],
5592                               CONST0_RTX (V4SImode), operands[1]));
5593   emit_insn
5594     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5595   DONE;
5596 })
5597
5598 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5599   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5600         (float:MODEF
5601           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5602   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5603   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5604    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5605   "#"
5606   [(set_attr "type" "sseicvt")
5607    (set_attr "mode" "<MODEF:MODE>")
5608    (set_attr "athlon_decode" "double,direct")
5609    (set_attr "amdfam10_decode" "vector,double")
5610    (set_attr "fp_int_src" "true")])
5611
5612 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5613   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5614         (float:MODEF
5615           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5616   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5617    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5618    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5619   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5620   [(set_attr "type" "sseicvt")
5621    (set_attr "prefix" "maybe_vex")
5622    (set_attr "mode" "<MODEF:MODE>")
5623    (set (attr "prefix_rex")
5624      (if_then_else
5625        (and (eq_attr "prefix" "maybe_vex")
5626             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5627        (const_string "1")
5628        (const_string "*")))
5629    (set_attr "athlon_decode" "double,direct")
5630    (set_attr "amdfam10_decode" "vector,double")
5631    (set_attr "fp_int_src" "true")])
5632
5633 (define_split
5634   [(set (match_operand:MODEF 0 "register_operand" "")
5635         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5636    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5637   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5638    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5639    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5640    && reload_completed
5641    && (SSE_REG_P (operands[0])
5642        || (GET_CODE (operands[0]) == SUBREG
5643            && SSE_REG_P (operands[0])))"
5644   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5645   "")
5646
5647 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5648   [(set (match_operand:MODEF 0 "register_operand" "=x")
5649         (float:MODEF
5650           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5651   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5652    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5653    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5654   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5655   [(set_attr "type" "sseicvt")
5656    (set_attr "prefix" "maybe_vex")
5657    (set_attr "mode" "<MODEF:MODE>")
5658    (set (attr "prefix_rex")
5659      (if_then_else
5660        (and (eq_attr "prefix" "maybe_vex")
5661             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5662        (const_string "1")
5663        (const_string "*")))
5664    (set_attr "athlon_decode" "direct")
5665    (set_attr "amdfam10_decode" "double")
5666    (set_attr "fp_int_src" "true")])
5667
5668 (define_split
5669   [(set (match_operand:MODEF 0 "register_operand" "")
5670         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5671    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5672   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5673    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5674    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5675    && reload_completed
5676    && (SSE_REG_P (operands[0])
5677        || (GET_CODE (operands[0]) == SUBREG
5678            && SSE_REG_P (operands[0])))"
5679   [(set (match_dup 2) (match_dup 1))
5680    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5681   "")
5682
5683 (define_split
5684   [(set (match_operand:MODEF 0 "register_operand" "")
5685         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5686    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5687   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5688    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5689    && reload_completed
5690    && (SSE_REG_P (operands[0])
5691        || (GET_CODE (operands[0]) == SUBREG
5692            && SSE_REG_P (operands[0])))"
5693   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5694   "")
5695
5696 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5697   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5698         (float:X87MODEF
5699           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5700   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5701   "TARGET_80387
5702    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5703   "@
5704    fild%Z1\t%1
5705    #"
5706   [(set_attr "type" "fmov,multi")
5707    (set_attr "mode" "<X87MODEF:MODE>")
5708    (set_attr "unit" "*,i387")
5709    (set_attr "fp_int_src" "true")])
5710
5711 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5712   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5713         (float:X87MODEF
5714           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5715   "TARGET_80387
5716    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5717   "fild%Z1\t%1"
5718   [(set_attr "type" "fmov")
5719    (set_attr "mode" "<X87MODEF:MODE>")
5720    (set_attr "fp_int_src" "true")])
5721
5722 (define_split
5723   [(set (match_operand:X87MODEF 0 "register_operand" "")
5724         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5725    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5726   "TARGET_80387
5727    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5728    && reload_completed
5729    && FP_REG_P (operands[0])"
5730   [(set (match_dup 2) (match_dup 1))
5731    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5732   "")
5733
5734 (define_split
5735   [(set (match_operand:X87MODEF 0 "register_operand" "")
5736         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5737    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5738   "TARGET_80387
5739    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5740    && reload_completed
5741    && FP_REG_P (operands[0])"
5742   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5743   "")
5744
5745 ;; Avoid store forwarding (partial memory) stall penalty
5746 ;; by passing DImode value through XMM registers.  */
5747
5748 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5749   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5750         (float:X87MODEF
5751           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5752    (clobber (match_scratch:V4SI 3 "=X,x"))
5753    (clobber (match_scratch:V4SI 4 "=X,x"))
5754    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5755   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5756    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5757    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5758   "#"
5759   [(set_attr "type" "multi")
5760    (set_attr "mode" "<X87MODEF:MODE>")
5761    (set_attr "unit" "i387")
5762    (set_attr "fp_int_src" "true")])
5763
5764 (define_split
5765   [(set (match_operand:X87MODEF 0 "register_operand" "")
5766         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5767    (clobber (match_scratch:V4SI 3 ""))
5768    (clobber (match_scratch:V4SI 4 ""))
5769    (clobber (match_operand:DI 2 "memory_operand" ""))]
5770   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5771    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5772    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5773    && reload_completed
5774    && FP_REG_P (operands[0])"
5775   [(set (match_dup 2) (match_dup 3))
5776    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5777 {
5778   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5779      Assemble the 64-bit DImode value in an xmm register.  */
5780   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5781                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5782   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5783                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5784   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5785                                          operands[4]));
5786
5787   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5788 })
5789
5790 (define_split
5791   [(set (match_operand:X87MODEF 0 "register_operand" "")
5792         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5793    (clobber (match_scratch:V4SI 3 ""))
5794    (clobber (match_scratch:V4SI 4 ""))
5795    (clobber (match_operand:DI 2 "memory_operand" ""))]
5796   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5797    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5798    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5799    && reload_completed
5800    && FP_REG_P (operands[0])"
5801   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5802   "")
5803
5804 ;; Avoid store forwarding (partial memory) stall penalty by extending
5805 ;; SImode value to DImode through XMM register instead of pushing two
5806 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5807 ;; targets benefit from this optimization. Also note that fild
5808 ;; loads from memory only.
5809
5810 (define_insn "*floatunssi<mode>2_1"
5811   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5812         (unsigned_float:X87MODEF
5813           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5814    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5815    (clobber (match_scratch:SI 3 "=X,x"))]
5816   "!TARGET_64BIT
5817    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5818    && TARGET_SSE"
5819   "#"
5820   [(set_attr "type" "multi")
5821    (set_attr "mode" "<MODE>")])
5822
5823 (define_split
5824   [(set (match_operand:X87MODEF 0 "register_operand" "")
5825         (unsigned_float:X87MODEF
5826           (match_operand:SI 1 "register_operand" "")))
5827    (clobber (match_operand:DI 2 "memory_operand" ""))
5828    (clobber (match_scratch:SI 3 ""))]
5829   "!TARGET_64BIT
5830    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5831    && TARGET_SSE
5832    && reload_completed"
5833   [(set (match_dup 2) (match_dup 1))
5834    (set (match_dup 0)
5835         (float:X87MODEF (match_dup 2)))]
5836   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5837
5838 (define_split
5839   [(set (match_operand:X87MODEF 0 "register_operand" "")
5840         (unsigned_float:X87MODEF
5841           (match_operand:SI 1 "memory_operand" "")))
5842    (clobber (match_operand:DI 2 "memory_operand" ""))
5843    (clobber (match_scratch:SI 3 ""))]
5844   "!TARGET_64BIT
5845    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5846    && TARGET_SSE
5847    && reload_completed"
5848   [(set (match_dup 2) (match_dup 3))
5849    (set (match_dup 0)
5850         (float:X87MODEF (match_dup 2)))]
5851 {
5852   emit_move_insn (operands[3], operands[1]);
5853   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5854 })
5855
5856 (define_expand "floatunssi<mode>2"
5857   [(parallel
5858      [(set (match_operand:X87MODEF 0 "register_operand" "")
5859            (unsigned_float:X87MODEF
5860              (match_operand:SI 1 "nonimmediate_operand" "")))
5861       (clobber (match_dup 2))
5862       (clobber (match_scratch:SI 3 ""))])]
5863   "!TARGET_64BIT
5864    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5865         && TARGET_SSE)
5866        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5867 {
5868   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5869     {
5870       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5871       DONE;
5872     }
5873   else
5874     {
5875       enum ix86_stack_slot slot = (virtuals_instantiated
5876                                    ? SLOT_TEMP
5877                                    : SLOT_VIRTUAL);
5878       operands[2] = assign_386_stack_local (DImode, slot);
5879     }
5880 })
5881
5882 (define_expand "floatunsdisf2"
5883   [(use (match_operand:SF 0 "register_operand" ""))
5884    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5885   "TARGET_64BIT && TARGET_SSE_MATH"
5886   "x86_emit_floatuns (operands); DONE;")
5887
5888 (define_expand "floatunsdidf2"
5889   [(use (match_operand:DF 0 "register_operand" ""))
5890    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5891   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5892    && TARGET_SSE2 && TARGET_SSE_MATH"
5893 {
5894   if (TARGET_64BIT)
5895     x86_emit_floatuns (operands);
5896   else
5897     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5898   DONE;
5899 })
5900 \f
5901 ;; Add instructions
5902
5903 (define_expand "add<mode>3"
5904   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5905         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5906                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5907   ""
5908   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5909
5910 (define_insn_and_split "*add<dwi>3_doubleword"
5911   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5912         (plus:<DWI>
5913           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5914           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5915    (clobber (reg:CC FLAGS_REG))]
5916   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5917   "#"
5918   "reload_completed"
5919   [(parallel [(set (reg:CC FLAGS_REG)
5920                    (unspec:CC [(match_dup 1) (match_dup 2)]
5921                               UNSPEC_ADD_CARRY))
5922               (set (match_dup 0)
5923                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5924    (parallel [(set (match_dup 3)
5925                    (plus:DWIH
5926                      (match_dup 4)
5927                      (plus:DWIH
5928                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5929                        (match_dup 5))))
5930               (clobber (reg:CC FLAGS_REG))])]
5931   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5932
5933 (define_insn "*add<mode>3_cc"
5934   [(set (reg:CC FLAGS_REG)
5935         (unspec:CC
5936           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5937            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5938           UNSPEC_ADD_CARRY))
5939    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5940         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5941   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5942   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5943   [(set_attr "type" "alu")
5944    (set_attr "mode" "<MODE>")])
5945
5946 (define_insn "addqi3_cc"
5947   [(set (reg:CC FLAGS_REG)
5948         (unspec:CC
5949           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5950            (match_operand:QI 2 "general_operand" "qn,qm")]
5951           UNSPEC_ADD_CARRY))
5952    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5953         (plus:QI (match_dup 1) (match_dup 2)))]
5954   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5955   "add{b}\t{%2, %0|%0, %2}"
5956   [(set_attr "type" "alu")
5957    (set_attr "mode" "QI")])
5958
5959 (define_insn "*lea_1"
5960   [(set (match_operand:DWIH 0 "register_operand" "=r")
5961         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5962   ""
5963   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5964   [(set_attr "type" "lea")
5965    (set_attr "mode" "<MODE>")])
5966
5967 (define_insn "*lea_2"
5968   [(set (match_operand:SI 0 "register_operand" "=r")
5969         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5970   "TARGET_64BIT"
5971   "lea{l}\t{%a1, %0|%0, %a1}"
5972   [(set_attr "type" "lea")
5973    (set_attr "mode" "SI")])
5974
5975 (define_insn "*lea_2_zext"
5976   [(set (match_operand:DI 0 "register_operand" "=r")
5977         (zero_extend:DI
5978           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5979   "TARGET_64BIT"
5980   "lea{l}\t{%a1, %k0|%k0, %a1}"
5981   [(set_attr "type" "lea")
5982    (set_attr "mode" "SI")])
5983
5984 (define_insn "*add<mode>_1"
5985   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5986         (plus:SWI48
5987           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5988           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5989    (clobber (reg:CC FLAGS_REG))]
5990   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5991 {
5992   switch (get_attr_type (insn))
5993     {
5994     case TYPE_LEA:
5995       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5996       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5997
5998     case TYPE_INCDEC:
5999       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6000       if (operands[2] == const1_rtx)
6001         return "inc{<imodesuffix>}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == constm1_rtx);
6005           return "dec{<imodesuffix>}\t%0";
6006         }
6007
6008     default:
6009       /* Use add as much as possible to replace lea for AGU optimization. */
6010       if (which_alternative == 2 && TARGET_OPT_AGU)
6011         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6012         
6013       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014
6015       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6016          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6017       if (CONST_INT_P (operands[2])
6018           /* Avoid overflows.  */
6019           && (<MODE>mode != DImode
6020               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6021           && (INTVAL (operands[2]) == 128
6022               || (INTVAL (operands[2]) < 0
6023                   && INTVAL (operands[2]) != -128)))
6024         {
6025           operands[2] = GEN_INT (-INTVAL (operands[2]));
6026           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6027         }
6028       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6029     }
6030 }
6031   [(set (attr "type")
6032      (cond [(and (eq_attr "alternative" "2") 
6033                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6034               (const_string "lea")
6035             (eq_attr "alternative" "3")
6036               (const_string "lea")
6037             ; Current assemblers are broken and do not allow @GOTOFF in
6038             ; ought but a memory context.
6039             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6040               (const_string "lea")
6041             (match_operand:SWI48 2 "incdec_operand" "")
6042               (const_string "incdec")
6043            ]
6044            (const_string "alu")))
6045    (set (attr "length_immediate")
6046       (if_then_else
6047         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6048         (const_string "1")
6049         (const_string "*")))
6050    (set_attr "mode" "<MODE>")])
6051
6052 ;; It may seem that nonimmediate operand is proper one for operand 1.
6053 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6054 ;; we take care in ix86_binary_operator_ok to not allow two memory
6055 ;; operands so proper swapping will be done in reload.  This allow
6056 ;; patterns constructed from addsi_1 to match.
6057
6058 (define_insn "*addsi_1_zext"
6059   [(set (match_operand:DI 0 "register_operand" "=r,r")
6060         (zero_extend:DI
6061           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6062                    (match_operand:SI 2 "general_operand" "g,li"))))
6063    (clobber (reg:CC FLAGS_REG))]
6064   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6065 {
6066   switch (get_attr_type (insn))
6067     {
6068     case TYPE_LEA:
6069       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6070       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6071
6072     case TYPE_INCDEC:
6073       if (operands[2] == const1_rtx)
6074         return "inc{l}\t%k0";
6075       else
6076         {
6077           gcc_assert (operands[2] == constm1_rtx);
6078           return "dec{l}\t%k0";
6079         }
6080
6081     default:
6082       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6083          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6084       if (CONST_INT_P (operands[2])
6085           && (INTVAL (operands[2]) == 128
6086               || (INTVAL (operands[2]) < 0
6087                   && INTVAL (operands[2]) != -128)))
6088         {
6089           operands[2] = GEN_INT (-INTVAL (operands[2]));
6090           return "sub{l}\t{%2, %k0|%k0, %2}";
6091         }
6092       return "add{l}\t{%2, %k0|%k0, %2}";
6093     }
6094 }
6095   [(set (attr "type")
6096      (cond [(eq_attr "alternative" "1")
6097               (const_string "lea")
6098             ; Current assemblers are broken and do not allow @GOTOFF in
6099             ; ought but a memory context.
6100             (match_operand:SI 2 "pic_symbolic_operand" "")
6101               (const_string "lea")
6102             (match_operand:SI 2 "incdec_operand" "")
6103               (const_string "incdec")
6104            ]
6105            (const_string "alu")))
6106    (set (attr "length_immediate")
6107       (if_then_else
6108         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6109         (const_string "1")
6110         (const_string "*")))
6111    (set_attr "mode" "SI")])
6112
6113 (define_insn "*addhi_1"
6114   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6115         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6116                  (match_operand:HI 2 "general_operand" "rn,rm")))
6117    (clobber (reg:CC FLAGS_REG))]
6118   "TARGET_PARTIAL_REG_STALL
6119    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6120 {
6121   switch (get_attr_type (insn))
6122     {
6123     case TYPE_INCDEC:
6124       if (operands[2] == const1_rtx)
6125         return "inc{w}\t%0";
6126       else
6127         {
6128           gcc_assert (operands[2] == constm1_rtx);
6129           return "dec{w}\t%0";
6130         }
6131
6132     default:
6133       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6134          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135       if (CONST_INT_P (operands[2])
6136           && (INTVAL (operands[2]) == 128
6137               || (INTVAL (operands[2]) < 0
6138                   && INTVAL (operands[2]) != -128)))
6139         {
6140           operands[2] = GEN_INT (-INTVAL (operands[2]));
6141           return "sub{w}\t{%2, %0|%0, %2}";
6142         }
6143       return "add{w}\t{%2, %0|%0, %2}";
6144     }
6145 }
6146   [(set (attr "type")
6147      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6148         (const_string "incdec")
6149         (const_string "alu")))
6150    (set (attr "length_immediate")
6151       (if_then_else
6152         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6153         (const_string "1")
6154         (const_string "*")))
6155    (set_attr "mode" "HI")])
6156
6157 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6158 ;; type optimizations enabled by define-splits.  This is not important
6159 ;; for PII, and in fact harmful because of partial register stalls.
6160
6161 (define_insn "*addhi_1_lea"
6162   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6163         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6164                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6165    (clobber (reg:CC FLAGS_REG))]
6166   "!TARGET_PARTIAL_REG_STALL
6167    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6168 {
6169   switch (get_attr_type (insn))
6170     {
6171     case TYPE_LEA:
6172       return "#";
6173     case TYPE_INCDEC:
6174       if (operands[2] == const1_rtx)
6175         return "inc{w}\t%0";
6176       else
6177         {
6178           gcc_assert (operands[2] == constm1_rtx);
6179           return "dec{w}\t%0";
6180         }
6181
6182     default:
6183       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6184          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6185       if (CONST_INT_P (operands[2])
6186           && (INTVAL (operands[2]) == 128
6187               || (INTVAL (operands[2]) < 0
6188                   && INTVAL (operands[2]) != -128)))
6189         {
6190           operands[2] = GEN_INT (-INTVAL (operands[2]));
6191           return "sub{w}\t{%2, %0|%0, %2}";
6192         }
6193       return "add{w}\t{%2, %0|%0, %2}";
6194     }
6195 }
6196   [(set (attr "type")
6197      (if_then_else (eq_attr "alternative" "2")
6198         (const_string "lea")
6199         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6200            (const_string "incdec")
6201            (const_string "alu"))))
6202    (set (attr "length_immediate")
6203       (if_then_else
6204         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6205         (const_string "1")
6206         (const_string "*")))
6207    (set_attr "mode" "HI,HI,SI")])
6208
6209 (define_insn "*addqi_1"
6210   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6211         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6212                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6213    (clobber (reg:CC FLAGS_REG))]
6214   "TARGET_PARTIAL_REG_STALL
6215    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6216 {
6217   int widen = (which_alternative == 2);
6218   switch (get_attr_type (insn))
6219     {
6220     case TYPE_INCDEC:
6221       if (operands[2] == const1_rtx)
6222         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6223       else
6224         {
6225           gcc_assert (operands[2] == constm1_rtx);
6226           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6227         }
6228
6229     default:
6230       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6232       if (CONST_INT_P (operands[2])
6233           && (INTVAL (operands[2]) == 128
6234               || (INTVAL (operands[2]) < 0
6235                   && INTVAL (operands[2]) != -128)))
6236         {
6237           operands[2] = GEN_INT (-INTVAL (operands[2]));
6238           if (widen)
6239             return "sub{l}\t{%2, %k0|%k0, %2}";
6240           else
6241             return "sub{b}\t{%2, %0|%0, %2}";
6242         }
6243       if (widen)
6244         return "add{l}\t{%k2, %k0|%k0, %k2}";
6245       else
6246         return "add{b}\t{%2, %0|%0, %2}";
6247     }
6248 }
6249   [(set (attr "type")
6250      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251         (const_string "incdec")
6252         (const_string "alu")))
6253    (set (attr "length_immediate")
6254       (if_then_else
6255         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6256         (const_string "1")
6257         (const_string "*")))
6258    (set_attr "mode" "QI,QI,SI")])
6259
6260 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6261 (define_insn "*addqi_1_lea"
6262   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6263         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6264                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "!TARGET_PARTIAL_REG_STALL
6267    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6268 {
6269   int widen = (which_alternative == 2);
6270   switch (get_attr_type (insn))
6271     {
6272     case TYPE_LEA:
6273       return "#";
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277       else
6278         {
6279           gcc_assert (operands[2] == constm1_rtx);
6280           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6281         }
6282
6283     default:
6284       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6285          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6286       if (CONST_INT_P (operands[2])
6287           && (INTVAL (operands[2]) == 128
6288               || (INTVAL (operands[2]) < 0
6289                   && INTVAL (operands[2]) != -128)))
6290         {
6291           operands[2] = GEN_INT (-INTVAL (operands[2]));
6292           if (widen)
6293             return "sub{l}\t{%2, %k0|%k0, %2}";
6294           else
6295             return "sub{b}\t{%2, %0|%0, %2}";
6296         }
6297       if (widen)
6298         return "add{l}\t{%k2, %k0|%k0, %k2}";
6299       else
6300         return "add{b}\t{%2, %0|%0, %2}";
6301     }
6302 }
6303   [(set (attr "type")
6304      (if_then_else (eq_attr "alternative" "3")
6305         (const_string "lea")
6306         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6307            (const_string "incdec")
6308            (const_string "alu"))))
6309    (set (attr "length_immediate")
6310       (if_then_else
6311         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6312         (const_string "1")
6313         (const_string "*")))
6314    (set_attr "mode" "QI,QI,SI,SI")])
6315
6316 (define_insn "*addqi_1_slp"
6317   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6318         (plus:QI (match_dup 0)
6319                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6320    (clobber (reg:CC FLAGS_REG))]
6321   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6322    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6323 {
6324   switch (get_attr_type (insn))
6325     {
6326     case TYPE_INCDEC:
6327       if (operands[1] == const1_rtx)
6328         return "inc{b}\t%0";
6329       else
6330         {
6331           gcc_assert (operands[1] == constm1_rtx);
6332           return "dec{b}\t%0";
6333         }
6334
6335     default:
6336       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6337       if (CONST_INT_P (operands[1])
6338           && INTVAL (operands[1]) < 0)
6339         {
6340           operands[1] = GEN_INT (-INTVAL (operands[1]));
6341           return "sub{b}\t{%1, %0|%0, %1}";
6342         }
6343       return "add{b}\t{%1, %0|%0, %1}";
6344     }
6345 }
6346   [(set (attr "type")
6347      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6348         (const_string "incdec")
6349         (const_string "alu1")))
6350    (set (attr "memory")
6351      (if_then_else (match_operand 1 "memory_operand" "")
6352         (const_string "load")
6353         (const_string "none")))
6354    (set_attr "mode" "QI")])
6355
6356 (define_insn "*add<mode>_2"
6357   [(set (reg FLAGS_REG)
6358         (compare
6359           (plus:SWI48
6360             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6361             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6362           (const_int 0)))
6363    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6364         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6365   "ix86_match_ccmode (insn, CCGOCmode)
6366    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6367    /* Current assemblers are broken and do not allow @GOTOFF in
6368       ought but a memory context.  */
6369    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6370 {
6371   switch (get_attr_type (insn))
6372     {
6373     case TYPE_INCDEC:
6374       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6375       if (operands[2] == const1_rtx)
6376         return "inc{<imodesuffix>}\t%0";
6377       else
6378         {
6379           gcc_assert (operands[2] == constm1_rtx);
6380           return "dec{<imodesuffix>}\t%0";
6381         }
6382
6383     default:
6384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6385       /* ???? In DImode, we ought to handle there the 32bit case too
6386          - do we need new constraint?  */
6387       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6388          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6389       if (CONST_INT_P (operands[2])
6390           /* Avoid overflows.  */
6391           && (<MODE>mode != DImode
6392               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6393           && (INTVAL (operands[2]) == 128
6394               || (INTVAL (operands[2]) < 0
6395                   && INTVAL (operands[2]) != -128)))
6396         {
6397           operands[2] = GEN_INT (-INTVAL (operands[2]));
6398           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6399         }
6400       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6401     }
6402 }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set (attr "length_immediate")
6408       (if_then_else
6409         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6410         (const_string "1")
6411         (const_string "*")))
6412    (set_attr "mode" "<MODE>")])
6413
6414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6415 (define_insn "*addsi_2_zext"
6416   [(set (reg FLAGS_REG)
6417         (compare
6418           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6419                    (match_operand:SI 2 "general_operand" "g"))
6420           (const_int 0)))
6421    (set (match_operand:DI 0 "register_operand" "=r")
6422         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6423   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424    && ix86_binary_operator_ok (PLUS, SImode, operands)
6425    /* Current assemblers are broken and do not allow @GOTOFF in
6426       ought but a memory context.  */
6427    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6428 {
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_INCDEC:
6432       if (operands[2] == const1_rtx)
6433         return "inc{l}\t%k0";
6434       else
6435         {
6436           gcc_assert (operands[2] == constm1_rtx);
6437           return "dec{l}\t%k0";
6438         }
6439
6440     default:
6441       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6442          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6443       if (CONST_INT_P (operands[2])
6444           && (INTVAL (operands[2]) == 128
6445               || (INTVAL (operands[2]) < 0
6446                   && INTVAL (operands[2]) != -128)))
6447         {
6448           operands[2] = GEN_INT (-INTVAL (operands[2]));
6449           return "sub{l}\t{%2, %k0|%k0, %2}";
6450         }
6451       return "add{l}\t{%2, %k0|%k0, %2}";
6452     }
6453 }
6454   [(set (attr "type")
6455      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6456         (const_string "incdec")
6457         (const_string "alu")))
6458    (set (attr "length_immediate")
6459       (if_then_else
6460         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6461         (const_string "1")
6462         (const_string "*")))
6463    (set_attr "mode" "SI")])
6464
6465 (define_insn "*addhi_2"
6466   [(set (reg FLAGS_REG)
6467         (compare
6468           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6469                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6470           (const_int 0)))
6471    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6472         (plus:HI (match_dup 1) (match_dup 2)))]
6473   "ix86_match_ccmode (insn, CCGOCmode)
6474    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6475 {
6476   switch (get_attr_type (insn))
6477     {
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{w}\t%0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx);
6484           return "dec{w}\t%0";
6485         }
6486
6487     default:
6488       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6490       if (CONST_INT_P (operands[2])
6491           && (INTVAL (operands[2]) == 128
6492               || (INTVAL (operands[2]) < 0
6493                   && INTVAL (operands[2]) != -128)))
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "sub{w}\t{%2, %0|%0, %2}";
6497         }
6498       return "add{w}\t{%2, %0|%0, %2}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu")))
6505    (set (attr "length_immediate")
6506       (if_then_else
6507         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6508         (const_string "1")
6509         (const_string "*")))
6510    (set_attr "mode" "HI")])
6511
6512 (define_insn "*addqi_2"
6513   [(set (reg FLAGS_REG)
6514         (compare
6515           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6516                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6517           (const_int 0)))
6518    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6519         (plus:QI (match_dup 1) (match_dup 2)))]
6520   "ix86_match_ccmode (insn, CCGOCmode)
6521    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6522 {
6523   switch (get_attr_type (insn))
6524     {
6525     case TYPE_INCDEC:
6526       if (operands[2] == const1_rtx)
6527         return "inc{b}\t%0";
6528       else
6529         {
6530           gcc_assert (operands[2] == constm1_rtx
6531                       || (CONST_INT_P (operands[2])
6532                           && INTVAL (operands[2]) == 255));
6533           return "dec{b}\t%0";
6534         }
6535
6536     default:
6537       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6538       if (CONST_INT_P (operands[2])
6539           && INTVAL (operands[2]) < 0)
6540         {
6541           operands[2] = GEN_INT (-INTVAL (operands[2]));
6542           return "sub{b}\t{%2, %0|%0, %2}";
6543         }
6544       return "add{b}\t{%2, %0|%0, %2}";
6545     }
6546 }
6547   [(set (attr "type")
6548      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549         (const_string "incdec")
6550         (const_string "alu")))
6551    (set_attr "mode" "QI")])
6552
6553 (define_insn "*add<mode>_3"
6554   [(set (reg FLAGS_REG)
6555         (compare
6556           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6557           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6558    (clobber (match_scratch:SWI48 0 "=r"))]
6559   "ix86_match_ccmode (insn, CCZmode)
6560    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6561    /* Current assemblers are broken and do not allow @GOTOFF in
6562       ought but a memory context.  */
6563    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6564 {
6565   switch (get_attr_type (insn))
6566     {
6567     case TYPE_INCDEC:
6568       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6569       if (operands[2] == const1_rtx)
6570         return "inc{<imodesuffix>}\t%0";
6571       else
6572         {
6573           gcc_assert (operands[2] == constm1_rtx);
6574           return "dec{<imodesuffix>}\t%0";
6575         }
6576
6577     default:
6578       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6579       /* ???? In DImode, we ought to handle there the 32bit case too
6580          - do we need new constraint?  */
6581       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6582          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6583       if (CONST_INT_P (operands[2])
6584           /* Avoid overflows.  */
6585           && (<MODE>mode != DImode
6586               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6587           && (INTVAL (operands[2]) == 128
6588               || (INTVAL (operands[2]) < 0
6589                   && INTVAL (operands[2]) != -128)))
6590         {
6591           operands[2] = GEN_INT (-INTVAL (operands[2]));
6592           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6593         }
6594       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6595     }
6596 }
6597   [(set (attr "type")
6598      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6599         (const_string "incdec")
6600         (const_string "alu")))
6601    (set (attr "length_immediate")
6602       (if_then_else
6603         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6604         (const_string "1")
6605         (const_string "*")))
6606    (set_attr "mode" "<MODE>")])
6607
6608 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6609 (define_insn "*addsi_3_zext"
6610   [(set (reg FLAGS_REG)
6611         (compare
6612           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6613           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6614    (set (match_operand:DI 0 "register_operand" "=r")
6615         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6616   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6617    && ix86_binary_operator_ok (PLUS, SImode, operands)
6618    /* Current assemblers are broken and do not allow @GOTOFF in
6619       ought but a memory context.  */
6620    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6621 {
6622   switch (get_attr_type (insn))
6623     {
6624     case TYPE_INCDEC:
6625       if (operands[2] == const1_rtx)
6626         return "inc{l}\t%k0";
6627       else
6628         {
6629           gcc_assert (operands[2] == constm1_rtx);
6630           return "dec{l}\t%k0";
6631         }
6632
6633     default:
6634       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6635          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6636       if (CONST_INT_P (operands[2])
6637           && (INTVAL (operands[2]) == 128
6638               || (INTVAL (operands[2]) < 0
6639                   && INTVAL (operands[2]) != -128)))
6640         {
6641           operands[2] = GEN_INT (-INTVAL (operands[2]));
6642           return "sub{l}\t{%2, %k0|%k0, %2}";
6643         }
6644       return "add{l}\t{%2, %k0|%k0, %2}";
6645     }
6646 }
6647   [(set (attr "type")
6648      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6649         (const_string "incdec")
6650         (const_string "alu")))
6651    (set (attr "length_immediate")
6652       (if_then_else
6653         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6654         (const_string "1")
6655         (const_string "*")))
6656    (set_attr "mode" "SI")])
6657
6658 (define_insn "*addhi_3"
6659   [(set (reg FLAGS_REG)
6660         (compare
6661           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6662           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6663    (clobber (match_scratch:HI 0 "=r"))]
6664   "ix86_match_ccmode (insn, CCZmode)
6665    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6666 {
6667   switch (get_attr_type (insn))
6668     {
6669     case TYPE_INCDEC:
6670       if (operands[2] == const1_rtx)
6671         return "inc{w}\t%0";
6672       else
6673         {
6674           gcc_assert (operands[2] == constm1_rtx);
6675           return "dec{w}\t%0";
6676         }
6677
6678     default:
6679       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6680          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6681       if (CONST_INT_P (operands[2])
6682           && (INTVAL (operands[2]) == 128
6683               || (INTVAL (operands[2]) < 0
6684                   && INTVAL (operands[2]) != -128)))
6685         {
6686           operands[2] = GEN_INT (-INTVAL (operands[2]));
6687           return "sub{w}\t{%2, %0|%0, %2}";
6688         }
6689       return "add{w}\t{%2, %0|%0, %2}";
6690     }
6691 }
6692   [(set (attr "type")
6693      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6694         (const_string "incdec")
6695         (const_string "alu")))
6696    (set (attr "length_immediate")
6697       (if_then_else
6698         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6699         (const_string "1")
6700         (const_string "*")))
6701    (set_attr "mode" "HI")])
6702
6703 (define_insn "*addqi_3"
6704   [(set (reg FLAGS_REG)
6705         (compare
6706           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6707           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6708    (clobber (match_scratch:QI 0 "=q"))]
6709   "ix86_match_ccmode (insn, CCZmode)
6710    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6711 {
6712   switch (get_attr_type (insn))
6713     {
6714     case TYPE_INCDEC:
6715       if (operands[2] == const1_rtx)
6716         return "inc{b}\t%0";
6717       else
6718         {
6719           gcc_assert (operands[2] == constm1_rtx
6720                       || (CONST_INT_P (operands[2])
6721                           && INTVAL (operands[2]) == 255));
6722           return "dec{b}\t%0";
6723         }
6724
6725     default:
6726       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6727       if (CONST_INT_P (operands[2])
6728           && INTVAL (operands[2]) < 0)
6729         {
6730           operands[2] = GEN_INT (-INTVAL (operands[2]));
6731           return "sub{b}\t{%2, %0|%0, %2}";
6732         }
6733       return "add{b}\t{%2, %0|%0, %2}";
6734     }
6735 }
6736   [(set (attr "type")
6737      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738         (const_string "incdec")
6739         (const_string "alu")))
6740    (set_attr "mode" "QI")])
6741
6742 ; For comparisons against 1, -1 and 128, we may generate better code
6743 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6744 ; is matched then.  We can't accept general immediate, because for
6745 ; case of overflows,  the result is messed up.
6746 ; This pattern also don't hold of 0x8000000000000000, since the value
6747 ; overflows when negated.
6748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6749 ; only for comparisons not depending on it.
6750
6751 (define_insn "*adddi_4"
6752   [(set (reg FLAGS_REG)
6753         (compare
6754           (match_operand:DI 1 "nonimmediate_operand" "0")
6755           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6756    (clobber (match_scratch:DI 0 "=rm"))]
6757   "TARGET_64BIT
6758    && ix86_match_ccmode (insn, CCGCmode)"
6759 {
6760   switch (get_attr_type (insn))
6761     {
6762     case TYPE_INCDEC:
6763       if (operands[2] == constm1_rtx)
6764         return "inc{q}\t%0";
6765       else
6766         {
6767           gcc_assert (operands[2] == const1_rtx);
6768           return "dec{q}\t%0";
6769         }
6770
6771     default:
6772       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6774          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6775       if ((INTVAL (operands[2]) == -128
6776            || (INTVAL (operands[2]) > 0
6777                && INTVAL (operands[2]) != 128))
6778           /* Avoid overflows.  */
6779           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6780         return "sub{q}\t{%2, %0|%0, %2}";
6781       operands[2] = GEN_INT (-INTVAL (operands[2]));
6782       return "add{q}\t{%2, %0|%0, %2}";
6783     }
6784 }
6785   [(set (attr "type")
6786      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6787         (const_string "incdec")
6788         (const_string "alu")))
6789    (set (attr "length_immediate")
6790       (if_then_else
6791         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6792         (const_string "1")
6793         (const_string "*")))
6794    (set_attr "mode" "DI")])
6795
6796 ; For comparisons against 1, -1 and 128, we may generate better code
6797 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6798 ; is matched then.  We can't accept general immediate, because for
6799 ; case of overflows,  the result is messed up.
6800 ; This pattern also don't hold of 0x80000000, since the value overflows
6801 ; when negated.
6802 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6803 ; only for comparisons not depending on it.
6804
6805 (define_insn "*addsi_4"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (match_operand:SI 1 "nonimmediate_operand" "0")
6809           (match_operand:SI 2 "const_int_operand" "n")))
6810    (clobber (match_scratch:SI 0 "=rm"))]
6811   "ix86_match_ccmode (insn, CCGCmode)
6812    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6813 {
6814   switch (get_attr_type (insn))
6815     {
6816     case TYPE_INCDEC:
6817       if (operands[2] == constm1_rtx)
6818         return "inc{l}\t%0";
6819       else
6820         {
6821           gcc_assert (operands[2] == const1_rtx);
6822           return "dec{l}\t%0";
6823         }
6824
6825     default:
6826       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6827       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6828          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6829       if ((INTVAL (operands[2]) == -128
6830            || (INTVAL (operands[2]) > 0
6831                && INTVAL (operands[2]) != 128)))
6832         return "sub{l}\t{%2, %0|%0, %2}";
6833       operands[2] = GEN_INT (-INTVAL (operands[2]));
6834       return "add{l}\t{%2, %0|%0, %2}";
6835     }
6836 }
6837   [(set (attr "type")
6838      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6839         (const_string "incdec")
6840         (const_string "alu")))
6841    (set (attr "length_immediate")
6842       (if_then_else
6843         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6844         (const_string "1")
6845         (const_string "*")))
6846    (set_attr "mode" "SI")])
6847
6848 ; See comments above addsi_4 for details.
6849
6850 (define_insn "*addhi_4"
6851   [(set (reg FLAGS_REG)
6852         (compare
6853           (match_operand:HI 1 "nonimmediate_operand" "0")
6854           (match_operand:HI 2 "const_int_operand" "n")))
6855    (clobber (match_scratch:HI 0 "=rm"))]
6856   "ix86_match_ccmode (insn, CCGCmode)
6857    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6858 {
6859   switch (get_attr_type (insn))
6860     {
6861     case TYPE_INCDEC:
6862       if (operands[2] == constm1_rtx)
6863         return "inc{w}\t%0";
6864       else
6865         {
6866           gcc_assert (operands[2] == const1_rtx);
6867           return "dec{w}\t%0";
6868         }
6869
6870     default:
6871       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6872       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6873          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6874       if ((INTVAL (operands[2]) == -128
6875            || (INTVAL (operands[2]) > 0
6876                && INTVAL (operands[2]) != 128)))
6877         return "sub{w}\t{%2, %0|%0, %2}";
6878       operands[2] = GEN_INT (-INTVAL (operands[2]));
6879       return "add{w}\t{%2, %0|%0, %2}";
6880     }
6881 }
6882   [(set (attr "type")
6883      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6884         (const_string "incdec")
6885         (const_string "alu")))
6886    (set (attr "length_immediate")
6887       (if_then_else
6888         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6889         (const_string "1")
6890         (const_string "*")))
6891    (set_attr "mode" "HI")])
6892
6893 ; See comments above addsi_4 for details.
6894
6895 (define_insn "*addqi_4"
6896   [(set (reg FLAGS_REG)
6897         (compare
6898           (match_operand:QI 1 "nonimmediate_operand" "0")
6899           (match_operand:QI 2 "const_int_operand" "n")))
6900    (clobber (match_scratch:QI 0 "=qm"))]
6901   "ix86_match_ccmode (insn, CCGCmode)
6902    && (INTVAL (operands[2]) & 0xff) != 0x80"
6903 {
6904   switch (get_attr_type (insn))
6905     {
6906     case TYPE_INCDEC:
6907       if (operands[2] == constm1_rtx
6908           || (CONST_INT_P (operands[2])
6909               && INTVAL (operands[2]) == 255))
6910         return "inc{b}\t%0";
6911       else
6912         {
6913           gcc_assert (operands[2] == const1_rtx);
6914           return "dec{b}\t%0";
6915         }
6916
6917     default:
6918       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6919       if (INTVAL (operands[2]) < 0)
6920         {
6921           operands[2] = GEN_INT (-INTVAL (operands[2]));
6922           return "add{b}\t{%2, %0|%0, %2}";
6923         }
6924       return "sub{b}\t{%2, %0|%0, %2}";
6925     }
6926 }
6927   [(set (attr "type")
6928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6929         (const_string "incdec")
6930         (const_string "alu")))
6931    (set_attr "mode" "QI")])
6932
6933 (define_insn "*add<mode>_5"
6934   [(set (reg FLAGS_REG)
6935         (compare
6936           (plus:SWI48
6937             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6938             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6939           (const_int 0)))
6940    (clobber (match_scratch:SWI48 0 "=r"))]
6941   "ix86_match_ccmode (insn, CCGOCmode)
6942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6943    /* Current assemblers are broken and do not allow @GOTOFF in
6944       ought but a memory context.  */
6945    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6946 {
6947   switch (get_attr_type (insn))
6948     {
6949     case TYPE_INCDEC:
6950       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6951       if (operands[2] == const1_rtx)
6952         return "inc{<imodesuffix>}\t%0";
6953       else
6954         {
6955           gcc_assert (operands[2] == constm1_rtx);
6956           return "dec{<imodesuffix>}\t%0";
6957         }
6958
6959     default:
6960       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6963       if (CONST_INT_P (operands[2])
6964           /* Avoid overflows.  */
6965           && (<MODE>mode != DImode
6966               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6967           && (INTVAL (operands[2]) == 128
6968               || (INTVAL (operands[2]) < 0
6969                   && INTVAL (operands[2]) != -128)))
6970         {
6971           operands[2] = GEN_INT (-INTVAL (operands[2]));
6972           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6973         }
6974       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6975     }
6976 }
6977   [(set (attr "type")
6978      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6979         (const_string "incdec")
6980         (const_string "alu")))
6981    (set (attr "length_immediate")
6982       (if_then_else
6983         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6984         (const_string "1")
6985         (const_string "*")))
6986    (set_attr "mode" "<MODE>")])
6987
6988 (define_insn "*addhi_5"
6989   [(set (reg FLAGS_REG)
6990         (compare
6991           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6992                    (match_operand:HI 2 "general_operand" "rmn"))
6993           (const_int 0)))
6994    (clobber (match_scratch:HI 0 "=r"))]
6995   "ix86_match_ccmode (insn, CCGOCmode)
6996    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6997 {
6998   switch (get_attr_type (insn))
6999     {
7000     case TYPE_INCDEC:
7001       if (operands[2] == const1_rtx)
7002         return "inc{w}\t%0";
7003       else
7004         {
7005           gcc_assert (operands[2] == constm1_rtx);
7006           return "dec{w}\t%0";
7007         }
7008
7009     default:
7010       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7012       if (CONST_INT_P (operands[2])
7013           && (INTVAL (operands[2]) == 128
7014               || (INTVAL (operands[2]) < 0
7015                   && INTVAL (operands[2]) != -128)))
7016         {
7017           operands[2] = GEN_INT (-INTVAL (operands[2]));
7018           return "sub{w}\t{%2, %0|%0, %2}";
7019         }
7020       return "add{w}\t{%2, %0|%0, %2}";
7021     }
7022 }
7023   [(set (attr "type")
7024      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7025         (const_string "incdec")
7026         (const_string "alu")))
7027    (set (attr "length_immediate")
7028       (if_then_else
7029         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7030         (const_string "1")
7031         (const_string "*")))
7032    (set_attr "mode" "HI")])
7033
7034 (define_insn "*addqi_5"
7035   [(set (reg FLAGS_REG)
7036         (compare
7037           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7038                    (match_operand:QI 2 "general_operand" "qmn"))
7039           (const_int 0)))
7040    (clobber (match_scratch:QI 0 "=q"))]
7041   "ix86_match_ccmode (insn, CCGOCmode)
7042    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7043 {
7044   switch (get_attr_type (insn))
7045     {
7046     case TYPE_INCDEC:
7047       if (operands[2] == const1_rtx)
7048         return "inc{b}\t%0";
7049       else
7050         {
7051           gcc_assert (operands[2] == constm1_rtx
7052                       || (CONST_INT_P (operands[2])
7053                           && INTVAL (operands[2]) == 255));
7054           return "dec{b}\t%0";
7055         }
7056
7057     default:
7058       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7059       if (CONST_INT_P (operands[2])
7060           && INTVAL (operands[2]) < 0)
7061         {
7062           operands[2] = GEN_INT (-INTVAL (operands[2]));
7063           return "sub{b}\t{%2, %0|%0, %2}";
7064         }
7065       return "add{b}\t{%2, %0|%0, %2}";
7066     }
7067 }
7068   [(set (attr "type")
7069      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7070         (const_string "incdec")
7071         (const_string "alu")))
7072    (set_attr "mode" "QI")])
7073
7074 (define_insn "*addqi_ext_1_rex64"
7075   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7076                          (const_int 8)
7077                          (const_int 8))
7078         (plus:SI
7079           (zero_extract:SI
7080             (match_operand 1 "ext_register_operand" "0")
7081             (const_int 8)
7082             (const_int 8))
7083           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7084    (clobber (reg:CC FLAGS_REG))]
7085   "TARGET_64BIT"
7086 {
7087   switch (get_attr_type (insn))
7088     {
7089     case TYPE_INCDEC:
7090       if (operands[2] == const1_rtx)
7091         return "inc{b}\t%h0";
7092       else
7093         {
7094           gcc_assert (operands[2] == constm1_rtx
7095                       || (CONST_INT_P (operands[2])
7096                           && INTVAL (operands[2]) == 255));
7097           return "dec{b}\t%h0";
7098         }
7099
7100     default:
7101       return "add{b}\t{%2, %h0|%h0, %2}";
7102     }
7103 }
7104   [(set (attr "type")
7105      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7106         (const_string "incdec")
7107         (const_string "alu")))
7108    (set_attr "modrm" "1")
7109    (set_attr "mode" "QI")])
7110
7111 (define_insn "addqi_ext_1"
7112   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7113                          (const_int 8)
7114                          (const_int 8))
7115         (plus:SI
7116           (zero_extract:SI
7117             (match_operand 1 "ext_register_operand" "0")
7118             (const_int 8)
7119             (const_int 8))
7120           (match_operand:QI 2 "general_operand" "Qmn")))
7121    (clobber (reg:CC FLAGS_REG))]
7122   "!TARGET_64BIT"
7123 {
7124   switch (get_attr_type (insn))
7125     {
7126     case TYPE_INCDEC:
7127       if (operands[2] == const1_rtx)
7128         return "inc{b}\t%h0";
7129       else
7130         {
7131           gcc_assert (operands[2] == constm1_rtx
7132                       || (CONST_INT_P (operands[2])
7133                           && INTVAL (operands[2]) == 255));
7134           return "dec{b}\t%h0";
7135         }
7136
7137     default:
7138       return "add{b}\t{%2, %h0|%h0, %2}";
7139     }
7140 }
7141   [(set (attr "type")
7142      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7143         (const_string "incdec")
7144         (const_string "alu")))
7145    (set_attr "modrm" "1")
7146    (set_attr "mode" "QI")])
7147
7148 (define_insn "*addqi_ext_2"
7149   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7150                          (const_int 8)
7151                          (const_int 8))
7152         (plus:SI
7153           (zero_extract:SI
7154             (match_operand 1 "ext_register_operand" "%0")
7155             (const_int 8)
7156             (const_int 8))
7157           (zero_extract:SI
7158             (match_operand 2 "ext_register_operand" "Q")
7159             (const_int 8)
7160             (const_int 8))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   ""
7163   "add{b}\t{%h2, %h0|%h0, %h2}"
7164   [(set_attr "type" "alu")
7165    (set_attr "mode" "QI")])
7166
7167 ;; The lea patterns for non-Pmodes needs to be matched by
7168 ;; several insns converted to real lea by splitters.
7169
7170 (define_insn_and_split "*lea_general_1"
7171   [(set (match_operand 0 "register_operand" "=r")
7172         (plus (plus (match_operand 1 "index_register_operand" "l")
7173                     (match_operand 2 "register_operand" "r"))
7174               (match_operand 3 "immediate_operand" "i")))]
7175   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7176     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7177    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7178    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7179    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7180    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7181        || GET_MODE (operands[3]) == VOIDmode)"
7182   "#"
7183   "&& reload_completed"
7184   [(const_int 0)]
7185 {
7186   rtx pat;
7187   operands[0] = gen_lowpart (SImode, operands[0]);
7188   operands[1] = gen_lowpart (Pmode, operands[1]);
7189   operands[2] = gen_lowpart (Pmode, operands[2]);
7190   operands[3] = gen_lowpart (Pmode, operands[3]);
7191   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7192                       operands[3]);
7193   if (Pmode != SImode)
7194     pat = gen_rtx_SUBREG (SImode, pat, 0);
7195   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7196   DONE;
7197 }
7198   [(set_attr "type" "lea")
7199    (set_attr "mode" "SI")])
7200
7201 (define_insn_and_split "*lea_general_1_zext"
7202   [(set (match_operand:DI 0 "register_operand" "=r")
7203         (zero_extend:DI
7204           (plus:SI (plus:SI
7205                      (match_operand:SI 1 "index_register_operand" "l")
7206                      (match_operand:SI 2 "register_operand" "r"))
7207                    (match_operand:SI 3 "immediate_operand" "i"))))]
7208   "TARGET_64BIT"
7209   "#"
7210   "&& reload_completed"
7211   [(set (match_dup 0)
7212         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7213                                                      (match_dup 2))
7214                                             (match_dup 3)) 0)))]
7215 {
7216   operands[1] = gen_lowpart (Pmode, operands[1]);
7217   operands[2] = gen_lowpart (Pmode, operands[2]);
7218   operands[3] = gen_lowpart (Pmode, operands[3]);
7219 }
7220   [(set_attr "type" "lea")
7221    (set_attr "mode" "SI")])
7222
7223 (define_insn_and_split "*lea_general_2"
7224   [(set (match_operand 0 "register_operand" "=r")
7225         (plus (mult (match_operand 1 "index_register_operand" "l")
7226                     (match_operand 2 "const248_operand" "i"))
7227               (match_operand 3 "nonmemory_operand" "ri")))]
7228   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7229     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7230    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7231    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7232    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7233        || GET_MODE (operands[3]) == VOIDmode)"
7234   "#"
7235   "&& reload_completed"
7236   [(const_int 0)]
7237 {
7238   rtx pat;
7239   operands[0] = gen_lowpart (SImode, operands[0]);
7240   operands[1] = gen_lowpart (Pmode, operands[1]);
7241   operands[3] = gen_lowpart (Pmode, operands[3]);
7242   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7243                       operands[3]);
7244   if (Pmode != SImode)
7245     pat = gen_rtx_SUBREG (SImode, pat, 0);
7246   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7247   DONE;
7248 }
7249   [(set_attr "type" "lea")
7250    (set_attr "mode" "SI")])
7251
7252 (define_insn_and_split "*lea_general_2_zext"
7253   [(set (match_operand:DI 0 "register_operand" "=r")
7254         (zero_extend:DI
7255           (plus:SI (mult:SI
7256                      (match_operand:SI 1 "index_register_operand" "l")
7257                      (match_operand:SI 2 "const248_operand" "n"))
7258                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7259   "TARGET_64BIT"
7260   "#"
7261   "&& reload_completed"
7262   [(set (match_dup 0)
7263         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7264                                                      (match_dup 2))
7265                                             (match_dup 3)) 0)))]
7266 {
7267   operands[1] = gen_lowpart (Pmode, operands[1]);
7268   operands[3] = gen_lowpart (Pmode, operands[3]);
7269 }
7270   [(set_attr "type" "lea")
7271    (set_attr "mode" "SI")])
7272
7273 (define_insn_and_split "*lea_general_3"
7274   [(set (match_operand 0 "register_operand" "=r")
7275         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7276                           (match_operand 2 "const248_operand" "i"))
7277                     (match_operand 3 "register_operand" "r"))
7278               (match_operand 4 "immediate_operand" "i")))]
7279   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7280     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7281    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7282    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7283    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7284   "#"
7285   "&& reload_completed"
7286   [(const_int 0)]
7287 {
7288   rtx pat;
7289   operands[0] = gen_lowpart (SImode, operands[0]);
7290   operands[1] = gen_lowpart (Pmode, operands[1]);
7291   operands[3] = gen_lowpart (Pmode, operands[3]);
7292   operands[4] = gen_lowpart (Pmode, operands[4]);
7293   pat = gen_rtx_PLUS (Pmode,
7294                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7295                                                          operands[2]),
7296                                     operands[3]),
7297                       operands[4]);
7298   if (Pmode != SImode)
7299     pat = gen_rtx_SUBREG (SImode, pat, 0);
7300   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7301   DONE;
7302 }
7303   [(set_attr "type" "lea")
7304    (set_attr "mode" "SI")])
7305
7306 (define_insn_and_split "*lea_general_3_zext"
7307   [(set (match_operand:DI 0 "register_operand" "=r")
7308         (zero_extend:DI
7309           (plus:SI (plus:SI
7310                      (mult:SI
7311                        (match_operand:SI 1 "index_register_operand" "l")
7312                        (match_operand:SI 2 "const248_operand" "n"))
7313                      (match_operand:SI 3 "register_operand" "r"))
7314                    (match_operand:SI 4 "immediate_operand" "i"))))]
7315   "TARGET_64BIT"
7316   "#"
7317   "&& reload_completed"
7318   [(set (match_dup 0)
7319         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7320                                                               (match_dup 2))
7321                                                      (match_dup 3))
7322                                             (match_dup 4)) 0)))]
7323 {
7324   operands[1] = gen_lowpart (Pmode, operands[1]);
7325   operands[3] = gen_lowpart (Pmode, operands[3]);
7326   operands[4] = gen_lowpart (Pmode, operands[4]);
7327 }
7328   [(set_attr "type" "lea")
7329    (set_attr "mode" "SI")])
7330
7331 ;; Convert lea to the lea pattern to avoid flags dependency.
7332 (define_split
7333   [(set (match_operand:DI 0 "register_operand" "")
7334         (plus:DI (match_operand:DI 1 "register_operand" "")
7335                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_64BIT && reload_completed 
7338    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7339   [(set (match_dup 0)
7340         (plus:DI (match_dup 1)
7341                  (match_dup 2)))]
7342   "")
7343
7344 ;; Convert lea to the lea pattern to avoid flags dependency.
7345 (define_split
7346   [(set (match_operand 0 "register_operand" "")
7347         (plus (match_operand 1 "register_operand" "")
7348               (match_operand 2 "nonmemory_operand" "")))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7351   [(const_int 0)]
7352 {
7353   rtx pat;
7354   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7355      may confuse gen_lowpart.  */
7356   if (GET_MODE (operands[0]) != Pmode)
7357     {
7358       operands[1] = gen_lowpart (Pmode, operands[1]);
7359       operands[2] = gen_lowpart (Pmode, operands[2]);
7360     }
7361   operands[0] = gen_lowpart (SImode, operands[0]);
7362   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7363   if (Pmode != SImode)
7364     pat = gen_rtx_SUBREG (SImode, pat, 0);
7365   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7366   DONE;
7367 })
7368
7369 ;; Convert lea to the lea pattern to avoid flags dependency.
7370 (define_split
7371   [(set (match_operand:DI 0 "register_operand" "")
7372         (zero_extend:DI
7373           (plus:SI (match_operand:SI 1 "register_operand" "")
7374                    (match_operand:SI 2 "nonmemory_operand" ""))))
7375    (clobber (reg:CC FLAGS_REG))]
7376   "TARGET_64BIT && reload_completed
7377    && true_regnum (operands[0]) != true_regnum (operands[1])"
7378   [(set (match_dup 0)
7379         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7380 {
7381   operands[1] = gen_lowpart (Pmode, operands[1]);
7382   operands[2] = gen_lowpart (Pmode, operands[2]);
7383 })
7384 \f
7385 ;; Subtract instructions
7386
7387 (define_expand "sub<mode>3"
7388   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7389         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7390                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7391   ""
7392   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7393
7394 (define_insn_and_split "*sub<dwi>3_doubleword"
7395   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7396         (minus:<DWI>
7397           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7398           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7399    (clobber (reg:CC FLAGS_REG))]
7400   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7401   "#"
7402   "reload_completed"
7403   [(parallel [(set (reg:CC FLAGS_REG)
7404                    (compare:CC (match_dup 1) (match_dup 2)))
7405               (set (match_dup 0)
7406                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7407    (parallel [(set (match_dup 3)
7408                    (minus:DWIH
7409                      (match_dup 4)
7410                      (plus:DWIH
7411                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7412                        (match_dup 5))))
7413               (clobber (reg:CC FLAGS_REG))])]
7414   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7415
7416 (define_insn "*sub<mode>_1"
7417   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7418         (minus:SWI
7419           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7420           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7423   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7424   [(set_attr "type" "alu")
7425    (set_attr "mode" "<MODE>")])
7426
7427 (define_insn "*subsi_1_zext"
7428   [(set (match_operand:DI 0 "register_operand" "=r")
7429         (zero_extend:DI
7430           (minus:SI (match_operand:SI 1 "register_operand" "0")
7431                     (match_operand:SI 2 "general_operand" "g"))))
7432    (clobber (reg:CC FLAGS_REG))]
7433   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7434   "sub{l}\t{%2, %k0|%k0, %2}"
7435   [(set_attr "type" "alu")
7436    (set_attr "mode" "SI")])
7437
7438 (define_insn "*subqi_1_slp"
7439   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7440         (minus:QI (match_dup 0)
7441                   (match_operand:QI 1 "general_operand" "qn,qm")))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7445   "sub{b}\t{%1, %0|%0, %1}"
7446   [(set_attr "type" "alu1")
7447    (set_attr "mode" "QI")])
7448
7449 (define_insn "*sub<mode>_2"
7450   [(set (reg FLAGS_REG)
7451         (compare
7452           (minus:SWI
7453             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7454             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7455           (const_int 0)))
7456    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7457         (minus:SWI (match_dup 1) (match_dup 2)))]
7458   "ix86_match_ccmode (insn, CCGOCmode)
7459    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7460   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7461   [(set_attr "type" "alu")
7462    (set_attr "mode" "<MODE>")])
7463
7464 (define_insn "*subsi_2_zext"
7465   [(set (reg FLAGS_REG)
7466         (compare
7467           (minus:SI (match_operand:SI 1 "register_operand" "0")
7468                     (match_operand:SI 2 "general_operand" "g"))
7469           (const_int 0)))
7470    (set (match_operand:DI 0 "register_operand" "=r")
7471         (zero_extend:DI
7472           (minus:SI (match_dup 1)
7473                     (match_dup 2))))]
7474   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7475    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7476   "sub{l}\t{%2, %k0|%k0, %2}"
7477   [(set_attr "type" "alu")
7478    (set_attr "mode" "SI")])
7479
7480 (define_insn "*sub<mode>_3"
7481   [(set (reg FLAGS_REG)
7482         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7483                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7484    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7485         (minus:SWI (match_dup 1) (match_dup 2)))]
7486   "ix86_match_ccmode (insn, CCmode)
7487    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7488   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7489   [(set_attr "type" "alu")
7490    (set_attr "mode" "<MODE>")])
7491
7492 (define_insn "*subsi_3_zext"
7493   [(set (reg FLAGS_REG)
7494         (compare (match_operand:SI 1 "register_operand" "0")
7495                  (match_operand:SI 2 "general_operand" "g")))
7496    (set (match_operand:DI 0 "register_operand" "=r")
7497         (zero_extend:DI
7498           (minus:SI (match_dup 1)
7499                     (match_dup 2))))]
7500   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7501    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7502   "sub{l}\t{%2, %1|%1, %2}"
7503   [(set_attr "type" "alu")
7504    (set_attr "mode" "SI")])
7505 \f
7506 ;; Add with carry and subtract with borrow
7507
7508 (define_expand "<plusminus_insn><mode>3_carry"
7509   [(parallel
7510     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7511           (plusminus:SWI
7512             (match_operand:SWI 1 "nonimmediate_operand" "")
7513             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7514                        [(match_operand 3 "flags_reg_operand" "")
7515                         (const_int 0)])
7516                       (match_operand:SWI 2 "<general_operand>" ""))))
7517      (clobber (reg:CC FLAGS_REG))])]
7518   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7519   "")
7520
7521 (define_insn "*<plusminus_insn><mode>3_carry"
7522   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7523         (plusminus:SWI
7524           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7525           (plus:SWI
7526             (match_operator 3 "ix86_carry_flag_operator"
7527              [(reg FLAGS_REG) (const_int 0)])
7528             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7529    (clobber (reg:CC FLAGS_REG))]
7530   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7531   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7532   [(set_attr "type" "alu")
7533    (set_attr "use_carry" "1")
7534    (set_attr "pent_pair" "pu")
7535    (set_attr "mode" "<MODE>")])
7536
7537 (define_insn "*addsi3_carry_zext"
7538   [(set (match_operand:DI 0 "register_operand" "=r")
7539         (zero_extend:DI
7540           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7541                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7542                              [(reg FLAGS_REG) (const_int 0)])
7543                             (match_operand:SI 2 "general_operand" "g")))))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7546   "adc{l}\t{%2, %k0|%k0, %2}"
7547   [(set_attr "type" "alu")
7548    (set_attr "use_carry" "1")
7549    (set_attr "pent_pair" "pu")
7550    (set_attr "mode" "SI")])
7551
7552 (define_insn "*subsi3_carry_zext"
7553   [(set (match_operand:DI 0 "register_operand" "=r")
7554         (zero_extend:DI
7555           (minus:SI (match_operand:SI 1 "register_operand" "0")
7556                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7557                               [(reg FLAGS_REG) (const_int 0)])
7558                              (match_operand:SI 2 "general_operand" "g")))))
7559    (clobber (reg:CC FLAGS_REG))]
7560   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7561   "sbb{l}\t{%2, %k0|%k0, %2}"
7562   [(set_attr "type" "alu")
7563    (set_attr "pent_pair" "pu")
7564    (set_attr "mode" "SI")])
7565 \f
7566 ;; Overflow setting add and subtract instructions
7567
7568 (define_insn "*add<mode>3_cconly_overflow"
7569   [(set (reg:CCC FLAGS_REG)
7570         (compare:CCC
7571           (plus:SWI
7572             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7573             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7574           (match_dup 1)))
7575    (clobber (match_scratch:SWI 0 "=<r>"))]
7576   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7577   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7578   [(set_attr "type" "alu")
7579    (set_attr "mode" "<MODE>")])
7580
7581 (define_insn "*sub<mode>3_cconly_overflow"
7582   [(set (reg:CCC FLAGS_REG)
7583         (compare:CCC
7584           (minus:SWI
7585             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7586             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7587           (match_dup 0)))]
7588   ""
7589   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7590   [(set_attr "type" "icmp")
7591    (set_attr "mode" "<MODE>")])
7592
7593 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7594   [(set (reg:CCC FLAGS_REG)
7595         (compare:CCC
7596             (plusminus:SWI
7597                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7598                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7599             (match_dup 1)))
7600    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7601         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7602   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7603   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7604   [(set_attr "type" "alu")
7605    (set_attr "mode" "<MODE>")])
7606
7607 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7608   [(set (reg:CCC FLAGS_REG)
7609         (compare:CCC
7610           (plusminus:SI
7611             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7612             (match_operand:SI 2 "general_operand" "g"))
7613           (match_dup 1)))
7614    (set (match_operand:DI 0 "register_operand" "=r")
7615         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7616   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7617   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7618   [(set_attr "type" "alu")
7619    (set_attr "mode" "SI")])
7620
7621 ;; The patterns that match these are at the end of this file.
7622
7623 (define_expand "<plusminus_insn>xf3"
7624   [(set (match_operand:XF 0 "register_operand" "")
7625         (plusminus:XF
7626           (match_operand:XF 1 "register_operand" "")
7627           (match_operand:XF 2 "register_operand" "")))]
7628   "TARGET_80387"
7629   "")
7630
7631 (define_expand "<plusminus_insn><mode>3"
7632   [(set (match_operand:MODEF 0 "register_operand" "")
7633         (plusminus:MODEF
7634           (match_operand:MODEF 1 "register_operand" "")
7635           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7636   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7637     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7638   "")
7639 \f
7640 ;; Multiply instructions
7641
7642 (define_expand "mul<mode>3"
7643   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7644                    (mult:SWIM248
7645                      (match_operand:SWIM248 1 "register_operand" "")
7646                      (match_operand:SWIM248 2 "<general_operand>" "")))
7647               (clobber (reg:CC FLAGS_REG))])]
7648   ""
7649   "")
7650
7651 (define_expand "mulqi3"
7652   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7653                    (mult:QI
7654                      (match_operand:QI 1 "register_operand" "")
7655                      (match_operand:QI 2 "nonimmediate_operand" "")))
7656               (clobber (reg:CC FLAGS_REG))])]
7657   "TARGET_QIMODE_MATH"
7658   "")
7659
7660 ;; On AMDFAM10
7661 ;; IMUL reg32/64, reg32/64, imm8        Direct
7662 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7663 ;; IMUL reg32/64, reg32/64, imm32       Direct
7664 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7665 ;; IMUL reg32/64, reg32/64              Direct
7666 ;; IMUL reg32/64, mem32/64              Direct
7667
7668 (define_insn "*mul<mode>3_1"
7669   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7670         (mult:SWI48
7671           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7672           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7675   "@
7676    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7677    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7678    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7679   [(set_attr "type" "imul")
7680    (set_attr "prefix_0f" "0,0,1")
7681    (set (attr "athlon_decode")
7682         (cond [(eq_attr "cpu" "athlon")
7683                   (const_string "vector")
7684                (eq_attr "alternative" "1")
7685                   (const_string "vector")
7686                (and (eq_attr "alternative" "2")
7687                     (match_operand 1 "memory_operand" ""))
7688                   (const_string "vector")]
7689               (const_string "direct")))
7690    (set (attr "amdfam10_decode")
7691         (cond [(and (eq_attr "alternative" "0,1")
7692                     (match_operand 1 "memory_operand" ""))
7693                   (const_string "vector")]
7694               (const_string "direct")))
7695    (set_attr "mode" "<MODE>")])
7696
7697 (define_insn "*mulsi3_1_zext"
7698   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7699         (zero_extend:DI
7700           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7701                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7702    (clobber (reg:CC FLAGS_REG))]
7703   "TARGET_64BIT
7704    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7705   "@
7706    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7707    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7708    imul{l}\t{%2, %k0|%k0, %2}"
7709   [(set_attr "type" "imul")
7710    (set_attr "prefix_0f" "0,0,1")
7711    (set (attr "athlon_decode")
7712         (cond [(eq_attr "cpu" "athlon")
7713                   (const_string "vector")
7714                (eq_attr "alternative" "1")
7715                   (const_string "vector")
7716                (and (eq_attr "alternative" "2")
7717                     (match_operand 1 "memory_operand" ""))
7718                   (const_string "vector")]
7719               (const_string "direct")))
7720    (set (attr "amdfam10_decode")
7721         (cond [(and (eq_attr "alternative" "0,1")
7722                     (match_operand 1 "memory_operand" ""))
7723                   (const_string "vector")]
7724               (const_string "direct")))
7725    (set_attr "mode" "SI")])
7726
7727 ;; On AMDFAM10
7728 ;; IMUL reg16, reg16, imm8      VectorPath
7729 ;; IMUL reg16, mem16, imm8      VectorPath
7730 ;; IMUL reg16, reg16, imm16     VectorPath
7731 ;; IMUL reg16, mem16, imm16     VectorPath
7732 ;; IMUL reg16, reg16            Direct
7733 ;; IMUL reg16, mem16            Direct
7734
7735 (define_insn "*mulhi3_1"
7736   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7737         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7738                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "TARGET_HIMODE_MATH
7741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742   "@
7743    imul{w}\t{%2, %1, %0|%0, %1, %2}
7744    imul{w}\t{%2, %1, %0|%0, %1, %2}
7745    imul{w}\t{%2, %0|%0, %2}"
7746   [(set_attr "type" "imul")
7747    (set_attr "prefix_0f" "0,0,1")
7748    (set (attr "athlon_decode")
7749         (cond [(eq_attr "cpu" "athlon")
7750                   (const_string "vector")
7751                (eq_attr "alternative" "1,2")
7752                   (const_string "vector")]
7753               (const_string "direct")))
7754    (set (attr "amdfam10_decode")
7755         (cond [(eq_attr "alternative" "0,1")
7756                   (const_string "vector")]
7757               (const_string "direct")))
7758    (set_attr "mode" "HI")])
7759
7760 ;;On AMDFAM10
7761 ;; MUL reg8     Direct
7762 ;; MUL mem8     Direct
7763
7764 (define_insn "*mulqi3_1"
7765   [(set (match_operand:QI 0 "register_operand" "=a")
7766         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7767                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7768    (clobber (reg:CC FLAGS_REG))]
7769   "TARGET_QIMODE_MATH
7770    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771   "mul{b}\t%2"
7772   [(set_attr "type" "imul")
7773    (set_attr "length_immediate" "0")
7774    (set (attr "athlon_decode")
7775      (if_then_else (eq_attr "cpu" "athlon")
7776         (const_string "vector")
7777         (const_string "direct")))
7778    (set_attr "amdfam10_decode" "direct")
7779    (set_attr "mode" "QI")])
7780
7781 (define_expand "<u>mul<mode><dwi>3"
7782   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7783                    (mult:<DWI>
7784                      (any_extend:<DWI>
7785                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7786                      (any_extend:<DWI>
7787                        (match_operand:DWIH 2 "register_operand" ""))))
7788               (clobber (reg:CC FLAGS_REG))])]
7789   ""
7790   "")
7791
7792 (define_expand "<u>mulqihi3"
7793   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7794                    (mult:HI
7795                      (any_extend:HI
7796                        (match_operand:QI 1 "nonimmediate_operand" ""))
7797                      (any_extend:HI
7798                        (match_operand:QI 2 "register_operand" ""))))
7799               (clobber (reg:CC FLAGS_REG))])]
7800   "TARGET_QIMODE_MATH"
7801   "")
7802
7803 (define_insn "*<u>mul<mode><dwi>3_1"
7804   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7805         (mult:<DWI>
7806           (any_extend:<DWI>
7807             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7808           (any_extend:<DWI>
7809             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7812   "<sgnprefix>mul{<imodesuffix>}\t%2"
7813   [(set_attr "type" "imul")
7814    (set_attr "length_immediate" "0")
7815    (set (attr "athlon_decode")
7816      (if_then_else (eq_attr "cpu" "athlon")
7817         (const_string "vector")
7818         (const_string "double")))
7819    (set_attr "amdfam10_decode" "double")
7820    (set_attr "mode" "<MODE>")])
7821
7822 (define_insn "*<u>mulqihi3_1"
7823   [(set (match_operand:HI 0 "register_operand" "=a")
7824         (mult:HI
7825           (any_extend:HI
7826             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7827           (any_extend:HI
7828             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7829    (clobber (reg:CC FLAGS_REG))]
7830   "TARGET_QIMODE_MATH
7831    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7832   "<sgnprefix>mul{b}\t%2"
7833   [(set_attr "type" "imul")
7834    (set_attr "length_immediate" "0")
7835    (set (attr "athlon_decode")
7836      (if_then_else (eq_attr "cpu" "athlon")
7837         (const_string "vector")
7838         (const_string "direct")))
7839    (set_attr "amdfam10_decode" "direct")
7840    (set_attr "mode" "QI")])
7841
7842 (define_expand "<s>mul<mode>3_highpart"
7843   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7844                    (truncate:SWI48
7845                      (lshiftrt:<DWI>
7846                        (mult:<DWI>
7847                          (any_extend:<DWI>
7848                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7849                          (any_extend:<DWI>
7850                            (match_operand:SWI48 2 "register_operand" "")))
7851                        (match_dup 4))))
7852               (clobber (match_scratch:SWI48 3 ""))
7853               (clobber (reg:CC FLAGS_REG))])]
7854   ""
7855   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7856
7857 (define_insn "*<s>muldi3_highpart_1"
7858   [(set (match_operand:DI 0 "register_operand" "=d")
7859         (truncate:DI
7860           (lshiftrt:TI
7861             (mult:TI
7862               (any_extend:TI
7863                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7864               (any_extend:TI
7865                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7866             (const_int 64))))
7867    (clobber (match_scratch:DI 3 "=1"))
7868    (clobber (reg:CC FLAGS_REG))]
7869   "TARGET_64BIT
7870    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7871   "<sgnprefix>mul{q}\t%2"
7872   [(set_attr "type" "imul")
7873    (set_attr "length_immediate" "0")
7874    (set (attr "athlon_decode")
7875      (if_then_else (eq_attr "cpu" "athlon")
7876         (const_string "vector")
7877         (const_string "double")))
7878    (set_attr "amdfam10_decode" "double")
7879    (set_attr "mode" "DI")])
7880
7881 (define_insn "*<s>mulsi3_highpart_1"
7882   [(set (match_operand:SI 0 "register_operand" "=d")
7883         (truncate:SI
7884           (lshiftrt:DI
7885             (mult:DI
7886               (any_extend:DI
7887                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7888               (any_extend:DI
7889                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7890             (const_int 32))))
7891    (clobber (match_scratch:SI 3 "=1"))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7894   "<sgnprefix>mul{l}\t%2"
7895   [(set_attr "type" "imul")
7896    (set_attr "length_immediate" "0")
7897    (set (attr "athlon_decode")
7898      (if_then_else (eq_attr "cpu" "athlon")
7899         (const_string "vector")
7900         (const_string "double")))
7901    (set_attr "amdfam10_decode" "double")
7902    (set_attr "mode" "SI")])
7903
7904 (define_insn "*<s>mulsi3_highpart_zext"
7905   [(set (match_operand:DI 0 "register_operand" "=d")
7906         (zero_extend:DI (truncate:SI
7907           (lshiftrt:DI
7908             (mult:DI (any_extend:DI
7909                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7910                      (any_extend:DI
7911                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7912             (const_int 32)))))
7913    (clobber (match_scratch:SI 3 "=1"))
7914    (clobber (reg:CC FLAGS_REG))]
7915   "TARGET_64BIT
7916    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7917   "<sgnprefix>mul{l}\t%2"
7918   [(set_attr "type" "imul")
7919    (set_attr "length_immediate" "0")
7920    (set (attr "athlon_decode")
7921      (if_then_else (eq_attr "cpu" "athlon")
7922         (const_string "vector")
7923         (const_string "double")))
7924    (set_attr "amdfam10_decode" "double")
7925    (set_attr "mode" "SI")])
7926
7927 ;; The patterns that match these are at the end of this file.
7928
7929 (define_expand "mulxf3"
7930   [(set (match_operand:XF 0 "register_operand" "")
7931         (mult:XF (match_operand:XF 1 "register_operand" "")
7932                  (match_operand:XF 2 "register_operand" "")))]
7933   "TARGET_80387"
7934   "")
7935
7936 (define_expand "mul<mode>3"
7937   [(set (match_operand:MODEF 0 "register_operand" "")
7938         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7939                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7940   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7941     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7942   "")
7943 \f
7944 ;; Divide instructions
7945
7946 (define_insn "<u>divqi3"
7947   [(set (match_operand:QI 0 "register_operand" "=a")
7948         (any_div:QI
7949           (match_operand:HI 1 "register_operand" "0")
7950           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7951    (clobber (reg:CC FLAGS_REG))]
7952   "TARGET_QIMODE_MATH"
7953   "<sgnprefix>div{b}\t%2"
7954   [(set_attr "type" "idiv")
7955    (set_attr "mode" "QI")])
7956
7957 ;; The patterns that match these are at the end of this file.
7958
7959 (define_expand "divxf3"
7960   [(set (match_operand:XF 0 "register_operand" "")
7961         (div:XF (match_operand:XF 1 "register_operand" "")
7962                 (match_operand:XF 2 "register_operand" "")))]
7963   "TARGET_80387"
7964   "")
7965
7966 (define_expand "divdf3"
7967   [(set (match_operand:DF 0 "register_operand" "")
7968         (div:DF (match_operand:DF 1 "register_operand" "")
7969                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7970    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7971     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7972    "")
7973
7974 (define_expand "divsf3"
7975   [(set (match_operand:SF 0 "register_operand" "")
7976         (div:SF (match_operand:SF 1 "register_operand" "")
7977                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7978   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7979     || TARGET_SSE_MATH"
7980 {
7981   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7982       && flag_finite_math_only && !flag_trapping_math
7983       && flag_unsafe_math_optimizations)
7984     {
7985       ix86_emit_swdivsf (operands[0], operands[1],
7986                          operands[2], SFmode);
7987       DONE;
7988     }
7989 })
7990 \f
7991 ;; Divmod instructions.
7992
7993 (define_expand "divmod<mode>4"
7994   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7995                    (div:SWIM248
7996                      (match_operand:SWIM248 1 "register_operand" "")
7997                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7998               (set (match_operand:SWIM248 3 "register_operand" "")
7999                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
8000               (clobber (reg:CC FLAGS_REG))])]
8001   ""
8002   "")
8003
8004 (define_insn_and_split "*divmod<mode>4"
8005   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8006         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8007                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8008    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8009         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8010    (clobber (reg:CC FLAGS_REG))]
8011   ""
8012   "#"
8013   "&& reload_completed"
8014   [(parallel [(set (match_dup 1)
8015                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8016               (clobber (reg:CC FLAGS_REG))])
8017    (parallel [(set (match_dup 0)
8018                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8019               (set (match_dup 1)
8020                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8021               (use (match_dup 1))
8022               (clobber (reg:CC FLAGS_REG))])]
8023 {
8024   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8025
8026   if (<MODE>mode != HImode
8027       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8028     operands[4] = operands[2];
8029   else
8030     {
8031       /* Avoid use of cltd in favor of a mov+shift.  */
8032       emit_move_insn (operands[1], operands[2]);
8033       operands[4] = operands[1];
8034     }
8035 }
8036   [(set_attr "type" "multi")
8037    (set_attr "mode" "<MODE>")])
8038
8039 (define_insn "*divmod<mode>4_noext"
8040   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8041         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8042                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8043    (set (match_operand:SWIM248 1 "register_operand" "=d")
8044         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8045    (use (match_operand:SWIM248 4 "register_operand" "1"))
8046    (clobber (reg:CC FLAGS_REG))]
8047   ""
8048   "idiv{<imodesuffix>}\t%3"
8049   [(set_attr "type" "idiv")
8050    (set_attr "mode" "<MODE>")])
8051
8052 (define_expand "udivmod<mode>4"
8053   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8054                    (udiv:SWIM248
8055                      (match_operand:SWIM248 1 "register_operand" "")
8056                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8057               (set (match_operand:SWIM248 3 "register_operand" "")
8058                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8059               (clobber (reg:CC FLAGS_REG))])]
8060   ""
8061   "")
8062
8063 (define_insn_and_split "*udivmod<mode>4"
8064   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8065         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8066                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8067    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8068         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8069    (clobber (reg:CC FLAGS_REG))]
8070   ""
8071   "#"
8072   "&& reload_completed"
8073   [(set (match_dup 1) (const_int 0))
8074    (parallel [(set (match_dup 0)
8075                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8076               (set (match_dup 1)
8077                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8078               (use (match_dup 1))
8079               (clobber (reg:CC FLAGS_REG))])]
8080   ""
8081   [(set_attr "type" "multi")
8082    (set_attr "mode" "<MODE>")])
8083
8084 (define_insn "*udivmod<mode>4_noext"
8085   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8086         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8087                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8088    (set (match_operand:SWIM248 1 "register_operand" "=d")
8089         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8090    (use (match_operand:SWIM248 4 "register_operand" "1"))
8091    (clobber (reg:CC FLAGS_REG))]
8092   ""
8093   "div{<imodesuffix>}\t%3"
8094   [(set_attr "type" "idiv")
8095    (set_attr "mode" "<MODE>")])
8096
8097 ;; We cannot use div/idiv for double division, because it causes
8098 ;; "division by zero" on the overflow and that's not what we expect
8099 ;; from truncate.  Because true (non truncating) double division is
8100 ;; never generated, we can't create this insn anyway.
8101 ;
8102 ;(define_insn ""
8103 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8104 ;       (truncate:SI
8105 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8106 ;                  (zero_extend:DI
8107 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8108 ;   (set (match_operand:SI 3 "register_operand" "=d")
8109 ;       (truncate:SI
8110 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8111 ;   (clobber (reg:CC FLAGS_REG))]
8112 ;  ""
8113 ;  "div{l}\t{%2, %0|%0, %2}"
8114 ;  [(set_attr "type" "idiv")])
8115 \f
8116 ;;- Logical AND instructions
8117
8118 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8119 ;; Note that this excludes ah.
8120
8121 (define_expand "testsi_ccno_1"
8122   [(set (reg:CCNO FLAGS_REG)
8123         (compare:CCNO
8124           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8125                   (match_operand:SI 1 "nonmemory_operand" ""))
8126           (const_int 0)))]
8127   ""
8128   "")
8129
8130 (define_expand "testqi_ccz_1"
8131   [(set (reg:CCZ FLAGS_REG)
8132         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8133                              (match_operand:QI 1 "nonmemory_operand" ""))
8134                  (const_int 0)))]
8135   ""
8136   "")
8137
8138 (define_insn "*testdi_1"
8139   [(set (reg FLAGS_REG)
8140         (compare
8141          (and:DI
8142           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8143           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8144          (const_int 0)))]
8145   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8147   "@
8148    test{l}\t{%k1, %k0|%k0, %k1}
8149    test{l}\t{%k1, %k0|%k0, %k1}
8150    test{q}\t{%1, %0|%0, %1}
8151    test{q}\t{%1, %0|%0, %1}
8152    test{q}\t{%1, %0|%0, %1}"
8153   [(set_attr "type" "test")
8154    (set_attr "modrm" "0,1,0,1,1")
8155    (set_attr "mode" "SI,SI,DI,DI,DI")])
8156
8157 (define_insn "*testqi_1_maybe_si"
8158   [(set (reg FLAGS_REG)
8159         (compare
8160           (and:QI
8161             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8162             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8163           (const_int 0)))]
8164    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8165     && ix86_match_ccmode (insn,
8166                          CONST_INT_P (operands[1])
8167                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8168 {
8169   if (which_alternative == 3)
8170     {
8171       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8172         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8173       return "test{l}\t{%1, %k0|%k0, %1}";
8174     }
8175   return "test{b}\t{%1, %0|%0, %1}";
8176 }
8177   [(set_attr "type" "test")
8178    (set_attr "modrm" "0,1,1,1")
8179    (set_attr "mode" "QI,QI,QI,SI")
8180    (set_attr "pent_pair" "uv,np,uv,np")])
8181
8182 (define_insn "*test<mode>_1"
8183   [(set (reg FLAGS_REG)
8184         (compare
8185          (and:SWI124
8186           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8187           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8188          (const_int 0)))]
8189   "ix86_match_ccmode (insn, CCNOmode)
8190    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8191   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8192   [(set_attr "type" "test")
8193    (set_attr "modrm" "0,1,1")
8194    (set_attr "mode" "<MODE>")
8195    (set_attr "pent_pair" "uv,np,uv")])
8196
8197 (define_expand "testqi_ext_ccno_0"
8198   [(set (reg:CCNO FLAGS_REG)
8199         (compare:CCNO
8200           (and:SI
8201             (zero_extract:SI
8202               (match_operand 0 "ext_register_operand" "")
8203               (const_int 8)
8204               (const_int 8))
8205             (match_operand 1 "const_int_operand" ""))
8206           (const_int 0)))]
8207   ""
8208   "")
8209
8210 (define_insn "*testqi_ext_0"
8211   [(set (reg FLAGS_REG)
8212         (compare
8213           (and:SI
8214             (zero_extract:SI
8215               (match_operand 0 "ext_register_operand" "Q")
8216               (const_int 8)
8217               (const_int 8))
8218             (match_operand 1 "const_int_operand" "n"))
8219           (const_int 0)))]
8220   "ix86_match_ccmode (insn, CCNOmode)"
8221   "test{b}\t{%1, %h0|%h0, %1}"
8222   [(set_attr "type" "test")
8223    (set_attr "mode" "QI")
8224    (set_attr "length_immediate" "1")
8225    (set_attr "modrm" "1")
8226    (set_attr "pent_pair" "np")])
8227
8228 (define_insn "*testqi_ext_1_rex64"
8229   [(set (reg FLAGS_REG)
8230         (compare
8231           (and:SI
8232             (zero_extract:SI
8233               (match_operand 0 "ext_register_operand" "Q")
8234               (const_int 8)
8235               (const_int 8))
8236             (zero_extend:SI
8237               (match_operand:QI 1 "register_operand" "Q")))
8238           (const_int 0)))]
8239   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8240   "test{b}\t{%1, %h0|%h0, %1}"
8241   [(set_attr "type" "test")
8242    (set_attr "mode" "QI")])
8243
8244 (define_insn "*testqi_ext_1"
8245   [(set (reg FLAGS_REG)
8246         (compare
8247           (and:SI
8248             (zero_extract:SI
8249               (match_operand 0 "ext_register_operand" "Q")
8250               (const_int 8)
8251               (const_int 8))
8252             (zero_extend:SI
8253               (match_operand:QI 1 "general_operand" "Qm")))
8254           (const_int 0)))]
8255   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8256   "test{b}\t{%1, %h0|%h0, %1}"
8257   [(set_attr "type" "test")
8258    (set_attr "mode" "QI")])
8259
8260 (define_insn "*testqi_ext_2"
8261   [(set (reg FLAGS_REG)
8262         (compare
8263           (and:SI
8264             (zero_extract:SI
8265               (match_operand 0 "ext_register_operand" "Q")
8266               (const_int 8)
8267               (const_int 8))
8268             (zero_extract:SI
8269               (match_operand 1 "ext_register_operand" "Q")
8270               (const_int 8)
8271               (const_int 8)))
8272           (const_int 0)))]
8273   "ix86_match_ccmode (insn, CCNOmode)"
8274   "test{b}\t{%h1, %h0|%h0, %h1}"
8275   [(set_attr "type" "test")
8276    (set_attr "mode" "QI")])
8277
8278 (define_insn "*testqi_ext_3_rex64"
8279   [(set (reg FLAGS_REG)
8280         (compare (zero_extract:DI
8281                    (match_operand 0 "nonimmediate_operand" "rm")
8282                    (match_operand:DI 1 "const_int_operand" "")
8283                    (match_operand:DI 2 "const_int_operand" ""))
8284                  (const_int 0)))]
8285   "TARGET_64BIT
8286    && ix86_match_ccmode (insn, CCNOmode)
8287    && INTVAL (operands[1]) > 0
8288    && INTVAL (operands[2]) >= 0
8289    /* Ensure that resulting mask is zero or sign extended operand.  */
8290    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8291        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8292            && INTVAL (operands[1]) > 32))
8293    && (GET_MODE (operands[0]) == SImode
8294        || GET_MODE (operands[0]) == DImode
8295        || GET_MODE (operands[0]) == HImode
8296        || GET_MODE (operands[0]) == QImode)"
8297   "#")
8298
8299 ;; Combine likes to form bit extractions for some tests.  Humor it.
8300 (define_insn "*testqi_ext_3"
8301   [(set (reg FLAGS_REG)
8302         (compare (zero_extract:SI
8303                    (match_operand 0 "nonimmediate_operand" "rm")
8304                    (match_operand:SI 1 "const_int_operand" "")
8305                    (match_operand:SI 2 "const_int_operand" ""))
8306                  (const_int 0)))]
8307   "ix86_match_ccmode (insn, CCNOmode)
8308    && INTVAL (operands[1]) > 0
8309    && INTVAL (operands[2]) >= 0
8310    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8311    && (GET_MODE (operands[0]) == SImode
8312        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8313        || GET_MODE (operands[0]) == HImode
8314        || GET_MODE (operands[0]) == QImode)"
8315   "#")
8316
8317 (define_split
8318   [(set (match_operand 0 "flags_reg_operand" "")
8319         (match_operator 1 "compare_operator"
8320           [(zero_extract
8321              (match_operand 2 "nonimmediate_operand" "")
8322              (match_operand 3 "const_int_operand" "")
8323              (match_operand 4 "const_int_operand" ""))
8324            (const_int 0)]))]
8325   "ix86_match_ccmode (insn, CCNOmode)"
8326   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8327 {
8328   rtx val = operands[2];
8329   HOST_WIDE_INT len = INTVAL (operands[3]);
8330   HOST_WIDE_INT pos = INTVAL (operands[4]);
8331   HOST_WIDE_INT mask;
8332   enum machine_mode mode, submode;
8333
8334   mode = GET_MODE (val);
8335   if (MEM_P (val))
8336     {
8337       /* ??? Combine likes to put non-volatile mem extractions in QImode
8338          no matter the size of the test.  So find a mode that works.  */
8339       if (! MEM_VOLATILE_P (val))
8340         {
8341           mode = smallest_mode_for_size (pos + len, MODE_INT);
8342           val = adjust_address (val, mode, 0);
8343         }
8344     }
8345   else if (GET_CODE (val) == SUBREG
8346            && (submode = GET_MODE (SUBREG_REG (val)),
8347                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8348            && pos + len <= GET_MODE_BITSIZE (submode)
8349            && GET_MODE_CLASS (submode) == MODE_INT)
8350     {
8351       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8352       mode = submode;
8353       val = SUBREG_REG (val);
8354     }
8355   else if (mode == HImode && pos + len <= 8)
8356     {
8357       /* Small HImode tests can be converted to QImode.  */
8358       mode = QImode;
8359       val = gen_lowpart (QImode, val);
8360     }
8361
8362   if (len == HOST_BITS_PER_WIDE_INT)
8363     mask = -1;
8364   else
8365     mask = ((HOST_WIDE_INT)1 << len) - 1;
8366   mask <<= pos;
8367
8368   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8369 })
8370
8371 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8372 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8373 ;; this is relatively important trick.
8374 ;; Do the conversion only post-reload to avoid limiting of the register class
8375 ;; to QI regs.
8376 (define_split
8377   [(set (match_operand 0 "flags_reg_operand" "")
8378         (match_operator 1 "compare_operator"
8379           [(and (match_operand 2 "register_operand" "")
8380                 (match_operand 3 "const_int_operand" ""))
8381            (const_int 0)]))]
8382    "reload_completed
8383     && QI_REG_P (operands[2])
8384     && GET_MODE (operands[2]) != QImode
8385     && ((ix86_match_ccmode (insn, CCZmode)
8386          && !(INTVAL (operands[3]) & ~(255 << 8)))
8387         || (ix86_match_ccmode (insn, CCNOmode)
8388             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8389   [(set (match_dup 0)
8390         (match_op_dup 1
8391           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8392                    (match_dup 3))
8393            (const_int 0)]))]
8394   "operands[2] = gen_lowpart (SImode, operands[2]);
8395    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8396
8397 (define_split
8398   [(set (match_operand 0 "flags_reg_operand" "")
8399         (match_operator 1 "compare_operator"
8400           [(and (match_operand 2 "nonimmediate_operand" "")
8401                 (match_operand 3 "const_int_operand" ""))
8402            (const_int 0)]))]
8403    "reload_completed
8404     && GET_MODE (operands[2]) != QImode
8405     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8406     && ((ix86_match_ccmode (insn, CCZmode)
8407          && !(INTVAL (operands[3]) & ~255))
8408         || (ix86_match_ccmode (insn, CCNOmode)
8409             && !(INTVAL (operands[3]) & ~127)))"
8410   [(set (match_dup 0)
8411         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8412                          (const_int 0)]))]
8413   "operands[2] = gen_lowpart (QImode, operands[2]);
8414    operands[3] = gen_lowpart (QImode, operands[3]);")
8415
8416 ;; %%% This used to optimize known byte-wide and operations to memory,
8417 ;; and sometimes to QImode registers.  If this is considered useful,
8418 ;; it should be done with splitters.
8419
8420 (define_expand "and<mode>3"
8421   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8422         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8423                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8424   ""
8425   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8426
8427 (define_insn "*anddi_1"
8428   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8429         (and:DI
8430          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8431          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8434 {
8435   switch (get_attr_type (insn))
8436     {
8437     case TYPE_IMOVX:
8438       {
8439         enum machine_mode mode;
8440
8441         gcc_assert (CONST_INT_P (operands[2]));
8442         if (INTVAL (operands[2]) == 0xff)
8443           mode = QImode;
8444         else
8445           {
8446             gcc_assert (INTVAL (operands[2]) == 0xffff);
8447             mode = HImode;
8448           }
8449
8450         operands[1] = gen_lowpart (mode, operands[1]);
8451         if (mode == QImode)
8452           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8453         else
8454           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8455       }
8456
8457     default:
8458       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8459       if (get_attr_mode (insn) == MODE_SI)
8460         return "and{l}\t{%k2, %k0|%k0, %k2}";
8461       else
8462         return "and{q}\t{%2, %0|%0, %2}";
8463     }
8464 }
8465   [(set_attr "type" "alu,alu,alu,imovx")
8466    (set_attr "length_immediate" "*,*,*,0")
8467    (set (attr "prefix_rex")
8468      (if_then_else
8469        (and (eq_attr "type" "imovx")
8470             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8471                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8472        (const_string "1")
8473        (const_string "*")))
8474    (set_attr "mode" "SI,DI,DI,SI")])
8475
8476 (define_insn "*andsi_1"
8477   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8478         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8479                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "ix86_binary_operator_ok (AND, SImode, operands)"
8482 {
8483   switch (get_attr_type (insn))
8484     {
8485     case TYPE_IMOVX:
8486       {
8487         enum machine_mode mode;
8488
8489         gcc_assert (CONST_INT_P (operands[2]));
8490         if (INTVAL (operands[2]) == 0xff)
8491           mode = QImode;
8492         else
8493           {
8494             gcc_assert (INTVAL (operands[2]) == 0xffff);
8495             mode = HImode;
8496           }
8497
8498         operands[1] = gen_lowpart (mode, operands[1]);
8499         if (mode == QImode)
8500           return "movz{bl|x}\t{%1, %0|%0, %1}";
8501         else
8502           return "movz{wl|x}\t{%1, %0|%0, %1}";
8503       }
8504
8505     default:
8506       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8507       return "and{l}\t{%2, %0|%0, %2}";
8508     }
8509 }
8510   [(set_attr "type" "alu,alu,imovx")
8511    (set (attr "prefix_rex")
8512      (if_then_else
8513        (and (eq_attr "type" "imovx")
8514             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8515                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8516        (const_string "1")
8517        (const_string "*")))
8518    (set_attr "length_immediate" "*,*,0")
8519    (set_attr "mode" "SI")])
8520
8521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8522 (define_insn "*andsi_1_zext"
8523   [(set (match_operand:DI 0 "register_operand" "=r")
8524         (zero_extend:DI
8525           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8526                   (match_operand:SI 2 "general_operand" "g"))))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8529   "and{l}\t{%2, %k0|%k0, %2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "mode" "SI")])
8532
8533 (define_insn "*andhi_1"
8534   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8535         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8536                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8537    (clobber (reg:CC FLAGS_REG))]
8538   "ix86_binary_operator_ok (AND, HImode, operands)"
8539 {
8540   switch (get_attr_type (insn))
8541     {
8542     case TYPE_IMOVX:
8543       gcc_assert (CONST_INT_P (operands[2]));
8544       gcc_assert (INTVAL (operands[2]) == 0xff);
8545       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8546
8547     default:
8548       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8549
8550       return "and{w}\t{%2, %0|%0, %2}";
8551     }
8552 }
8553   [(set_attr "type" "alu,alu,imovx")
8554    (set_attr "length_immediate" "*,*,0")
8555    (set (attr "prefix_rex")
8556      (if_then_else
8557        (and (eq_attr "type" "imovx")
8558             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8559        (const_string "1")
8560        (const_string "*")))
8561    (set_attr "mode" "HI,HI,SI")])
8562
8563 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8564 (define_insn "*andqi_1"
8565   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8566         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8567                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "ix86_binary_operator_ok (AND, QImode, operands)"
8570   "@
8571    and{b}\t{%2, %0|%0, %2}
8572    and{b}\t{%2, %0|%0, %2}
8573    and{l}\t{%k2, %k0|%k0, %k2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "QI,QI,SI")])
8576
8577 (define_insn "*andqi_1_slp"
8578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8579         (and:QI (match_dup 0)
8580                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584   "and{b}\t{%1, %0|%0, %1}"
8585   [(set_attr "type" "alu1")
8586    (set_attr "mode" "QI")])
8587
8588 (define_split
8589   [(set (match_operand 0 "register_operand" "")
8590         (and (match_dup 0)
8591              (const_int -65536)))
8592    (clobber (reg:CC FLAGS_REG))]
8593   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8594     || optimize_function_for_size_p (cfun)"
8595   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8596   "operands[1] = gen_lowpart (HImode, operands[0]);")
8597
8598 (define_split
8599   [(set (match_operand 0 "ext_register_operand" "")
8600         (and (match_dup 0)
8601              (const_int -256)))
8602    (clobber (reg:CC FLAGS_REG))]
8603   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8604    && reload_completed"
8605   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8606   "operands[1] = gen_lowpart (QImode, operands[0]);")
8607
8608 (define_split
8609   [(set (match_operand 0 "ext_register_operand" "")
8610         (and (match_dup 0)
8611              (const_int -65281)))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8614    && reload_completed"
8615   [(parallel [(set (zero_extract:SI (match_dup 0)
8616                                     (const_int 8)
8617                                     (const_int 8))
8618                    (xor:SI
8619                      (zero_extract:SI (match_dup 0)
8620                                       (const_int 8)
8621                                       (const_int 8))
8622                      (zero_extract:SI (match_dup 0)
8623                                       (const_int 8)
8624                                       (const_int 8))))
8625               (clobber (reg:CC FLAGS_REG))])]
8626   "operands[0] = gen_lowpart (SImode, operands[0]);")
8627
8628 (define_insn "*anddi_2"
8629   [(set (reg FLAGS_REG)
8630         (compare
8631          (and:DI
8632           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8633           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8634          (const_int 0)))
8635    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8636         (and:DI (match_dup 1) (match_dup 2)))]
8637   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638    && ix86_binary_operator_ok (AND, DImode, operands)"
8639   "@
8640    and{l}\t{%k2, %k0|%k0, %k2}
8641    and{q}\t{%2, %0|%0, %2}
8642    and{q}\t{%2, %0|%0, %2}"
8643   [(set_attr "type" "alu")
8644    (set_attr "mode" "SI,DI,DI")])
8645
8646 (define_insn "*andqi_2_maybe_si"
8647   [(set (reg FLAGS_REG)
8648         (compare (and:QI
8649                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8651                  (const_int 0)))
8652    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653         (and:QI (match_dup 1) (match_dup 2)))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)
8655    && ix86_match_ccmode (insn,
8656                          CONST_INT_P (operands[2])
8657                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8658 {
8659   if (which_alternative == 2)
8660     {
8661       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663       return "and{l}\t{%2, %k0|%k0, %2}";
8664     }
8665   return "and{b}\t{%2, %0|%0, %2}";
8666 }
8667   [(set_attr "type" "alu")
8668    (set_attr "mode" "QI,QI,SI")])
8669
8670 (define_insn "*and<mode>_2"
8671   [(set (reg FLAGS_REG)
8672         (compare (and:SWI124
8673                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8674                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8675                  (const_int 0)))
8676    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8677         (and:SWI124 (match_dup 1) (match_dup 2)))]
8678   "ix86_match_ccmode (insn, CCNOmode)
8679    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8680   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8681   [(set_attr "type" "alu")
8682    (set_attr "mode" "<MODE>")])
8683
8684 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8685 (define_insn "*andsi_2_zext"
8686   [(set (reg FLAGS_REG)
8687         (compare (and:SI
8688                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8689                   (match_operand:SI 2 "general_operand" "g"))
8690                  (const_int 0)))
8691    (set (match_operand:DI 0 "register_operand" "=r")
8692         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8693   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (AND, SImode, operands)"
8695   "and{l}\t{%2, %k0|%k0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "SI")])
8698
8699 (define_insn "*andqi_2_slp"
8700   [(set (reg FLAGS_REG)
8701         (compare (and:QI
8702                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8703                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8704                  (const_int 0)))
8705    (set (strict_low_part (match_dup 0))
8706         (and:QI (match_dup 0) (match_dup 1)))]
8707   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8708    && ix86_match_ccmode (insn, CCNOmode)
8709    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8710   "and{b}\t{%1, %0|%0, %1}"
8711   [(set_attr "type" "alu1")
8712    (set_attr "mode" "QI")])
8713
8714 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8715 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8716 ;; for a QImode operand, which of course failed.
8717 (define_insn "andqi_ext_0"
8718   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8719                          (const_int 8)
8720                          (const_int 8))
8721         (and:SI
8722           (zero_extract:SI
8723             (match_operand 1 "ext_register_operand" "0")
8724             (const_int 8)
8725             (const_int 8))
8726           (match_operand 2 "const_int_operand" "n")))
8727    (clobber (reg:CC FLAGS_REG))]
8728   ""
8729   "and{b}\t{%2, %h0|%h0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "length_immediate" "1")
8732    (set_attr "modrm" "1")
8733    (set_attr "mode" "QI")])
8734
8735 ;; Generated by peephole translating test to and.  This shows up
8736 ;; often in fp comparisons.
8737 (define_insn "*andqi_ext_0_cc"
8738   [(set (reg FLAGS_REG)
8739         (compare
8740           (and:SI
8741             (zero_extract:SI
8742               (match_operand 1 "ext_register_operand" "0")
8743               (const_int 8)
8744               (const_int 8))
8745             (match_operand 2 "const_int_operand" "n"))
8746           (const_int 0)))
8747    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8748                          (const_int 8)
8749                          (const_int 8))
8750         (and:SI
8751           (zero_extract:SI
8752             (match_dup 1)
8753             (const_int 8)
8754             (const_int 8))
8755           (match_dup 2)))]
8756   "ix86_match_ccmode (insn, CCNOmode)"
8757   "and{b}\t{%2, %h0|%h0, %2}"
8758   [(set_attr "type" "alu")
8759    (set_attr "length_immediate" "1")
8760    (set_attr "modrm" "1")
8761    (set_attr "mode" "QI")])
8762
8763 (define_insn "*andqi_ext_1_rex64"
8764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765                          (const_int 8)
8766                          (const_int 8))
8767         (and:SI
8768           (zero_extract:SI
8769             (match_operand 1 "ext_register_operand" "0")
8770             (const_int 8)
8771             (const_int 8))
8772           (zero_extend:SI
8773             (match_operand 2 "ext_register_operand" "Q"))))
8774    (clobber (reg:CC FLAGS_REG))]
8775   "TARGET_64BIT"
8776   "and{b}\t{%2, %h0|%h0, %2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "length_immediate" "0")
8779    (set_attr "mode" "QI")])
8780
8781 (define_insn "*andqi_ext_1"
8782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783                          (const_int 8)
8784                          (const_int 8))
8785         (and:SI
8786           (zero_extract:SI
8787             (match_operand 1 "ext_register_operand" "0")
8788             (const_int 8)
8789             (const_int 8))
8790           (zero_extend:SI
8791             (match_operand:QI 2 "general_operand" "Qm"))))
8792    (clobber (reg:CC FLAGS_REG))]
8793   "!TARGET_64BIT"
8794   "and{b}\t{%2, %h0|%h0, %2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "length_immediate" "0")
8797    (set_attr "mode" "QI")])
8798
8799 (define_insn "*andqi_ext_2"
8800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8801                          (const_int 8)
8802                          (const_int 8))
8803         (and:SI
8804           (zero_extract:SI
8805             (match_operand 1 "ext_register_operand" "%0")
8806             (const_int 8)
8807             (const_int 8))
8808           (zero_extract:SI
8809             (match_operand 2 "ext_register_operand" "Q")
8810             (const_int 8)
8811             (const_int 8))))
8812    (clobber (reg:CC FLAGS_REG))]
8813   ""
8814   "and{b}\t{%h2, %h0|%h0, %h2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "length_immediate" "0")
8817    (set_attr "mode" "QI")])
8818
8819 ;; Convert wide AND instructions with immediate operand to shorter QImode
8820 ;; equivalents when possible.
8821 ;; Don't do the splitting with memory operands, since it introduces risk
8822 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8823 ;; for size, but that can (should?) be handled by generic code instead.
8824 (define_split
8825   [(set (match_operand 0 "register_operand" "")
8826         (and (match_operand 1 "register_operand" "")
8827              (match_operand 2 "const_int_operand" "")))
8828    (clobber (reg:CC FLAGS_REG))]
8829    "reload_completed
8830     && QI_REG_P (operands[0])
8831     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8832     && !(~INTVAL (operands[2]) & ~(255 << 8))
8833     && GET_MODE (operands[0]) != QImode"
8834   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8835                    (and:SI (zero_extract:SI (match_dup 1)
8836                                             (const_int 8) (const_int 8))
8837                            (match_dup 2)))
8838               (clobber (reg:CC FLAGS_REG))])]
8839   "operands[0] = gen_lowpart (SImode, operands[0]);
8840    operands[1] = gen_lowpart (SImode, operands[1]);
8841    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8842
8843 ;; Since AND can be encoded with sign extended immediate, this is only
8844 ;; profitable when 7th bit is not set.
8845 (define_split
8846   [(set (match_operand 0 "register_operand" "")
8847         (and (match_operand 1 "general_operand" "")
8848              (match_operand 2 "const_int_operand" "")))
8849    (clobber (reg:CC FLAGS_REG))]
8850    "reload_completed
8851     && ANY_QI_REG_P (operands[0])
8852     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8853     && !(~INTVAL (operands[2]) & ~255)
8854     && !(INTVAL (operands[2]) & 128)
8855     && GET_MODE (operands[0]) != QImode"
8856   [(parallel [(set (strict_low_part (match_dup 0))
8857                    (and:QI (match_dup 1)
8858                            (match_dup 2)))
8859               (clobber (reg:CC FLAGS_REG))])]
8860   "operands[0] = gen_lowpart (QImode, operands[0]);
8861    operands[1] = gen_lowpart (QImode, operands[1]);
8862    operands[2] = gen_lowpart (QImode, operands[2]);")
8863 \f
8864 ;; Logical inclusive and exclusive OR instructions
8865
8866 ;; %%% This used to optimize known byte-wide and operations to memory.
8867 ;; If this is considered useful, it should be done with splitters.
8868
8869 (define_expand "<code><mode>3"
8870   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8871         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8872                      (match_operand:SWIM 2 "<general_operand>" "")))]
8873   ""
8874   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8875
8876 (define_insn "*<code><mode>_1"
8877   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8878         (any_or:SWI248
8879          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8880          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8881    (clobber (reg:CC FLAGS_REG))]
8882   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8883   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "<MODE>")])
8886
8887 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8888 (define_insn "*<code>qi_1"
8889   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8890         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8891                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8892    (clobber (reg:CC FLAGS_REG))]
8893   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8894   "@
8895    <logicprefix>{b}\t{%2, %0|%0, %2}
8896    <logicprefix>{b}\t{%2, %0|%0, %2}
8897    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "QI,QI,SI")])
8900
8901 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902 (define_insn "*<code>si_1_zext"
8903   [(set (match_operand:DI 0 "register_operand" "=r")
8904         (zero_extend:DI
8905          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8906                     (match_operand:SI 2 "general_operand" "g"))))
8907    (clobber (reg:CC FLAGS_REG))]
8908   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8909   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "SI")])
8912
8913 (define_insn "*<code>si_1_zext_imm"
8914   [(set (match_operand:DI 0 "register_operand" "=r")
8915         (any_or:DI
8916          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8917          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8920   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8923
8924 (define_insn "*<code>qi_1_slp"
8925   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8926         (any_or:QI (match_dup 0)
8927                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8930    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8931   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8932   [(set_attr "type" "alu1")
8933    (set_attr "mode" "QI")])
8934
8935 (define_insn "*<code><mode>_2"
8936   [(set (reg FLAGS_REG)
8937         (compare (any_or:SWI
8938                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8939                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8940                  (const_int 0)))
8941    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8942         (any_or:SWI (match_dup 1) (match_dup 2)))]
8943   "ix86_match_ccmode (insn, CCNOmode)
8944    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8945   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "<MODE>")])
8948
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 ;; ??? Special case for immediate operand is missing - it is tricky.
8951 (define_insn "*<code>si_2_zext"
8952   [(set (reg FLAGS_REG)
8953         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8954                             (match_operand:SI 2 "general_operand" "g"))
8955                  (const_int 0)))
8956    (set (match_operand:DI 0 "register_operand" "=r")
8957         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8958   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8959    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8960   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8961   [(set_attr "type" "alu")
8962    (set_attr "mode" "SI")])
8963
8964 (define_insn "*<code>si_2_zext_imm"
8965   [(set (reg FLAGS_REG)
8966         (compare (any_or:SI
8967                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8968                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8969                  (const_int 0)))
8970    (set (match_operand:DI 0 "register_operand" "=r")
8971         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8972   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8973    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8974   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8975   [(set_attr "type" "alu")
8976    (set_attr "mode" "SI")])
8977
8978 (define_insn "*<code>qi_2_slp"
8979   [(set (reg FLAGS_REG)
8980         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8981                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8982                  (const_int 0)))
8983    (set (strict_low_part (match_dup 0))
8984         (any_or:QI (match_dup 0) (match_dup 1)))]
8985   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8986    && ix86_match_ccmode (insn, CCNOmode)
8987    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8988   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8989   [(set_attr "type" "alu1")
8990    (set_attr "mode" "QI")])
8991
8992 (define_insn "*<code><mode>_3"
8993   [(set (reg FLAGS_REG)
8994         (compare (any_or:SWI
8995                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8996                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8997                  (const_int 0)))
8998    (clobber (match_scratch:SWI 0 "=<r>"))]
8999   "ix86_match_ccmode (insn, CCNOmode)
9000    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9001   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "<MODE>")])
9004
9005 (define_insn "*<code>qi_ext_0"
9006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9007                          (const_int 8)
9008                          (const_int 8))
9009         (any_or:SI
9010           (zero_extract:SI
9011             (match_operand 1 "ext_register_operand" "0")
9012             (const_int 8)
9013             (const_int 8))
9014           (match_operand 2 "const_int_operand" "n")))
9015    (clobber (reg:CC FLAGS_REG))]
9016   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9017   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "length_immediate" "1")
9020    (set_attr "modrm" "1")
9021    (set_attr "mode" "QI")])
9022
9023 (define_insn "*<code>qi_ext_1_rex64"
9024   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9025                          (const_int 8)
9026                          (const_int 8))
9027         (any_or:SI
9028           (zero_extract:SI
9029             (match_operand 1 "ext_register_operand" "0")
9030             (const_int 8)
9031             (const_int 8))
9032           (zero_extend:SI
9033             (match_operand 2 "ext_register_operand" "Q"))))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "TARGET_64BIT
9036    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9037   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "length_immediate" "0")
9040    (set_attr "mode" "QI")])
9041
9042 (define_insn "*<code>qi_ext_1"
9043   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9044                          (const_int 8)
9045                          (const_int 8))
9046         (any_or:SI
9047           (zero_extract:SI
9048             (match_operand 1 "ext_register_operand" "0")
9049             (const_int 8)
9050             (const_int 8))
9051           (zero_extend:SI
9052             (match_operand:QI 2 "general_operand" "Qm"))))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "!TARGET_64BIT
9055    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9056   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9057   [(set_attr "type" "alu")
9058    (set_attr "length_immediate" "0")
9059    (set_attr "mode" "QI")])
9060
9061 (define_insn "*<code>qi_ext_2"
9062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9063                          (const_int 8)
9064                          (const_int 8))
9065         (any_or:SI
9066           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9067                            (const_int 8)
9068                            (const_int 8))
9069           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9070                            (const_int 8)
9071                            (const_int 8))))
9072    (clobber (reg:CC FLAGS_REG))]
9073   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9074   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
9075   [(set_attr "type" "alu")
9076    (set_attr "length_immediate" "0")
9077    (set_attr "mode" "QI")])
9078
9079 (define_split
9080   [(set (match_operand 0 "register_operand" "")
9081         (any_or (match_operand 1 "register_operand" "")
9082                 (match_operand 2 "const_int_operand" "")))
9083    (clobber (reg:CC FLAGS_REG))]
9084    "reload_completed
9085     && QI_REG_P (operands[0])
9086     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9087     && !(INTVAL (operands[2]) & ~(255 << 8))
9088     && GET_MODE (operands[0]) != QImode"
9089   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9090                    (any_or:SI (zero_extract:SI (match_dup 1)
9091                                                (const_int 8) (const_int 8))
9092                               (match_dup 2)))
9093               (clobber (reg:CC FLAGS_REG))])]
9094   "operands[0] = gen_lowpart (SImode, operands[0]);
9095    operands[1] = gen_lowpart (SImode, operands[1]);
9096    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9097
9098 ;; Since OR can be encoded with sign extended immediate, this is only
9099 ;; profitable when 7th bit is set.
9100 (define_split
9101   [(set (match_operand 0 "register_operand" "")
9102         (any_or (match_operand 1 "general_operand" "")
9103                 (match_operand 2 "const_int_operand" "")))
9104    (clobber (reg:CC FLAGS_REG))]
9105    "reload_completed
9106     && ANY_QI_REG_P (operands[0])
9107     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9108     && !(INTVAL (operands[2]) & ~255)
9109     && (INTVAL (operands[2]) & 128)
9110     && GET_MODE (operands[0]) != QImode"
9111   [(parallel [(set (strict_low_part (match_dup 0))
9112                    (any_or:QI (match_dup 1)
9113                               (match_dup 2)))
9114               (clobber (reg:CC FLAGS_REG))])]
9115   "operands[0] = gen_lowpart (QImode, operands[0]);
9116    operands[1] = gen_lowpart (QImode, operands[1]);
9117    operands[2] = gen_lowpart (QImode, operands[2]);")
9118
9119 (define_expand "xorqi_cc_ext_1"
9120   [(parallel [
9121      (set (reg:CCNO FLAGS_REG)
9122           (compare:CCNO
9123             (xor:SI
9124               (zero_extract:SI
9125                 (match_operand 1 "ext_register_operand" "")
9126                 (const_int 8)
9127                 (const_int 8))
9128               (match_operand:QI 2 "general_operand" ""))
9129             (const_int 0)))
9130      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9131                            (const_int 8)
9132                            (const_int 8))
9133           (xor:SI
9134             (zero_extract:SI
9135              (match_dup 1)
9136              (const_int 8)
9137              (const_int 8))
9138             (match_dup 2)))])]
9139   ""
9140   "")
9141
9142 (define_insn "*xorqi_cc_ext_1_rex64"
9143   [(set (reg FLAGS_REG)
9144         (compare
9145           (xor:SI
9146             (zero_extract:SI
9147               (match_operand 1 "ext_register_operand" "0")
9148               (const_int 8)
9149               (const_int 8))
9150             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9151           (const_int 0)))
9152    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9153                          (const_int 8)
9154                          (const_int 8))
9155         (xor:SI
9156           (zero_extract:SI
9157            (match_dup 1)
9158            (const_int 8)
9159            (const_int 8))
9160           (match_dup 2)))]
9161   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9162   "xor{b}\t{%2, %h0|%h0, %2}"
9163   [(set_attr "type" "alu")
9164    (set_attr "modrm" "1")
9165    (set_attr "mode" "QI")])
9166
9167 (define_insn "*xorqi_cc_ext_1"
9168   [(set (reg FLAGS_REG)
9169         (compare
9170           (xor:SI
9171             (zero_extract:SI
9172               (match_operand 1 "ext_register_operand" "0")
9173               (const_int 8)
9174               (const_int 8))
9175             (match_operand:QI 2 "general_operand" "qmn"))
9176           (const_int 0)))
9177    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9178                          (const_int 8)
9179                          (const_int 8))
9180         (xor:SI
9181           (zero_extract:SI
9182            (match_dup 1)
9183            (const_int 8)
9184            (const_int 8))
9185           (match_dup 2)))]
9186   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9187   "xor{b}\t{%2, %h0|%h0, %2}"
9188   [(set_attr "type" "alu")
9189    (set_attr "modrm" "1")
9190    (set_attr "mode" "QI")])
9191 \f
9192 ;; Negation instructions
9193
9194 (define_expand "neg<mode>2"
9195   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9196         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9197   ""
9198   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9199
9200 (define_insn_and_split "*neg<dwi>2_doubleword"
9201   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9202         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9205   "#"
9206   "reload_completed"
9207   [(parallel
9208     [(set (reg:CCZ FLAGS_REG)
9209           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9210      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9211    (parallel
9212     [(set (match_dup 2)
9213           (plus:DWIH (match_dup 3)
9214                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9215                                 (const_int 0))))
9216      (clobber (reg:CC FLAGS_REG))])
9217    (parallel
9218     [(set (match_dup 2)
9219           (neg:DWIH (match_dup 2)))
9220      (clobber (reg:CC FLAGS_REG))])]
9221   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9222
9223 (define_insn "*neg<mode>2_1"
9224   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9225         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9226    (clobber (reg:CC FLAGS_REG))]
9227   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9228   "neg{<imodesuffix>}\t%0"
9229   [(set_attr "type" "negnot")
9230    (set_attr "mode" "<MODE>")])
9231
9232 ;; Combine is quite creative about this pattern.
9233 (define_insn "*negsi2_1_zext"
9234   [(set (match_operand:DI 0 "register_operand" "=r")
9235         (lshiftrt:DI
9236           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9237                              (const_int 32)))
9238         (const_int 32)))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9241   "neg{l}\t%k0"
9242   [(set_attr "type" "negnot")
9243    (set_attr "mode" "SI")])
9244
9245 ;; The problem with neg is that it does not perform (compare x 0),
9246 ;; it really performs (compare 0 x), which leaves us with the zero
9247 ;; flag being the only useful item.
9248
9249 (define_insn "*neg<mode>2_cmpz"
9250   [(set (reg:CCZ FLAGS_REG)
9251         (compare:CCZ
9252           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9253                    (const_int 0)))
9254    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9255         (neg:SWI (match_dup 1)))]
9256   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9257   "neg{<imodesuffix>}\t%0"
9258   [(set_attr "type" "negnot")
9259    (set_attr "mode" "<MODE>")])
9260
9261 (define_insn "*negsi2_cmpz_zext"
9262   [(set (reg:CCZ FLAGS_REG)
9263         (compare:CCZ
9264           (lshiftrt:DI
9265             (neg:DI (ashift:DI
9266                       (match_operand:DI 1 "register_operand" "0")
9267                       (const_int 32)))
9268             (const_int 32))
9269           (const_int 0)))
9270    (set (match_operand:DI 0 "register_operand" "=r")
9271         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9272                                         (const_int 32)))
9273                      (const_int 32)))]
9274   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9275   "neg{l}\t%k0"
9276   [(set_attr "type" "negnot")
9277    (set_attr "mode" "SI")])
9278
9279 ;; Changing of sign for FP values is doable using integer unit too.
9280
9281 (define_expand "<code><mode>2"
9282   [(set (match_operand:X87MODEF 0 "register_operand" "")
9283         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9284   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9285   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9286
9287 (define_insn "*absneg<mode>2_mixed"
9288   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9289         (match_operator:MODEF 3 "absneg_operator"
9290           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9291    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9292    (clobber (reg:CC FLAGS_REG))]
9293   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9294   "#")
9295
9296 (define_insn "*absneg<mode>2_sse"
9297   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9298         (match_operator:MODEF 3 "absneg_operator"
9299           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9300    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9301    (clobber (reg:CC FLAGS_REG))]
9302   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9303   "#")
9304
9305 (define_insn "*absneg<mode>2_i387"
9306   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9307         (match_operator:X87MODEF 3 "absneg_operator"
9308           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9309    (use (match_operand 2 "" ""))
9310    (clobber (reg:CC FLAGS_REG))]
9311   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9312   "#")
9313
9314 (define_expand "<code>tf2"
9315   [(set (match_operand:TF 0 "register_operand" "")
9316         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9317   "TARGET_SSE2"
9318   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9319
9320 (define_insn "*absnegtf2_sse"
9321   [(set (match_operand:TF 0 "register_operand" "=x,x")
9322         (match_operator:TF 3 "absneg_operator"
9323           [(match_operand:TF 1 "register_operand" "0,x")]))
9324    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9325    (clobber (reg:CC FLAGS_REG))]
9326   "TARGET_SSE2"
9327   "#")
9328
9329 ;; Splitters for fp abs and neg.
9330
9331 (define_split
9332   [(set (match_operand 0 "fp_register_operand" "")
9333         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9334    (use (match_operand 2 "" ""))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "reload_completed"
9337   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9338
9339 (define_split
9340   [(set (match_operand 0 "register_operand" "")
9341         (match_operator 3 "absneg_operator"
9342           [(match_operand 1 "register_operand" "")]))
9343    (use (match_operand 2 "nonimmediate_operand" ""))
9344    (clobber (reg:CC FLAGS_REG))]
9345   "reload_completed && SSE_REG_P (operands[0])"
9346   [(set (match_dup 0) (match_dup 3))]
9347 {
9348   enum machine_mode mode = GET_MODE (operands[0]);
9349   enum machine_mode vmode = GET_MODE (operands[2]);
9350   rtx tmp;
9351
9352   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9353   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9354   if (operands_match_p (operands[0], operands[2]))
9355     {
9356       tmp = operands[1];
9357       operands[1] = operands[2];
9358       operands[2] = tmp;
9359     }
9360   if (GET_CODE (operands[3]) == ABS)
9361     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9362   else
9363     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9364   operands[3] = tmp;
9365 })
9366
9367 (define_split
9368   [(set (match_operand:SF 0 "register_operand" "")
9369         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9370    (use (match_operand:V4SF 2 "" ""))
9371    (clobber (reg:CC FLAGS_REG))]
9372   "reload_completed"
9373   [(parallel [(set (match_dup 0) (match_dup 1))
9374               (clobber (reg:CC FLAGS_REG))])]
9375 {
9376   rtx tmp;
9377   operands[0] = gen_lowpart (SImode, operands[0]);
9378   if (GET_CODE (operands[1]) == ABS)
9379     {
9380       tmp = gen_int_mode (0x7fffffff, SImode);
9381       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9382     }
9383   else
9384     {
9385       tmp = gen_int_mode (0x80000000, SImode);
9386       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9387     }
9388   operands[1] = tmp;
9389 })
9390
9391 (define_split
9392   [(set (match_operand:DF 0 "register_operand" "")
9393         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9394    (use (match_operand 2 "" ""))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "reload_completed"
9397   [(parallel [(set (match_dup 0) (match_dup 1))
9398               (clobber (reg:CC FLAGS_REG))])]
9399 {
9400   rtx tmp;
9401   if (TARGET_64BIT)
9402     {
9403       tmp = gen_lowpart (DImode, operands[0]);
9404       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9405       operands[0] = tmp;
9406
9407       if (GET_CODE (operands[1]) == ABS)
9408         tmp = const0_rtx;
9409       else
9410         tmp = gen_rtx_NOT (DImode, tmp);
9411     }
9412   else
9413     {
9414       operands[0] = gen_highpart (SImode, operands[0]);
9415       if (GET_CODE (operands[1]) == ABS)
9416         {
9417           tmp = gen_int_mode (0x7fffffff, SImode);
9418           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9419         }
9420       else
9421         {
9422           tmp = gen_int_mode (0x80000000, SImode);
9423           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9424         }
9425     }
9426   operands[1] = tmp;
9427 })
9428
9429 (define_split
9430   [(set (match_operand:XF 0 "register_operand" "")
9431         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9432    (use (match_operand 2 "" ""))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "reload_completed"
9435   [(parallel [(set (match_dup 0) (match_dup 1))
9436               (clobber (reg:CC FLAGS_REG))])]
9437 {
9438   rtx tmp;
9439   operands[0] = gen_rtx_REG (SImode,
9440                              true_regnum (operands[0])
9441                              + (TARGET_64BIT ? 1 : 2));
9442   if (GET_CODE (operands[1]) == ABS)
9443     {
9444       tmp = GEN_INT (0x7fff);
9445       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9446     }
9447   else
9448     {
9449       tmp = GEN_INT (0x8000);
9450       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9451     }
9452   operands[1] = tmp;
9453 })
9454
9455 ;; Conditionalize these after reload. If they match before reload, we
9456 ;; lose the clobber and ability to use integer instructions.
9457
9458 (define_insn "*<code><mode>2_1"
9459   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9460         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9461   "TARGET_80387
9462    && (reload_completed
9463        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9464   "f<absnegprefix>"
9465   [(set_attr "type" "fsgn")
9466    (set_attr "mode" "<MODE>")])
9467
9468 (define_insn "*<code>extendsfdf2"
9469   [(set (match_operand:DF 0 "register_operand" "=f")
9470         (absneg:DF (float_extend:DF
9471                      (match_operand:SF 1 "register_operand" "0"))))]
9472   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9473   "f<absnegprefix>"
9474   [(set_attr "type" "fsgn")
9475    (set_attr "mode" "DF")])
9476
9477 (define_insn "*<code>extendsfxf2"
9478   [(set (match_operand:XF 0 "register_operand" "=f")
9479         (absneg:XF (float_extend:XF
9480                      (match_operand:SF 1 "register_operand" "0"))))]
9481   "TARGET_80387"
9482   "f<absnegprefix>"
9483   [(set_attr "type" "fsgn")
9484    (set_attr "mode" "XF")])
9485
9486 (define_insn "*<code>extenddfxf2"
9487   [(set (match_operand:XF 0 "register_operand" "=f")
9488         (absneg:XF (float_extend:XF
9489                       (match_operand:DF 1 "register_operand" "0"))))]
9490   "TARGET_80387"
9491   "f<absnegprefix>"
9492   [(set_attr "type" "fsgn")
9493    (set_attr "mode" "XF")])
9494
9495 ;; Copysign instructions
9496
9497 (define_mode_iterator CSGNMODE [SF DF TF])
9498 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9499
9500 (define_expand "copysign<mode>3"
9501   [(match_operand:CSGNMODE 0 "register_operand" "")
9502    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9503    (match_operand:CSGNMODE 2 "register_operand" "")]
9504   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9505    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9506 {
9507   ix86_expand_copysign (operands);
9508   DONE;
9509 })
9510
9511 (define_insn_and_split "copysign<mode>3_const"
9512   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9513         (unspec:CSGNMODE
9514           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9515            (match_operand:CSGNMODE 2 "register_operand" "0")
9516            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9517           UNSPEC_COPYSIGN))]
9518   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9519    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9520   "#"
9521   "&& reload_completed"
9522   [(const_int 0)]
9523 {
9524   ix86_split_copysign_const (operands);
9525   DONE;
9526 })
9527
9528 (define_insn "copysign<mode>3_var"
9529   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9530         (unspec:CSGNMODE
9531           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9532            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9533            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9534            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9535           UNSPEC_COPYSIGN))
9536    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9537   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9538    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9539   "#")
9540
9541 (define_split
9542   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9543         (unspec:CSGNMODE
9544           [(match_operand:CSGNMODE 2 "register_operand" "")
9545            (match_operand:CSGNMODE 3 "register_operand" "")
9546            (match_operand:<CSGNVMODE> 4 "" "")
9547            (match_operand:<CSGNVMODE> 5 "" "")]
9548           UNSPEC_COPYSIGN))
9549    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9550   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9551     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9552    && reload_completed"
9553   [(const_int 0)]
9554 {
9555   ix86_split_copysign_var (operands);
9556   DONE;
9557 })
9558 \f
9559 ;; One complement instructions
9560
9561 (define_expand "one_cmpl<mode>2"
9562   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9563         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9564   ""
9565   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9566
9567 (define_insn "*one_cmpl<mode>2_1"
9568   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9569         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9570   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9571   "not{<imodesuffix>}\t%0"
9572   [(set_attr "type" "negnot")
9573    (set_attr "mode" "<MODE>")])
9574
9575 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9576 (define_insn "*one_cmplqi2_1"
9577   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9578         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9579   "ix86_unary_operator_ok (NOT, QImode, operands)"
9580   "@
9581    not{b}\t%0
9582    not{l}\t%k0"
9583   [(set_attr "type" "negnot")
9584    (set_attr "mode" "QI,SI")])
9585
9586 ;; ??? Currently never generated - xor is used instead.
9587 (define_insn "*one_cmplsi2_1_zext"
9588   [(set (match_operand:DI 0 "register_operand" "=r")
9589         (zero_extend:DI
9590           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9591   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9592   "not{l}\t%k0"
9593   [(set_attr "type" "negnot")
9594    (set_attr "mode" "SI")])
9595
9596 (define_insn "*one_cmpl<mode>2_2"
9597   [(set (reg FLAGS_REG)
9598         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9599                  (const_int 0)))
9600    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9601         (not:SWI (match_dup 1)))]
9602   "ix86_match_ccmode (insn, CCNOmode)
9603    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9604   "#"
9605   [(set_attr "type" "alu1")
9606    (set_attr "mode" "<MODE>")])
9607
9608 (define_split
9609   [(set (match_operand 0 "flags_reg_operand" "")
9610         (match_operator 2 "compare_operator"
9611           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9612            (const_int 0)]))
9613    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9614         (not:SWI (match_dup 3)))]
9615   "ix86_match_ccmode (insn, CCNOmode)"
9616   [(parallel [(set (match_dup 0)
9617                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9618                                     (const_int 0)]))
9619               (set (match_dup 1)
9620                    (xor:SWI (match_dup 3) (const_int -1)))])]
9621   "")
9622
9623 ;; ??? Currently never generated - xor is used instead.
9624 (define_insn "*one_cmplsi2_2_zext"
9625   [(set (reg FLAGS_REG)
9626         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9627                  (const_int 0)))
9628    (set (match_operand:DI 0 "register_operand" "=r")
9629         (zero_extend:DI (not:SI (match_dup 1))))]
9630   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9631    && ix86_unary_operator_ok (NOT, SImode, operands)"
9632   "#"
9633   [(set_attr "type" "alu1")
9634    (set_attr "mode" "SI")])
9635
9636 (define_split
9637   [(set (match_operand 0 "flags_reg_operand" "")
9638         (match_operator 2 "compare_operator"
9639           [(not:SI (match_operand:SI 3 "register_operand" ""))
9640            (const_int 0)]))
9641    (set (match_operand:DI 1 "register_operand" "")
9642         (zero_extend:DI (not:SI (match_dup 3))))]
9643   "ix86_match_ccmode (insn, CCNOmode)"
9644   [(parallel [(set (match_dup 0)
9645                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9646                                     (const_int 0)]))
9647               (set (match_dup 1)
9648                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9649   "")
9650 \f
9651 ;; Arithmetic shift instructions
9652
9653 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9654 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9655 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9656 ;; from the assembler input.
9657 ;;
9658 ;; This instruction shifts the target reg/mem as usual, but instead of
9659 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9660 ;; is a left shift double, bits are taken from the high order bits of
9661 ;; reg, else if the insn is a shift right double, bits are taken from the
9662 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9663 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9664 ;;
9665 ;; Since sh[lr]d does not change the `reg' operand, that is done
9666 ;; separately, making all shifts emit pairs of shift double and normal
9667 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9668 ;; support a 63 bit shift, each shift where the count is in a reg expands
9669 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9670 ;;
9671 ;; If the shift count is a constant, we need never emit more than one
9672 ;; shift pair, instead using moves and sign extension for counts greater
9673 ;; than 31.
9674
9675 (define_expand "ashlti3"
9676   [(set (match_operand:TI 0 "register_operand" "")
9677         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9678                    (match_operand:QI 2 "nonmemory_operand" "")))]
9679   "TARGET_64BIT"
9680   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9681
9682 (define_insn "*ashlti3_1"
9683   [(set (match_operand:TI 0 "register_operand" "=&r,r")
9684         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9685                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "TARGET_64BIT"
9688   "#"
9689   [(set_attr "type" "multi")])
9690
9691 (define_peephole2
9692   [(match_scratch:DI 3 "r")
9693    (parallel [(set (match_operand:TI 0 "register_operand" "")
9694                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9695                               (match_operand:QI 2 "nonmemory_operand" "")))
9696               (clobber (reg:CC FLAGS_REG))])
9697    (match_dup 3)]
9698   "TARGET_64BIT"
9699   [(const_int 0)]
9700   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9701
9702 (define_split
9703   [(set (match_operand:TI 0 "register_operand" "")
9704         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9705                    (match_operand:QI 2 "nonmemory_operand" "")))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9708                     ? epilogue_completed : reload_completed)"
9709   [(const_int 0)]
9710   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9711
9712 (define_insn "x86_64_shld"
9713   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9714         (ior:DI (ashift:DI (match_dup 0)
9715                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9716                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9717                   (minus:QI (const_int 64) (match_dup 2)))))
9718    (clobber (reg:CC FLAGS_REG))]
9719   "TARGET_64BIT"
9720   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9721   [(set_attr "type" "ishift")
9722    (set_attr "prefix_0f" "1")
9723    (set_attr "mode" "DI")
9724    (set_attr "athlon_decode" "vector")
9725    (set_attr "amdfam10_decode" "vector")])
9726
9727 (define_expand "x86_64_shift_adj_1"
9728   [(set (reg:CCZ FLAGS_REG)
9729         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9730                              (const_int 64))
9731                      (const_int 0)))
9732    (set (match_operand:DI 0 "register_operand" "")
9733         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9734                          (match_operand:DI 1 "register_operand" "")
9735                          (match_dup 0)))
9736    (set (match_dup 1)
9737         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9738                          (match_operand:DI 3 "register_operand" "r")
9739                          (match_dup 1)))]
9740   "TARGET_64BIT"
9741   "")
9742
9743 (define_expand "x86_64_shift_adj_2"
9744   [(use (match_operand:DI 0 "register_operand" ""))
9745    (use (match_operand:DI 1 "register_operand" ""))
9746    (use (match_operand:QI 2 "register_operand" ""))]
9747   "TARGET_64BIT"
9748 {
9749   rtx label = gen_label_rtx ();
9750   rtx tmp;
9751
9752   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9753
9754   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9755   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9756   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9757                               gen_rtx_LABEL_REF (VOIDmode, label),
9758                               pc_rtx);
9759   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9760   JUMP_LABEL (tmp) = label;
9761
9762   emit_move_insn (operands[0], operands[1]);
9763   ix86_expand_clear (operands[1]);
9764
9765   emit_label (label);
9766   LABEL_NUSES (label) = 1;
9767
9768   DONE;
9769 })
9770
9771 (define_expand "ashldi3"
9772   [(set (match_operand:DI 0 "shiftdi_operand" "")
9773         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9774                    (match_operand:QI 2 "nonmemory_operand" "")))]
9775   ""
9776   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9777
9778 (define_insn "*ashldi3_1_rex64"
9779   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9780         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9781                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9784 {
9785   switch (get_attr_type (insn))
9786     {
9787     case TYPE_ALU:
9788       gcc_assert (operands[2] == const1_rtx);
9789       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9790       return "add{q}\t%0, %0";
9791
9792     case TYPE_LEA:
9793       gcc_assert (CONST_INT_P (operands[2]));
9794       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9795       operands[1] = gen_rtx_MULT (DImode, operands[1],
9796                                   GEN_INT (1 << INTVAL (operands[2])));
9797       return "lea{q}\t{%a1, %0|%0, %a1}";
9798
9799     default:
9800       if (REG_P (operands[2]))
9801         return "sal{q}\t{%b2, %0|%0, %b2}";
9802       else if (operands[2] == const1_rtx
9803                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9804         return "sal{q}\t%0";
9805       else
9806         return "sal{q}\t{%2, %0|%0, %2}";
9807     }
9808 }
9809   [(set (attr "type")
9810      (cond [(eq_attr "alternative" "1")
9811               (const_string "lea")
9812             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9813                           (const_int 0))
9814                       (match_operand 0 "register_operand" ""))
9815                  (match_operand 2 "const1_operand" ""))
9816               (const_string "alu")
9817            ]
9818            (const_string "ishift")))
9819    (set (attr "length_immediate")
9820      (if_then_else
9821        (ior (eq_attr "type" "alu")
9822             (and (eq_attr "type" "ishift")
9823                  (and (match_operand 2 "const1_operand" "")
9824                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9825                           (const_int 0)))))
9826        (const_string "0")
9827        (const_string "*")))
9828    (set_attr "mode" "DI")])
9829
9830 ;; Convert lea to the lea pattern to avoid flags dependency.
9831 (define_split
9832   [(set (match_operand:DI 0 "register_operand" "")
9833         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9834                    (match_operand:QI 2 "immediate_operand" "")))
9835    (clobber (reg:CC FLAGS_REG))]
9836   "TARGET_64BIT && reload_completed
9837    && true_regnum (operands[0]) != true_regnum (operands[1])"
9838   [(set (match_dup 0)
9839         (mult:DI (match_dup 1)
9840                  (match_dup 2)))]
9841   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9842
9843 ;; This pattern can't accept a variable shift count, since shifts by
9844 ;; zero don't affect the flags.  We assume that shifts by constant
9845 ;; zero are optimized away.
9846 (define_insn "*ashldi3_cmp_rex64"
9847   [(set (reg FLAGS_REG)
9848         (compare
9849           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9850                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9851           (const_int 0)))
9852    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9853         (ashift:DI (match_dup 1) (match_dup 2)))]
9854   "TARGET_64BIT
9855    && (optimize_function_for_size_p (cfun)
9856        || !TARGET_PARTIAL_FLAG_REG_STALL
9857        || (operands[2] == const1_rtx
9858            && (TARGET_SHIFT1
9859                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9860    && ix86_match_ccmode (insn, CCGOCmode)
9861    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9862 {
9863   switch (get_attr_type (insn))
9864     {
9865     case TYPE_ALU:
9866       gcc_assert (operands[2] == const1_rtx);
9867       return "add{q}\t%0, %0";
9868
9869     default:
9870       if (REG_P (operands[2]))
9871         return "sal{q}\t{%b2, %0|%0, %b2}";
9872       else if (operands[2] == const1_rtx
9873                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874         return "sal{q}\t%0";
9875       else
9876         return "sal{q}\t{%2, %0|%0, %2}";
9877     }
9878 }
9879   [(set (attr "type")
9880      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9881                           (const_int 0))
9882                       (match_operand 0 "register_operand" ""))
9883                  (match_operand 2 "const1_operand" ""))
9884               (const_string "alu")
9885            ]
9886            (const_string "ishift")))
9887    (set (attr "length_immediate")
9888      (if_then_else
9889        (ior (eq_attr "type" "alu")
9890             (and (eq_attr "type" "ishift")
9891                  (and (match_operand 2 "const1_operand" "")
9892                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9893                           (const_int 0)))))
9894        (const_string "0")
9895        (const_string "*")))
9896    (set_attr "mode" "DI")])
9897
9898 (define_insn "*ashldi3_cconly_rex64"
9899   [(set (reg FLAGS_REG)
9900         (compare
9901           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9902                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9903           (const_int 0)))
9904    (clobber (match_scratch:DI 0 "=r"))]
9905   "TARGET_64BIT
9906    && (optimize_function_for_size_p (cfun)
9907        || !TARGET_PARTIAL_FLAG_REG_STALL
9908        || (operands[2] == const1_rtx
9909            && (TARGET_SHIFT1
9910                || TARGET_DOUBLE_WITH_ADD)))
9911    && ix86_match_ccmode (insn, CCGOCmode)
9912    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9913 {
9914   switch (get_attr_type (insn))
9915     {
9916     case TYPE_ALU:
9917       gcc_assert (operands[2] == const1_rtx);
9918       return "add{q}\t%0, %0";
9919
9920     default:
9921       if (REG_P (operands[2]))
9922         return "sal{q}\t{%b2, %0|%0, %b2}";
9923       else if (operands[2] == const1_rtx
9924                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925         return "sal{q}\t%0";
9926       else
9927         return "sal{q}\t{%2, %0|%0, %2}";
9928     }
9929 }
9930   [(set (attr "type")
9931      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9932                           (const_int 0))
9933                       (match_operand 0 "register_operand" ""))
9934                  (match_operand 2 "const1_operand" ""))
9935               (const_string "alu")
9936            ]
9937            (const_string "ishift")))
9938    (set (attr "length_immediate")
9939      (if_then_else
9940        (ior (eq_attr "type" "alu")
9941             (and (eq_attr "type" "ishift")
9942                  (and (match_operand 2 "const1_operand" "")
9943                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9944                           (const_int 0)))))
9945        (const_string "0")
9946        (const_string "*")))
9947    (set_attr "mode" "DI")])
9948
9949 (define_insn "*ashldi3_1"
9950   [(set (match_operand:DI 0 "register_operand" "=&r,r")
9951         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9952                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9953    (clobber (reg:CC FLAGS_REG))]
9954   "!TARGET_64BIT"
9955   "#"
9956   [(set_attr "type" "multi")])
9957
9958 ;; By default we don't ask for a scratch register, because when DImode
9959 ;; values are manipulated, registers are already at a premium.  But if
9960 ;; we have one handy, we won't turn it away.
9961 (define_peephole2
9962   [(match_scratch:SI 3 "r")
9963    (parallel [(set (match_operand:DI 0 "register_operand" "")
9964                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9965                               (match_operand:QI 2 "nonmemory_operand" "")))
9966               (clobber (reg:CC FLAGS_REG))])
9967    (match_dup 3)]
9968   "!TARGET_64BIT && TARGET_CMOVE"
9969   [(const_int 0)]
9970   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9971
9972 (define_split
9973   [(set (match_operand:DI 0 "register_operand" "")
9974         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9975                    (match_operand:QI 2 "nonmemory_operand" "")))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9978                      ? epilogue_completed : reload_completed)"
9979   [(const_int 0)]
9980   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9981
9982 (define_insn "x86_shld"
9983   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9984         (ior:SI (ashift:SI (match_dup 0)
9985                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9986                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9987                   (minus:QI (const_int 32) (match_dup 2)))))
9988    (clobber (reg:CC FLAGS_REG))]
9989   ""
9990   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9991   [(set_attr "type" "ishift")
9992    (set_attr "prefix_0f" "1")
9993    (set_attr "mode" "SI")
9994    (set_attr "pent_pair" "np")
9995    (set_attr "athlon_decode" "vector")
9996    (set_attr "amdfam10_decode" "vector")])
9997
9998 (define_expand "x86_shift_adj_1"
9999   [(set (reg:CCZ FLAGS_REG)
10000         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10001                              (const_int 32))
10002                      (const_int 0)))
10003    (set (match_operand:SI 0 "register_operand" "")
10004         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10005                          (match_operand:SI 1 "register_operand" "")
10006                          (match_dup 0)))
10007    (set (match_dup 1)
10008         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10009                          (match_operand:SI 3 "register_operand" "r")
10010                          (match_dup 1)))]
10011   "TARGET_CMOVE"
10012   "")
10013
10014 (define_expand "x86_shift_adj_2"
10015   [(use (match_operand:SI 0 "register_operand" ""))
10016    (use (match_operand:SI 1 "register_operand" ""))
10017    (use (match_operand:QI 2 "register_operand" ""))]
10018   ""
10019 {
10020   rtx label = gen_label_rtx ();
10021   rtx tmp;
10022
10023   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10024
10025   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10026   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10027   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10028                               gen_rtx_LABEL_REF (VOIDmode, label),
10029                               pc_rtx);
10030   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10031   JUMP_LABEL (tmp) = label;
10032
10033   emit_move_insn (operands[0], operands[1]);
10034   ix86_expand_clear (operands[1]);
10035
10036   emit_label (label);
10037   LABEL_NUSES (label) = 1;
10038
10039   DONE;
10040 })
10041
10042 (define_expand "ashlsi3"
10043   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10044         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10045                    (match_operand:QI 2 "nonmemory_operand" "")))]
10046   ""
10047   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10048
10049 (define_insn "*ashlsi3_1"
10050   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10051         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10052                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10053    (clobber (reg:CC FLAGS_REG))]
10054   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10055 {
10056   switch (get_attr_type (insn))
10057     {
10058     case TYPE_ALU:
10059       gcc_assert (operands[2] == const1_rtx);
10060       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10061       return "add{l}\t%0, %0";
10062
10063     case TYPE_LEA:
10064       return "#";
10065
10066     default:
10067       if (REG_P (operands[2]))
10068         return "sal{l}\t{%b2, %0|%0, %b2}";
10069       else if (operands[2] == const1_rtx
10070                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10071         return "sal{l}\t%0";
10072       else
10073         return "sal{l}\t{%2, %0|%0, %2}";
10074     }
10075 }
10076   [(set (attr "type")
10077      (cond [(eq_attr "alternative" "1")
10078               (const_string "lea")
10079             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10080                           (const_int 0))
10081                       (match_operand 0 "register_operand" ""))
10082                  (match_operand 2 "const1_operand" ""))
10083               (const_string "alu")
10084            ]
10085            (const_string "ishift")))
10086    (set (attr "length_immediate")
10087      (if_then_else
10088        (ior (eq_attr "type" "alu")
10089             (and (eq_attr "type" "ishift")
10090                  (and (match_operand 2 "const1_operand" "")
10091                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10092                           (const_int 0)))))
10093        (const_string "0")
10094        (const_string "*")))
10095    (set_attr "mode" "SI")])
10096
10097 ;; Convert lea to the lea pattern to avoid flags dependency.
10098 (define_split
10099   [(set (match_operand 0 "register_operand" "")
10100         (ashift (match_operand 1 "index_register_operand" "")
10101                 (match_operand:QI 2 "const_int_operand" "")))
10102    (clobber (reg:CC FLAGS_REG))]
10103   "reload_completed
10104    && true_regnum (operands[0]) != true_regnum (operands[1])
10105    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10106   [(const_int 0)]
10107 {
10108   rtx pat;
10109   enum machine_mode mode = GET_MODE (operands[0]);
10110
10111   if (GET_MODE_SIZE (mode) < 4)
10112     operands[0] = gen_lowpart (SImode, operands[0]);
10113   if (mode != Pmode)
10114     operands[1] = gen_lowpart (Pmode, operands[1]);
10115   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10116
10117   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10118   if (Pmode != SImode)
10119     pat = gen_rtx_SUBREG (SImode, pat, 0);
10120   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10121   DONE;
10122 })
10123
10124 ;; Rare case of shifting RSP is handled by generating move and shift
10125 (define_split
10126   [(set (match_operand 0 "register_operand" "")
10127         (ashift (match_operand 1 "register_operand" "")
10128                 (match_operand:QI 2 "const_int_operand" "")))
10129    (clobber (reg:CC FLAGS_REG))]
10130   "reload_completed
10131    && true_regnum (operands[0]) != true_regnum (operands[1])"
10132   [(const_int 0)]
10133 {
10134   rtx pat, clob;
10135   emit_move_insn (operands[0], operands[1]);
10136   pat = gen_rtx_SET (VOIDmode, operands[0],
10137                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10138                                      operands[0], operands[2]));
10139   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10140   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10141   DONE;
10142 })
10143
10144 (define_insn "*ashlsi3_1_zext"
10145   [(set (match_operand:DI 0 "register_operand" "=r,r")
10146         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10147                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10148    (clobber (reg:CC FLAGS_REG))]
10149   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10150 {
10151   switch (get_attr_type (insn))
10152     {
10153     case TYPE_ALU:
10154       gcc_assert (operands[2] == const1_rtx);
10155       return "add{l}\t%k0, %k0";
10156
10157     case TYPE_LEA:
10158       return "#";
10159
10160     default:
10161       if (REG_P (operands[2]))
10162         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10163       else if (operands[2] == const1_rtx
10164                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165         return "sal{l}\t%k0";
10166       else
10167         return "sal{l}\t{%2, %k0|%k0, %2}";
10168     }
10169 }
10170   [(set (attr "type")
10171      (cond [(eq_attr "alternative" "1")
10172               (const_string "lea")
10173             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10174                      (const_int 0))
10175                  (match_operand 2 "const1_operand" ""))
10176               (const_string "alu")
10177            ]
10178            (const_string "ishift")))
10179    (set (attr "length_immediate")
10180      (if_then_else
10181        (ior (eq_attr "type" "alu")
10182             (and (eq_attr "type" "ishift")
10183                  (and (match_operand 2 "const1_operand" "")
10184                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10185                           (const_int 0)))))
10186        (const_string "0")
10187        (const_string "*")))
10188    (set_attr "mode" "SI")])
10189
10190 ;; Convert lea to the lea pattern to avoid flags dependency.
10191 (define_split
10192   [(set (match_operand:DI 0 "register_operand" "")
10193         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10194                                 (match_operand:QI 2 "const_int_operand" ""))))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "TARGET_64BIT && reload_completed
10197    && true_regnum (operands[0]) != true_regnum (operands[1])"
10198   [(set (match_dup 0) (zero_extend:DI
10199                         (subreg:SI (mult:SI (match_dup 1)
10200                                             (match_dup 2)) 0)))]
10201 {
10202   operands[1] = gen_lowpart (Pmode, operands[1]);
10203   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10204 })
10205
10206 ;; This pattern can't accept a variable shift count, since shifts by
10207 ;; zero don't affect the flags.  We assume that shifts by constant
10208 ;; zero are optimized away.
10209 (define_insn "*ashlsi3_cmp"
10210   [(set (reg FLAGS_REG)
10211         (compare
10212           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10213                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10214           (const_int 0)))
10215    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10216         (ashift:SI (match_dup 1) (match_dup 2)))]
10217    "(optimize_function_for_size_p (cfun)
10218      || !TARGET_PARTIAL_FLAG_REG_STALL
10219      || (operands[2] == const1_rtx
10220          && (TARGET_SHIFT1
10221              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10222    && ix86_match_ccmode (insn, CCGOCmode)
10223    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10224 {
10225   switch (get_attr_type (insn))
10226     {
10227     case TYPE_ALU:
10228       gcc_assert (operands[2] == const1_rtx);
10229       return "add{l}\t%0, %0";
10230
10231     default:
10232       if (REG_P (operands[2]))
10233         return "sal{l}\t{%b2, %0|%0, %b2}";
10234       else if (operands[2] == const1_rtx
10235                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10236         return "sal{l}\t%0";
10237       else
10238         return "sal{l}\t{%2, %0|%0, %2}";
10239     }
10240 }
10241   [(set (attr "type")
10242      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10243                           (const_int 0))
10244                       (match_operand 0 "register_operand" ""))
10245                  (match_operand 2 "const1_operand" ""))
10246               (const_string "alu")
10247            ]
10248            (const_string "ishift")))
10249    (set (attr "length_immediate")
10250      (if_then_else
10251        (ior (eq_attr "type" "alu")
10252             (and (eq_attr "type" "ishift")
10253                  (and (match_operand 2 "const1_operand" "")
10254                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10255                           (const_int 0)))))
10256        (const_string "0")
10257        (const_string "*")))
10258    (set_attr "mode" "SI")])
10259
10260 (define_insn "*ashlsi3_cconly"
10261   [(set (reg FLAGS_REG)
10262         (compare
10263           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10264                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10265           (const_int 0)))
10266    (clobber (match_scratch:SI 0 "=r"))]
10267   "(optimize_function_for_size_p (cfun)
10268     || !TARGET_PARTIAL_FLAG_REG_STALL
10269     || (operands[2] == const1_rtx
10270         && (TARGET_SHIFT1
10271             || TARGET_DOUBLE_WITH_ADD)))
10272    && ix86_match_ccmode (insn, CCGOCmode)
10273    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10274 {
10275   switch (get_attr_type (insn))
10276     {
10277     case TYPE_ALU:
10278       gcc_assert (operands[2] == const1_rtx);
10279       return "add{l}\t%0, %0";
10280
10281     default:
10282       if (REG_P (operands[2]))
10283         return "sal{l}\t{%b2, %0|%0, %b2}";
10284       else if (operands[2] == const1_rtx
10285                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10286         return "sal{l}\t%0";
10287       else
10288         return "sal{l}\t{%2, %0|%0, %2}";
10289     }
10290 }
10291   [(set (attr "type")
10292      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10293                           (const_int 0))
10294                       (match_operand 0 "register_operand" ""))
10295                  (match_operand 2 "const1_operand" ""))
10296               (const_string "alu")
10297            ]
10298            (const_string "ishift")))
10299    (set (attr "length_immediate")
10300      (if_then_else
10301        (ior (eq_attr "type" "alu")
10302             (and (eq_attr "type" "ishift")
10303                  (and (match_operand 2 "const1_operand" "")
10304                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10305                           (const_int 0)))))
10306        (const_string "0")
10307        (const_string "*")))
10308    (set_attr "mode" "SI")])
10309
10310 (define_insn "*ashlsi3_cmp_zext"
10311   [(set (reg FLAGS_REG)
10312         (compare
10313           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10314                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10315           (const_int 0)))
10316    (set (match_operand:DI 0 "register_operand" "=r")
10317         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10318   "TARGET_64BIT
10319    && (optimize_function_for_size_p (cfun)
10320        || !TARGET_PARTIAL_FLAG_REG_STALL
10321        || (operands[2] == const1_rtx
10322            && (TARGET_SHIFT1
10323                || TARGET_DOUBLE_WITH_ADD)))
10324    && ix86_match_ccmode (insn, CCGOCmode)
10325    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10326 {
10327   switch (get_attr_type (insn))
10328     {
10329     case TYPE_ALU:
10330       gcc_assert (operands[2] == const1_rtx);
10331       return "add{l}\t%k0, %k0";
10332
10333     default:
10334       if (REG_P (operands[2]))
10335         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10336       else if (operands[2] == const1_rtx
10337                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10338         return "sal{l}\t%k0";
10339       else
10340         return "sal{l}\t{%2, %k0|%k0, %2}";
10341     }
10342 }
10343   [(set (attr "type")
10344      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10345                      (const_int 0))
10346                  (match_operand 2 "const1_operand" ""))
10347               (const_string "alu")
10348            ]
10349            (const_string "ishift")))
10350    (set (attr "length_immediate")
10351      (if_then_else
10352        (ior (eq_attr "type" "alu")
10353             (and (eq_attr "type" "ishift")
10354                  (and (match_operand 2 "const1_operand" "")
10355                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10356                           (const_int 0)))))
10357        (const_string "0")
10358        (const_string "*")))
10359    (set_attr "mode" "SI")])
10360
10361 (define_expand "ashlhi3"
10362   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10363         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10364                    (match_operand:QI 2 "nonmemory_operand" "")))]
10365   "TARGET_HIMODE_MATH"
10366   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10367
10368 (define_insn "*ashlhi3_1_lea"
10369   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10370         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10371                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10372    (clobber (reg:CC FLAGS_REG))]
10373   "!TARGET_PARTIAL_REG_STALL
10374    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10375 {
10376   switch (get_attr_type (insn))
10377     {
10378     case TYPE_LEA:
10379       return "#";
10380     case TYPE_ALU:
10381       gcc_assert (operands[2] == const1_rtx);
10382       return "add{w}\t%0, %0";
10383
10384     default:
10385       if (REG_P (operands[2]))
10386         return "sal{w}\t{%b2, %0|%0, %b2}";
10387       else if (operands[2] == const1_rtx
10388                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10389         return "sal{w}\t%0";
10390       else
10391         return "sal{w}\t{%2, %0|%0, %2}";
10392     }
10393 }
10394   [(set (attr "type")
10395      (cond [(eq_attr "alternative" "1")
10396               (const_string "lea")
10397             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10398                           (const_int 0))
10399                       (match_operand 0 "register_operand" ""))
10400                  (match_operand 2 "const1_operand" ""))
10401               (const_string "alu")
10402            ]
10403            (const_string "ishift")))
10404    (set (attr "length_immediate")
10405      (if_then_else
10406        (ior (eq_attr "type" "alu")
10407             (and (eq_attr "type" "ishift")
10408                  (and (match_operand 2 "const1_operand" "")
10409                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10410                           (const_int 0)))))
10411        (const_string "0")
10412        (const_string "*")))
10413    (set_attr "mode" "HI,SI")])
10414
10415 (define_insn "*ashlhi3_1"
10416   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10417         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10418                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_PARTIAL_REG_STALL
10421    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10422 {
10423   switch (get_attr_type (insn))
10424     {
10425     case TYPE_ALU:
10426       gcc_assert (operands[2] == const1_rtx);
10427       return "add{w}\t%0, %0";
10428
10429     default:
10430       if (REG_P (operands[2]))
10431         return "sal{w}\t{%b2, %0|%0, %b2}";
10432       else if (operands[2] == const1_rtx
10433                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10434         return "sal{w}\t%0";
10435       else
10436         return "sal{w}\t{%2, %0|%0, %2}";
10437     }
10438 }
10439   [(set (attr "type")
10440      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10441                           (const_int 0))
10442                       (match_operand 0 "register_operand" ""))
10443                  (match_operand 2 "const1_operand" ""))
10444               (const_string "alu")
10445            ]
10446            (const_string "ishift")))
10447    (set (attr "length_immediate")
10448      (if_then_else
10449        (ior (eq_attr "type" "alu")
10450             (and (eq_attr "type" "ishift")
10451                  (and (match_operand 2 "const1_operand" "")
10452                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10453                           (const_int 0)))))
10454        (const_string "0")
10455        (const_string "*")))
10456    (set_attr "mode" "HI")])
10457
10458 ;; This pattern can't accept a variable shift count, since shifts by
10459 ;; zero don't affect the flags.  We assume that shifts by constant
10460 ;; zero are optimized away.
10461 (define_insn "*ashlhi3_cmp"
10462   [(set (reg FLAGS_REG)
10463         (compare
10464           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10465                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10466           (const_int 0)))
10467    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10468         (ashift:HI (match_dup 1) (match_dup 2)))]
10469   "(optimize_function_for_size_p (cfun)
10470     || !TARGET_PARTIAL_FLAG_REG_STALL
10471     || (operands[2] == const1_rtx
10472         && (TARGET_SHIFT1
10473             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10474    && ix86_match_ccmode (insn, CCGOCmode)
10475    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10476 {
10477   switch (get_attr_type (insn))
10478     {
10479     case TYPE_ALU:
10480       gcc_assert (operands[2] == const1_rtx);
10481       return "add{w}\t%0, %0";
10482
10483     default:
10484       if (REG_P (operands[2]))
10485         return "sal{w}\t{%b2, %0|%0, %b2}";
10486       else if (operands[2] == const1_rtx
10487                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10488         return "sal{w}\t%0";
10489       else
10490         return "sal{w}\t{%2, %0|%0, %2}";
10491     }
10492 }
10493   [(set (attr "type")
10494      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10495                           (const_int 0))
10496                       (match_operand 0 "register_operand" ""))
10497                  (match_operand 2 "const1_operand" ""))
10498               (const_string "alu")
10499            ]
10500            (const_string "ishift")))
10501    (set (attr "length_immediate")
10502      (if_then_else
10503        (ior (eq_attr "type" "alu")
10504             (and (eq_attr "type" "ishift")
10505                  (and (match_operand 2 "const1_operand" "")
10506                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10507                           (const_int 0)))))
10508        (const_string "0")
10509        (const_string "*")))
10510    (set_attr "mode" "HI")])
10511
10512 (define_insn "*ashlhi3_cconly"
10513   [(set (reg FLAGS_REG)
10514         (compare
10515           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10516                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10517           (const_int 0)))
10518    (clobber (match_scratch:HI 0 "=r"))]
10519   "(optimize_function_for_size_p (cfun)
10520     || !TARGET_PARTIAL_FLAG_REG_STALL
10521     || (operands[2] == const1_rtx
10522         && (TARGET_SHIFT1
10523             || TARGET_DOUBLE_WITH_ADD)))
10524    && ix86_match_ccmode (insn, CCGOCmode)
10525    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10526 {
10527   switch (get_attr_type (insn))
10528     {
10529     case TYPE_ALU:
10530       gcc_assert (operands[2] == const1_rtx);
10531       return "add{w}\t%0, %0";
10532
10533     default:
10534       if (REG_P (operands[2]))
10535         return "sal{w}\t{%b2, %0|%0, %b2}";
10536       else if (operands[2] == const1_rtx
10537                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10538         return "sal{w}\t%0";
10539       else
10540         return "sal{w}\t{%2, %0|%0, %2}";
10541     }
10542 }
10543   [(set (attr "type")
10544      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10545                           (const_int 0))
10546                       (match_operand 0 "register_operand" ""))
10547                  (match_operand 2 "const1_operand" ""))
10548               (const_string "alu")
10549            ]
10550            (const_string "ishift")))
10551    (set (attr "length_immediate")
10552      (if_then_else
10553        (ior (eq_attr "type" "alu")
10554             (and (eq_attr "type" "ishift")
10555                  (and (match_operand 2 "const1_operand" "")
10556                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10557                           (const_int 0)))))
10558        (const_string "0")
10559        (const_string "*")))
10560    (set_attr "mode" "HI")])
10561
10562 (define_expand "ashlqi3"
10563   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10564         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10565                    (match_operand:QI 2 "nonmemory_operand" "")))]
10566   "TARGET_QIMODE_MATH"
10567   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10568
10569 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10570
10571 (define_insn "*ashlqi3_1_lea"
10572   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10573         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10574                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10575    (clobber (reg:CC FLAGS_REG))]
10576   "!TARGET_PARTIAL_REG_STALL
10577    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10578 {
10579   switch (get_attr_type (insn))
10580     {
10581     case TYPE_LEA:
10582       return "#";
10583     case TYPE_ALU:
10584       gcc_assert (operands[2] == const1_rtx);
10585       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10586         return "add{l}\t%k0, %k0";
10587       else
10588         return "add{b}\t%0, %0";
10589
10590     default:
10591       if (REG_P (operands[2]))
10592         {
10593           if (get_attr_mode (insn) == MODE_SI)
10594             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10595           else
10596             return "sal{b}\t{%b2, %0|%0, %b2}";
10597         }
10598       else if (operands[2] == const1_rtx
10599                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10600         {
10601           if (get_attr_mode (insn) == MODE_SI)
10602             return "sal{l}\t%0";
10603           else
10604             return "sal{b}\t%0";
10605         }
10606       else
10607         {
10608           if (get_attr_mode (insn) == MODE_SI)
10609             return "sal{l}\t{%2, %k0|%k0, %2}";
10610           else
10611             return "sal{b}\t{%2, %0|%0, %2}";
10612         }
10613     }
10614 }
10615   [(set (attr "type")
10616      (cond [(eq_attr "alternative" "2")
10617               (const_string "lea")
10618             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10619                           (const_int 0))
10620                       (match_operand 0 "register_operand" ""))
10621                  (match_operand 2 "const1_operand" ""))
10622               (const_string "alu")
10623            ]
10624            (const_string "ishift")))
10625    (set (attr "length_immediate")
10626      (if_then_else
10627        (ior (eq_attr "type" "alu")
10628             (and (eq_attr "type" "ishift")
10629                  (and (match_operand 2 "const1_operand" "")
10630                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10631                           (const_int 0)))))
10632        (const_string "0")
10633        (const_string "*")))
10634    (set_attr "mode" "QI,SI,SI")])
10635
10636 (define_insn "*ashlqi3_1"
10637   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10638         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10639                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10640    (clobber (reg:CC FLAGS_REG))]
10641   "TARGET_PARTIAL_REG_STALL
10642    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10643 {
10644   switch (get_attr_type (insn))
10645     {
10646     case TYPE_ALU:
10647       gcc_assert (operands[2] == const1_rtx);
10648       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10649         return "add{l}\t%k0, %k0";
10650       else
10651         return "add{b}\t%0, %0";
10652
10653     default:
10654       if (REG_P (operands[2]))
10655         {
10656           if (get_attr_mode (insn) == MODE_SI)
10657             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10658           else
10659             return "sal{b}\t{%b2, %0|%0, %b2}";
10660         }
10661       else if (operands[2] == const1_rtx
10662                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10663         {
10664           if (get_attr_mode (insn) == MODE_SI)
10665             return "sal{l}\t%0";
10666           else
10667             return "sal{b}\t%0";
10668         }
10669       else
10670         {
10671           if (get_attr_mode (insn) == MODE_SI)
10672             return "sal{l}\t{%2, %k0|%k0, %2}";
10673           else
10674             return "sal{b}\t{%2, %0|%0, %2}";
10675         }
10676     }
10677 }
10678   [(set (attr "type")
10679      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10680                           (const_int 0))
10681                       (match_operand 0 "register_operand" ""))
10682                  (match_operand 2 "const1_operand" ""))
10683               (const_string "alu")
10684            ]
10685            (const_string "ishift")))
10686    (set (attr "length_immediate")
10687      (if_then_else
10688        (ior (eq_attr "type" "alu")
10689             (and (eq_attr "type" "ishift")
10690                  (and (match_operand 2 "const1_operand" "")
10691                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10692                           (const_int 0)))))
10693        (const_string "0")
10694        (const_string "*")))
10695    (set_attr "mode" "QI,SI")])
10696
10697 ;; This pattern can't accept a variable shift count, since shifts by
10698 ;; zero don't affect the flags.  We assume that shifts by constant
10699 ;; zero are optimized away.
10700 (define_insn "*ashlqi3_cmp"
10701   [(set (reg FLAGS_REG)
10702         (compare
10703           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10704                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10705           (const_int 0)))
10706    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10707         (ashift:QI (match_dup 1) (match_dup 2)))]
10708   "(optimize_function_for_size_p (cfun)
10709     || !TARGET_PARTIAL_FLAG_REG_STALL
10710     || (operands[2] == const1_rtx
10711         && (TARGET_SHIFT1
10712             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10713    && ix86_match_ccmode (insn, CCGOCmode)
10714    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10715 {
10716   switch (get_attr_type (insn))
10717     {
10718     case TYPE_ALU:
10719       gcc_assert (operands[2] == const1_rtx);
10720       return "add{b}\t%0, %0";
10721
10722     default:
10723       if (REG_P (operands[2]))
10724         return "sal{b}\t{%b2, %0|%0, %b2}";
10725       else if (operands[2] == const1_rtx
10726                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10727         return "sal{b}\t%0";
10728       else
10729         return "sal{b}\t{%2, %0|%0, %2}";
10730     }
10731 }
10732   [(set (attr "type")
10733      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10734                           (const_int 0))
10735                       (match_operand 0 "register_operand" ""))
10736                  (match_operand 2 "const1_operand" ""))
10737               (const_string "alu")
10738            ]
10739            (const_string "ishift")))
10740    (set (attr "length_immediate")
10741      (if_then_else
10742        (ior (eq_attr "type" "alu")
10743             (and (eq_attr "type" "ishift")
10744                  (and (match_operand 2 "const1_operand" "")
10745                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10746                           (const_int 0)))))
10747        (const_string "0")
10748        (const_string "*")))
10749    (set_attr "mode" "QI")])
10750
10751 (define_insn "*ashlqi3_cconly"
10752   [(set (reg FLAGS_REG)
10753         (compare
10754           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10755                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10756           (const_int 0)))
10757    (clobber (match_scratch:QI 0 "=q"))]
10758   "(optimize_function_for_size_p (cfun)
10759     || !TARGET_PARTIAL_FLAG_REG_STALL
10760     || (operands[2] == const1_rtx
10761         && (TARGET_SHIFT1
10762             || TARGET_DOUBLE_WITH_ADD)))
10763    && ix86_match_ccmode (insn, CCGOCmode)
10764    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10765 {
10766   switch (get_attr_type (insn))
10767     {
10768     case TYPE_ALU:
10769       gcc_assert (operands[2] == const1_rtx);
10770       return "add{b}\t%0, %0";
10771
10772     default:
10773       if (REG_P (operands[2]))
10774         return "sal{b}\t{%b2, %0|%0, %b2}";
10775       else if (operands[2] == const1_rtx
10776                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10777         return "sal{b}\t%0";
10778       else
10779         return "sal{b}\t{%2, %0|%0, %2}";
10780     }
10781 }
10782   [(set (attr "type")
10783      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10784                           (const_int 0))
10785                       (match_operand 0 "register_operand" ""))
10786                  (match_operand 2 "const1_operand" ""))
10787               (const_string "alu")
10788            ]
10789            (const_string "ishift")))
10790    (set (attr "length_immediate")
10791      (if_then_else
10792        (ior (eq_attr "type" "alu")
10793             (and (eq_attr "type" "ishift")
10794                  (and (match_operand 2 "const1_operand" "")
10795                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10796                           (const_int 0)))))
10797        (const_string "0")
10798        (const_string "*")))
10799    (set_attr "mode" "QI")])
10800
10801 ;; See comment above `ashldi3' about how this works.
10802
10803 (define_expand "ashrti3"
10804   [(set (match_operand:TI 0 "register_operand" "")
10805         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10806                      (match_operand:QI 2 "nonmemory_operand" "")))]
10807   "TARGET_64BIT"
10808   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10809
10810 (define_insn "*ashrti3_1"
10811   [(set (match_operand:TI 0 "register_operand" "=r")
10812         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10813                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
10814    (clobber (reg:CC FLAGS_REG))]
10815   "TARGET_64BIT"
10816   "#"
10817   [(set_attr "type" "multi")])
10818
10819 (define_peephole2
10820   [(match_scratch:DI 3 "r")
10821    (parallel [(set (match_operand:TI 0 "register_operand" "")
10822                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10823                                 (match_operand:QI 2 "nonmemory_operand" "")))
10824               (clobber (reg:CC FLAGS_REG))])
10825    (match_dup 3)]
10826   "TARGET_64BIT"
10827   [(const_int 0)]
10828   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10829
10830 (define_split
10831   [(set (match_operand:TI 0 "register_operand" "")
10832         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10833                      (match_operand:QI 2 "nonmemory_operand" "")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10836                     ? epilogue_completed : reload_completed)"
10837   [(const_int 0)]
10838   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10839
10840 (define_insn "x86_64_shrd"
10841   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10842         (ior:DI (ashiftrt:DI (match_dup 0)
10843                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10844                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10845                   (minus:QI (const_int 64) (match_dup 2)))))
10846    (clobber (reg:CC FLAGS_REG))]
10847   "TARGET_64BIT"
10848   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10849   [(set_attr "type" "ishift")
10850    (set_attr "prefix_0f" "1")
10851    (set_attr "mode" "DI")
10852    (set_attr "athlon_decode" "vector")
10853    (set_attr "amdfam10_decode" "vector")])
10854
10855 (define_expand "ashrdi3"
10856   [(set (match_operand:DI 0 "shiftdi_operand" "")
10857         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10858                      (match_operand:QI 2 "nonmemory_operand" "")))]
10859   ""
10860   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10861
10862 (define_expand "x86_64_shift_adj_3"
10863   [(use (match_operand:DI 0 "register_operand" ""))
10864    (use (match_operand:DI 1 "register_operand" ""))
10865    (use (match_operand:QI 2 "register_operand" ""))]
10866   ""
10867 {
10868   rtx label = gen_label_rtx ();
10869   rtx tmp;
10870
10871   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10872
10873   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10874   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10875   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10876                               gen_rtx_LABEL_REF (VOIDmode, label),
10877                               pc_rtx);
10878   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10879   JUMP_LABEL (tmp) = label;
10880
10881   emit_move_insn (operands[0], operands[1]);
10882   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10883
10884   emit_label (label);
10885   LABEL_NUSES (label) = 1;
10886
10887   DONE;
10888 })
10889
10890 (define_insn "ashrdi3_63_rex64"
10891   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10892         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10893                      (match_operand:DI 2 "const_int_operand" "i,i")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_64BIT && INTVAL (operands[2]) == 63
10896    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10897    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10898   "@
10899    {cqto|cqo}
10900    sar{q}\t{%2, %0|%0, %2}"
10901   [(set_attr "type" "imovx,ishift")
10902    (set_attr "prefix_0f" "0,*")
10903    (set_attr "length_immediate" "0,*")
10904    (set_attr "modrm" "0,1")
10905    (set_attr "mode" "DI")])
10906
10907 (define_insn "*ashrdi3_1_one_bit_rex64"
10908   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10909         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10910                      (match_operand:QI 2 "const1_operand" "")))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "TARGET_64BIT
10913    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10914    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10915   "sar{q}\t%0"
10916   [(set_attr "type" "ishift")
10917    (set_attr "length_immediate" "0")
10918    (set_attr "mode" "DI")])
10919
10920 (define_insn "*ashrdi3_1_rex64"
10921   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10922         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10923                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10924    (clobber (reg:CC FLAGS_REG))]
10925   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10926   "@
10927    sar{q}\t{%2, %0|%0, %2}
10928    sar{q}\t{%b2, %0|%0, %b2}"
10929   [(set_attr "type" "ishift")
10930    (set_attr "mode" "DI")])
10931
10932 ;; This pattern can't accept a variable shift count, since shifts by
10933 ;; zero don't affect the flags.  We assume that shifts by constant
10934 ;; zero are optimized away.
10935 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10936   [(set (reg FLAGS_REG)
10937         (compare
10938           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10939                        (match_operand:QI 2 "const1_operand" ""))
10940           (const_int 0)))
10941    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10942         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10943   "TARGET_64BIT
10944    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10945    && ix86_match_ccmode (insn, CCGOCmode)
10946    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10947   "sar{q}\t%0"
10948   [(set_attr "type" "ishift")
10949    (set_attr "length_immediate" "0")
10950    (set_attr "mode" "DI")])
10951
10952 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10953   [(set (reg FLAGS_REG)
10954         (compare
10955           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10956                        (match_operand:QI 2 "const1_operand" ""))
10957           (const_int 0)))
10958    (clobber (match_scratch:DI 0 "=r"))]
10959   "TARGET_64BIT
10960    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10961    && ix86_match_ccmode (insn, CCGOCmode)
10962    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10963   "sar{q}\t%0"
10964   [(set_attr "type" "ishift")
10965    (set_attr "length_immediate" "0")
10966    (set_attr "mode" "DI")])
10967
10968 ;; This pattern can't accept a variable shift count, since shifts by
10969 ;; zero don't affect the flags.  We assume that shifts by constant
10970 ;; zero are optimized away.
10971 (define_insn "*ashrdi3_cmp_rex64"
10972   [(set (reg FLAGS_REG)
10973         (compare
10974           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10976           (const_int 0)))
10977    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979   "TARGET_64BIT
10980    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10981    && ix86_match_ccmode (insn, CCGOCmode)
10982    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10983   "sar{q}\t{%2, %0|%0, %2}"
10984   [(set_attr "type" "ishift")
10985    (set_attr "mode" "DI")])
10986
10987 (define_insn "*ashrdi3_cconly_rex64"
10988   [(set (reg FLAGS_REG)
10989         (compare
10990           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10991                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10992           (const_int 0)))
10993    (clobber (match_scratch:DI 0 "=r"))]
10994   "TARGET_64BIT
10995    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10996    && ix86_match_ccmode (insn, CCGOCmode)
10997    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10998   "sar{q}\t{%2, %0|%0, %2}"
10999   [(set_attr "type" "ishift")
11000    (set_attr "mode" "DI")])
11001
11002 (define_insn "*ashrdi3_1"
11003   [(set (match_operand:DI 0 "register_operand" "=r")
11004         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11005                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11006    (clobber (reg:CC FLAGS_REG))]
11007   "!TARGET_64BIT"
11008   "#"
11009   [(set_attr "type" "multi")])
11010
11011 ;; By default we don't ask for a scratch register, because when DImode
11012 ;; values are manipulated, registers are already at a premium.  But if
11013 ;; we have one handy, we won't turn it away.
11014 (define_peephole2
11015   [(match_scratch:SI 3 "r")
11016    (parallel [(set (match_operand:DI 0 "register_operand" "")
11017                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11018                                 (match_operand:QI 2 "nonmemory_operand" "")))
11019               (clobber (reg:CC FLAGS_REG))])
11020    (match_dup 3)]
11021   "!TARGET_64BIT && TARGET_CMOVE"
11022   [(const_int 0)]
11023   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11024
11025 (define_split
11026   [(set (match_operand:DI 0 "register_operand" "")
11027         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11028                      (match_operand:QI 2 "nonmemory_operand" "")))
11029    (clobber (reg:CC FLAGS_REG))]
11030   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11031                      ? epilogue_completed : reload_completed)"
11032   [(const_int 0)]
11033   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11034
11035 (define_insn "x86_shrd"
11036   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11037         (ior:SI (ashiftrt:SI (match_dup 0)
11038                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11039                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11040                   (minus:QI (const_int 32) (match_dup 2)))))
11041    (clobber (reg:CC FLAGS_REG))]
11042   ""
11043   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11044   [(set_attr "type" "ishift")
11045    (set_attr "prefix_0f" "1")
11046    (set_attr "pent_pair" "np")
11047    (set_attr "mode" "SI")])
11048
11049 (define_expand "x86_shift_adj_3"
11050   [(use (match_operand:SI 0 "register_operand" ""))
11051    (use (match_operand:SI 1 "register_operand" ""))
11052    (use (match_operand:QI 2 "register_operand" ""))]
11053   ""
11054 {
11055   rtx label = gen_label_rtx ();
11056   rtx tmp;
11057
11058   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11059
11060   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11061   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11062   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11063                               gen_rtx_LABEL_REF (VOIDmode, label),
11064                               pc_rtx);
11065   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11066   JUMP_LABEL (tmp) = label;
11067
11068   emit_move_insn (operands[0], operands[1]);
11069   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11070
11071   emit_label (label);
11072   LABEL_NUSES (label) = 1;
11073
11074   DONE;
11075 })
11076
11077 (define_expand "ashrsi3_31"
11078   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11079                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11080                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11081               (clobber (reg:CC FLAGS_REG))])]
11082   "")
11083
11084 (define_insn "*ashrsi3_31"
11085   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11086         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11087                      (match_operand:SI 2 "const_int_operand" "i,i")))
11088    (clobber (reg:CC FLAGS_REG))]
11089   "INTVAL (operands[2]) == 31
11090    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11092   "@
11093    {cltd|cdq}
11094    sar{l}\t{%2, %0|%0, %2}"
11095   [(set_attr "type" "imovx,ishift")
11096    (set_attr "prefix_0f" "0,*")
11097    (set_attr "length_immediate" "0,*")
11098    (set_attr "modrm" "0,1")
11099    (set_attr "mode" "SI")])
11100
11101 (define_insn "*ashrsi3_31_zext"
11102   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11103         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11104                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11107    && INTVAL (operands[2]) == 31
11108    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11109   "@
11110    {cltd|cdq}
11111    sar{l}\t{%2, %k0|%k0, %2}"
11112   [(set_attr "type" "imovx,ishift")
11113    (set_attr "prefix_0f" "0,*")
11114    (set_attr "length_immediate" "0,*")
11115    (set_attr "modrm" "0,1")
11116    (set_attr "mode" "SI")])
11117
11118 (define_expand "ashrsi3"
11119   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11120         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11121                      (match_operand:QI 2 "nonmemory_operand" "")))]
11122   ""
11123   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11124
11125 (define_insn "*ashrsi3_1_one_bit"
11126   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11127         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11128                      (match_operand:QI 2 "const1_operand" "")))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11131    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11132   "sar{l}\t%0"
11133   [(set_attr "type" "ishift")
11134    (set_attr "length_immediate" "0")
11135    (set_attr "mode" "SI")])
11136
11137 (define_insn "*ashrsi3_1_one_bit_zext"
11138   [(set (match_operand:DI 0 "register_operand" "=r")
11139         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11140                                      (match_operand:QI 2 "const1_operand" ""))))
11141    (clobber (reg:CC FLAGS_REG))]
11142   "TARGET_64BIT
11143    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11144    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145   "sar{l}\t%k0"
11146   [(set_attr "type" "ishift")
11147    (set_attr "length_immediate" "0")
11148    (set_attr "mode" "SI")])
11149
11150 (define_insn "*ashrsi3_1"
11151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11152         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11153                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11154    (clobber (reg:CC FLAGS_REG))]
11155   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11156   "@
11157    sar{l}\t{%2, %0|%0, %2}
11158    sar{l}\t{%b2, %0|%0, %b2}"
11159   [(set_attr "type" "ishift")
11160    (set_attr "mode" "SI")])
11161
11162 (define_insn "*ashrsi3_1_zext"
11163   [(set (match_operand:DI 0 "register_operand" "=r,r")
11164         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11165                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11168   "@
11169    sar{l}\t{%2, %k0|%k0, %2}
11170    sar{l}\t{%b2, %k0|%k0, %b2}"
11171   [(set_attr "type" "ishift")
11172    (set_attr "mode" "SI")])
11173
11174 ;; This pattern can't accept a variable shift count, since shifts by
11175 ;; zero don't affect the flags.  We assume that shifts by constant
11176 ;; zero are optimized away.
11177 (define_insn "*ashrsi3_one_bit_cmp"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11181                        (match_operand:QI 2 "const1_operand" ""))
11182           (const_int 0)))
11183    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11184         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11185   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11186    && ix86_match_ccmode (insn, CCGOCmode)
11187    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188   "sar{l}\t%0"
11189   [(set_attr "type" "ishift")
11190    (set_attr "length_immediate" "0")
11191    (set_attr "mode" "SI")])
11192
11193 (define_insn "*ashrsi3_one_bit_cconly"
11194   [(set (reg FLAGS_REG)
11195         (compare
11196           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11197                        (match_operand:QI 2 "const1_operand" ""))
11198           (const_int 0)))
11199    (clobber (match_scratch:SI 0 "=r"))]
11200   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11201    && ix86_match_ccmode (insn, CCGOCmode)
11202    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11203   "sar{l}\t%0"
11204   [(set_attr "type" "ishift")
11205    (set_attr "length_immediate" "0")
11206    (set_attr "mode" "SI")])
11207
11208 (define_insn "*ashrsi3_one_bit_cmp_zext"
11209   [(set (reg FLAGS_REG)
11210         (compare
11211           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11212                        (match_operand:QI 2 "const1_operand" ""))
11213           (const_int 0)))
11214    (set (match_operand:DI 0 "register_operand" "=r")
11215         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11216   "TARGET_64BIT
11217    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11218    && ix86_match_ccmode (insn, CCmode)
11219    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11220   "sar{l}\t%k0"
11221   [(set_attr "type" "ishift")
11222    (set_attr "length_immediate" "0")
11223    (set_attr "mode" "SI")])
11224
11225 ;; This pattern can't accept a variable shift count, since shifts by
11226 ;; zero don't affect the flags.  We assume that shifts by constant
11227 ;; zero are optimized away.
11228 (define_insn "*ashrsi3_cmp"
11229   [(set (reg FLAGS_REG)
11230         (compare
11231           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11232                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11233           (const_int 0)))
11234    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11235         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11236   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11237    && ix86_match_ccmode (insn, CCGOCmode)
11238    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11239   "sar{l}\t{%2, %0|%0, %2}"
11240   [(set_attr "type" "ishift")
11241    (set_attr "mode" "SI")])
11242
11243 (define_insn "*ashrsi3_cconly"
11244   [(set (reg FLAGS_REG)
11245         (compare
11246           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11247                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11248           (const_int 0)))
11249    (clobber (match_scratch:SI 0 "=r"))]
11250   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11251    && ix86_match_ccmode (insn, CCGOCmode)
11252    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11253   "sar{l}\t{%2, %0|%0, %2}"
11254   [(set_attr "type" "ishift")
11255    (set_attr "mode" "SI")])
11256
11257 (define_insn "*ashrsi3_cmp_zext"
11258   [(set (reg FLAGS_REG)
11259         (compare
11260           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11261                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11262           (const_int 0)))
11263    (set (match_operand:DI 0 "register_operand" "=r")
11264         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11265   "TARGET_64BIT
11266    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11267    && ix86_match_ccmode (insn, CCGOCmode)
11268    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11269   "sar{l}\t{%2, %k0|%k0, %2}"
11270   [(set_attr "type" "ishift")
11271    (set_attr "mode" "SI")])
11272
11273 (define_expand "ashrhi3"
11274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11275         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11276                      (match_operand:QI 2 "nonmemory_operand" "")))]
11277   "TARGET_HIMODE_MATH"
11278   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11279
11280 (define_insn "*ashrhi3_1_one_bit"
11281   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11282         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11283                      (match_operand:QI 2 "const1_operand" "")))
11284    (clobber (reg:CC FLAGS_REG))]
11285   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11286    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11287   "sar{w}\t%0"
11288   [(set_attr "type" "ishift")
11289    (set_attr "length_immediate" "0")
11290    (set_attr "mode" "HI")])
11291
11292 (define_insn "*ashrhi3_1"
11293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11294         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11295                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11298   "@
11299    sar{w}\t{%2, %0|%0, %2}
11300    sar{w}\t{%b2, %0|%0, %b2}"
11301   [(set_attr "type" "ishift")
11302    (set_attr "mode" "HI")])
11303
11304 ;; This pattern can't accept a variable shift count, since shifts by
11305 ;; zero don't affect the flags.  We assume that shifts by constant
11306 ;; zero are optimized away.
11307 (define_insn "*ashrhi3_one_bit_cmp"
11308   [(set (reg FLAGS_REG)
11309         (compare
11310           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11311                        (match_operand:QI 2 "const1_operand" ""))
11312           (const_int 0)))
11313    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11314         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11315   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11316    && ix86_match_ccmode (insn, CCGOCmode)
11317    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11318   "sar{w}\t%0"
11319   [(set_attr "type" "ishift")
11320    (set_attr "length_immediate" "0")
11321    (set_attr "mode" "HI")])
11322
11323 (define_insn "*ashrhi3_one_bit_cconly"
11324   [(set (reg FLAGS_REG)
11325         (compare
11326           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11327                        (match_operand:QI 2 "const1_operand" ""))
11328           (const_int 0)))
11329    (clobber (match_scratch:HI 0 "=r"))]
11330   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11331    && ix86_match_ccmode (insn, CCGOCmode)
11332    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11333   "sar{w}\t%0"
11334   [(set_attr "type" "ishift")
11335    (set_attr "length_immediate" "0")
11336    (set_attr "mode" "HI")])
11337
11338 ;; This pattern can't accept a variable shift count, since shifts by
11339 ;; zero don't affect the flags.  We assume that shifts by constant
11340 ;; zero are optimized away.
11341 (define_insn "*ashrhi3_cmp"
11342   [(set (reg FLAGS_REG)
11343         (compare
11344           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11345                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11346           (const_int 0)))
11347    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11348         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11349   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11350    && ix86_match_ccmode (insn, CCGOCmode)
11351    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11352   "sar{w}\t{%2, %0|%0, %2}"
11353   [(set_attr "type" "ishift")
11354    (set_attr "mode" "HI")])
11355
11356 (define_insn "*ashrhi3_cconly"
11357   [(set (reg FLAGS_REG)
11358         (compare
11359           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11360                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11361           (const_int 0)))
11362    (clobber (match_scratch:HI 0 "=r"))]
11363   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11364    && ix86_match_ccmode (insn, CCGOCmode)
11365    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11366   "sar{w}\t{%2, %0|%0, %2}"
11367   [(set_attr "type" "ishift")
11368    (set_attr "mode" "HI")])
11369
11370 (define_expand "ashrqi3"
11371   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11372         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11373                      (match_operand:QI 2 "nonmemory_operand" "")))]
11374   "TARGET_QIMODE_MATH"
11375   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11376
11377 (define_insn "*ashrqi3_1_one_bit"
11378   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11379         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11380                      (match_operand:QI 2 "const1_operand" "")))
11381    (clobber (reg:CC FLAGS_REG))]
11382   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11383    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11384   "sar{b}\t%0"
11385   [(set_attr "type" "ishift")
11386    (set_attr "length_immediate" "0")
11387    (set_attr "mode" "QI")])
11388
11389 (define_insn "*ashrqi3_1_one_bit_slp"
11390   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11391         (ashiftrt:QI (match_dup 0)
11392                      (match_operand:QI 1 "const1_operand" "")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11395    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11396    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11397   "sar{b}\t%0"
11398   [(set_attr "type" "ishift1")
11399    (set_attr "length_immediate" "0")
11400    (set_attr "mode" "QI")])
11401
11402 (define_insn "*ashrqi3_1"
11403   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11404         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11405                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11408   "@
11409    sar{b}\t{%2, %0|%0, %2}
11410    sar{b}\t{%b2, %0|%0, %b2}"
11411   [(set_attr "type" "ishift")
11412    (set_attr "mode" "QI")])
11413
11414 (define_insn "*ashrqi3_1_slp"
11415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11416         (ashiftrt:QI (match_dup 0)
11417                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11420    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11421   "@
11422    sar{b}\t{%1, %0|%0, %1}
11423    sar{b}\t{%b1, %0|%0, %b1}"
11424   [(set_attr "type" "ishift1")
11425    (set_attr "mode" "QI")])
11426
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrqi3_one_bit_cmp"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const1_operand" "I"))
11435           (const_int 0)))
11436    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11437         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11438   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11439    && ix86_match_ccmode (insn, CCGOCmode)
11440    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11441   "sar{b}\t%0"
11442   [(set_attr "type" "ishift")
11443    (set_attr "length_immediate" "0")
11444    (set_attr "mode" "QI")])
11445
11446 (define_insn "*ashrqi3_one_bit_cconly"
11447   [(set (reg FLAGS_REG)
11448         (compare
11449           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11450                        (match_operand:QI 2 "const1_operand" ""))
11451           (const_int 0)))
11452    (clobber (match_scratch:QI 0 "=q"))]
11453   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11454    && ix86_match_ccmode (insn, CCGOCmode)
11455    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11456   "sar{b}\t%0"
11457   [(set_attr "type" "ishift")
11458    (set_attr "length_immediate" "0")
11459    (set_attr "mode" "QI")])
11460
11461 ;; This pattern can't accept a variable shift count, since shifts by
11462 ;; zero don't affect the flags.  We assume that shifts by constant
11463 ;; zero are optimized away.
11464 (define_insn "*ashrqi3_cmp"
11465   [(set (reg FLAGS_REG)
11466         (compare
11467           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11468                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11469           (const_int 0)))
11470    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11471         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11472   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11473    && ix86_match_ccmode (insn, CCGOCmode)
11474    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11475   "sar{b}\t{%2, %0|%0, %2}"
11476   [(set_attr "type" "ishift")
11477    (set_attr "mode" "QI")])
11478
11479 (define_insn "*ashrqi3_cconly"
11480   [(set (reg FLAGS_REG)
11481         (compare
11482           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11483                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11484           (const_int 0)))
11485    (clobber (match_scratch:QI 0 "=q"))]
11486   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11487    && ix86_match_ccmode (insn, CCGOCmode)
11488    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11489   "sar{b}\t{%2, %0|%0, %2}"
11490   [(set_attr "type" "ishift")
11491    (set_attr "mode" "QI")])
11492
11493 \f
11494 ;; Logical shift instructions
11495
11496 ;; See comment above `ashldi3' about how this works.
11497
11498 (define_expand "lshrti3"
11499   [(set (match_operand:TI 0 "register_operand" "")
11500         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11501                      (match_operand:QI 2 "nonmemory_operand" "")))]
11502   "TARGET_64BIT"
11503   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11504
11505 (define_insn "*lshrti3_1"
11506   [(set (match_operand:TI 0 "register_operand" "=r")
11507         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11508                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "TARGET_64BIT"
11511   "#"
11512   [(set_attr "type" "multi")])
11513
11514 (define_peephole2
11515   [(match_scratch:DI 3 "r")
11516    (parallel [(set (match_operand:TI 0 "register_operand" "")
11517                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11518                                 (match_operand:QI 2 "nonmemory_operand" "")))
11519               (clobber (reg:CC FLAGS_REG))])
11520    (match_dup 3)]
11521   "TARGET_64BIT"
11522   [(const_int 0)]
11523   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11524
11525 (define_split
11526   [(set (match_operand:TI 0 "register_operand" "")
11527         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11528                      (match_operand:QI 2 "nonmemory_operand" "")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11531                     ? epilogue_completed : reload_completed)"
11532   [(const_int 0)]
11533   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11534
11535 (define_expand "lshrdi3"
11536   [(set (match_operand:DI 0 "shiftdi_operand" "")
11537         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11538                      (match_operand:QI 2 "nonmemory_operand" "")))]
11539   ""
11540   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11541
11542 (define_insn "*lshrdi3_1_one_bit_rex64"
11543   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11544         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11545                      (match_operand:QI 2 "const1_operand" "")))
11546    (clobber (reg:CC FLAGS_REG))]
11547   "TARGET_64BIT
11548    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11549    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11550   "shr{q}\t%0"
11551   [(set_attr "type" "ishift")
11552    (set_attr "length_immediate" "0")
11553    (set_attr "mode" "DI")])
11554
11555 (define_insn "*lshrdi3_1_rex64"
11556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11557         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11558                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11559    (clobber (reg:CC FLAGS_REG))]
11560   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11561   "@
11562    shr{q}\t{%2, %0|%0, %2}
11563    shr{q}\t{%b2, %0|%0, %b2}"
11564   [(set_attr "type" "ishift")
11565    (set_attr "mode" "DI")])
11566
11567 ;; This pattern can't accept a variable shift count, since shifts by
11568 ;; zero don't affect the flags.  We assume that shifts by constant
11569 ;; zero are optimized away.
11570 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11571   [(set (reg FLAGS_REG)
11572         (compare
11573           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11574                        (match_operand:QI 2 "const1_operand" ""))
11575           (const_int 0)))
11576    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11577         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11578   "TARGET_64BIT
11579    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11580    && ix86_match_ccmode (insn, CCGOCmode)
11581    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11582   "shr{q}\t%0"
11583   [(set_attr "type" "ishift")
11584    (set_attr "length_immediate" "0")
11585    (set_attr "mode" "DI")])
11586
11587 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11588   [(set (reg FLAGS_REG)
11589         (compare
11590           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11591                        (match_operand:QI 2 "const1_operand" ""))
11592           (const_int 0)))
11593    (clobber (match_scratch:DI 0 "=r"))]
11594   "TARGET_64BIT
11595    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11596    && ix86_match_ccmode (insn, CCGOCmode)
11597    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11598   "shr{q}\t%0"
11599   [(set_attr "type" "ishift")
11600    (set_attr "length_immediate" "0")
11601    (set_attr "mode" "DI")])
11602
11603 ;; This pattern can't accept a variable shift count, since shifts by
11604 ;; zero don't affect the flags.  We assume that shifts by constant
11605 ;; zero are optimized away.
11606 (define_insn "*lshrdi3_cmp_rex64"
11607   [(set (reg FLAGS_REG)
11608         (compare
11609           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11610                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11611           (const_int 0)))
11612    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11613         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11614   "TARGET_64BIT
11615    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11616    && ix86_match_ccmode (insn, CCGOCmode)
11617    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618   "shr{q}\t{%2, %0|%0, %2}"
11619   [(set_attr "type" "ishift")
11620    (set_attr "mode" "DI")])
11621
11622 (define_insn "*lshrdi3_cconly_rex64"
11623   [(set (reg FLAGS_REG)
11624         (compare
11625           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11626                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11627           (const_int 0)))
11628    (clobber (match_scratch:DI 0 "=r"))]
11629   "TARGET_64BIT
11630    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11631    && ix86_match_ccmode (insn, CCGOCmode)
11632    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11633   "shr{q}\t{%2, %0|%0, %2}"
11634   [(set_attr "type" "ishift")
11635    (set_attr "mode" "DI")])
11636
11637 (define_insn "*lshrdi3_1"
11638   [(set (match_operand:DI 0 "register_operand" "=r")
11639         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11640                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "!TARGET_64BIT"
11643   "#"
11644   [(set_attr "type" "multi")])
11645
11646 ;; By default we don't ask for a scratch register, because when DImode
11647 ;; values are manipulated, registers are already at a premium.  But if
11648 ;; we have one handy, we won't turn it away.
11649 (define_peephole2
11650   [(match_scratch:SI 3 "r")
11651    (parallel [(set (match_operand:DI 0 "register_operand" "")
11652                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11653                                 (match_operand:QI 2 "nonmemory_operand" "")))
11654               (clobber (reg:CC FLAGS_REG))])
11655    (match_dup 3)]
11656   "!TARGET_64BIT && TARGET_CMOVE"
11657   [(const_int 0)]
11658   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11659
11660 (define_split
11661   [(set (match_operand:DI 0 "register_operand" "")
11662         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11663                      (match_operand:QI 2 "nonmemory_operand" "")))
11664    (clobber (reg:CC FLAGS_REG))]
11665   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11666                      ? epilogue_completed : reload_completed)"
11667   [(const_int 0)]
11668   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11669
11670 (define_expand "lshrsi3"
11671   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11672         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11673                      (match_operand:QI 2 "nonmemory_operand" "")))]
11674   ""
11675   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11676
11677 (define_insn "*lshrsi3_1_one_bit"
11678   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11679         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680                      (match_operand:QI 2 "const1_operand" "")))
11681    (clobber (reg:CC FLAGS_REG))]
11682   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11683    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684   "shr{l}\t%0"
11685   [(set_attr "type" "ishift")
11686    (set_attr "length_immediate" "0")
11687    (set_attr "mode" "SI")])
11688
11689 (define_insn "*lshrsi3_1_one_bit_zext"
11690   [(set (match_operand:DI 0 "register_operand" "=r")
11691         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11692                      (match_operand:QI 2 "const1_operand" "")))
11693    (clobber (reg:CC FLAGS_REG))]
11694   "TARGET_64BIT
11695    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11696    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11697   "shr{l}\t%k0"
11698   [(set_attr "type" "ishift")
11699    (set_attr "length_immediate" "0")
11700    (set_attr "mode" "SI")])
11701
11702 (define_insn "*lshrsi3_1"
11703   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11704         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11705                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11708   "@
11709    shr{l}\t{%2, %0|%0, %2}
11710    shr{l}\t{%b2, %0|%0, %b2}"
11711   [(set_attr "type" "ishift")
11712    (set_attr "mode" "SI")])
11713
11714 (define_insn "*lshrsi3_1_zext"
11715   [(set (match_operand:DI 0 "register_operand" "=r,r")
11716         (zero_extend:DI
11717           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11718                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11721   "@
11722    shr{l}\t{%2, %k0|%k0, %2}
11723    shr{l}\t{%b2, %k0|%k0, %b2}"
11724   [(set_attr "type" "ishift")
11725    (set_attr "mode" "SI")])
11726
11727 ;; This pattern can't accept a variable shift count, since shifts by
11728 ;; zero don't affect the flags.  We assume that shifts by constant
11729 ;; zero are optimized away.
11730 (define_insn "*lshrsi3_one_bit_cmp"
11731   [(set (reg FLAGS_REG)
11732         (compare
11733           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11734                        (match_operand:QI 2 "const1_operand" ""))
11735           (const_int 0)))
11736    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11737         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11738   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11739    && ix86_match_ccmode (insn, CCGOCmode)
11740    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11741   "shr{l}\t%0"
11742   [(set_attr "type" "ishift")
11743    (set_attr "length_immediate" "0")
11744    (set_attr "mode" "SI")])
11745
11746 (define_insn "*lshrsi3_one_bit_cconly"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const1_operand" ""))
11751           (const_int 0)))
11752    (clobber (match_scratch:SI 0 "=r"))]
11753   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11754    && ix86_match_ccmode (insn, CCGOCmode)
11755    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11756   "shr{l}\t%0"
11757   [(set_attr "type" "ishift")
11758    (set_attr "length_immediate" "0")
11759    (set_attr "mode" "SI")])
11760
11761 (define_insn "*lshrsi3_cmp_one_bit_zext"
11762   [(set (reg FLAGS_REG)
11763         (compare
11764           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11765                        (match_operand:QI 2 "const1_operand" ""))
11766           (const_int 0)))
11767    (set (match_operand:DI 0 "register_operand" "=r")
11768         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11769   "TARGET_64BIT
11770    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11771    && ix86_match_ccmode (insn, CCGOCmode)
11772    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11773   "shr{l}\t%k0"
11774   [(set_attr "type" "ishift")
11775    (set_attr "length_immediate" "0")
11776    (set_attr "mode" "SI")])
11777
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags.  We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*lshrsi3_cmp"
11782   [(set (reg FLAGS_REG)
11783         (compare
11784           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11785                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11786           (const_int 0)))
11787    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11788         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11789   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11790    && ix86_match_ccmode (insn, CCGOCmode)
11791    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11792   "shr{l}\t{%2, %0|%0, %2}"
11793   [(set_attr "type" "ishift")
11794    (set_attr "mode" "SI")])
11795
11796 (define_insn "*lshrsi3_cconly"
11797   [(set (reg FLAGS_REG)
11798       (compare
11799         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11800                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801         (const_int 0)))
11802    (clobber (match_scratch:SI 0 "=r"))]
11803   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11804    && ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11806   "shr{l}\t{%2, %0|%0, %2}"
11807   [(set_attr "type" "ishift")
11808    (set_attr "mode" "SI")])
11809
11810 (define_insn "*lshrsi3_cmp_zext"
11811   [(set (reg FLAGS_REG)
11812         (compare
11813           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11814                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11815           (const_int 0)))
11816    (set (match_operand:DI 0 "register_operand" "=r")
11817         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11818   "TARGET_64BIT
11819    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11820    && ix86_match_ccmode (insn, CCGOCmode)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t{%2, %k0|%k0, %2}"
11823   [(set_attr "type" "ishift")
11824    (set_attr "mode" "SI")])
11825
11826 (define_expand "lshrhi3"
11827   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11828         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11829                      (match_operand:QI 2 "nonmemory_operand" "")))]
11830   "TARGET_HIMODE_MATH"
11831   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11832
11833 (define_insn "*lshrhi3_1_one_bit"
11834   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11835         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11836                      (match_operand:QI 2 "const1_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840   "shr{w}\t%0"
11841   [(set_attr "type" "ishift")
11842    (set_attr "length_immediate" "0")
11843    (set_attr "mode" "HI")])
11844
11845 (define_insn "*lshrhi3_1"
11846   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11847         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11848                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11849    (clobber (reg:CC FLAGS_REG))]
11850   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11851   "@
11852    shr{w}\t{%2, %0|%0, %2}
11853    shr{w}\t{%b2, %0|%0, %b2}"
11854   [(set_attr "type" "ishift")
11855    (set_attr "mode" "HI")])
11856
11857 ;; This pattern can't accept a variable shift count, since shifts by
11858 ;; zero don't affect the flags.  We assume that shifts by constant
11859 ;; zero are optimized away.
11860 (define_insn "*lshrhi3_one_bit_cmp"
11861   [(set (reg FLAGS_REG)
11862         (compare
11863           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11864                        (match_operand:QI 2 "const1_operand" ""))
11865           (const_int 0)))
11866    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11867         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11868   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11869    && ix86_match_ccmode (insn, CCGOCmode)
11870    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "shr{w}\t%0"
11872   [(set_attr "type" "ishift")
11873    (set_attr "length_immediate" "0")
11874    (set_attr "mode" "HI")])
11875
11876 (define_insn "*lshrhi3_one_bit_cconly"
11877   [(set (reg FLAGS_REG)
11878         (compare
11879           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11880                        (match_operand:QI 2 "const1_operand" ""))
11881           (const_int 0)))
11882    (clobber (match_scratch:HI 0 "=r"))]
11883   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11884    && ix86_match_ccmode (insn, CCGOCmode)
11885    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11886   "shr{w}\t%0"
11887   [(set_attr "type" "ishift")
11888    (set_attr "length_immediate" "0")
11889    (set_attr "mode" "HI")])
11890
11891 ;; This pattern can't accept a variable shift count, since shifts by
11892 ;; zero don't affect the flags.  We assume that shifts by constant
11893 ;; zero are optimized away.
11894 (define_insn "*lshrhi3_cmp"
11895   [(set (reg FLAGS_REG)
11896         (compare
11897           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11898                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899           (const_int 0)))
11900    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11901         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11902   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11903    && ix86_match_ccmode (insn, CCGOCmode)
11904    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11905   "shr{w}\t{%2, %0|%0, %2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11908
11909 (define_insn "*lshrhi3_cconly"
11910   [(set (reg FLAGS_REG)
11911         (compare
11912           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11913                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914           (const_int 0)))
11915    (clobber (match_scratch:HI 0 "=r"))]
11916   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11917    && ix86_match_ccmode (insn, CCGOCmode)
11918    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11919   "shr{w}\t{%2, %0|%0, %2}"
11920   [(set_attr "type" "ishift")
11921    (set_attr "mode" "HI")])
11922
11923 (define_expand "lshrqi3"
11924   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11925         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11926                      (match_operand:QI 2 "nonmemory_operand" "")))]
11927   "TARGET_QIMODE_MATH"
11928   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11929
11930 (define_insn "*lshrqi3_1_one_bit"
11931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11932         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11933                      (match_operand:QI 2 "const1_operand" "")))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11936    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11937   "shr{b}\t%0"
11938   [(set_attr "type" "ishift")
11939    (set_attr "length_immediate" "0")
11940    (set_attr "mode" "QI")])
11941
11942 (define_insn "*lshrqi3_1_one_bit_slp"
11943   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11944         (lshiftrt:QI (match_dup 0)
11945                      (match_operand:QI 1 "const1_operand" "")))
11946    (clobber (reg:CC FLAGS_REG))]
11947   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11948    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11949   "shr{b}\t%0"
11950   [(set_attr "type" "ishift1")
11951    (set_attr "length_immediate" "0")
11952    (set_attr "mode" "QI")])
11953
11954 (define_insn "*lshrqi3_1"
11955   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11956         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11957                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11960   "@
11961    shr{b}\t{%2, %0|%0, %2}
11962    shr{b}\t{%b2, %0|%0, %b2}"
11963   [(set_attr "type" "ishift")
11964    (set_attr "mode" "QI")])
11965
11966 (define_insn "*lshrqi3_1_slp"
11967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11968         (lshiftrt:QI (match_dup 0)
11969                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11970    (clobber (reg:CC FLAGS_REG))]
11971   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11972    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11973   "@
11974    shr{b}\t{%1, %0|%0, %1}
11975    shr{b}\t{%b1, %0|%0, %b1}"
11976   [(set_attr "type" "ishift1")
11977    (set_attr "mode" "QI")])
11978
11979 ;; This pattern can't accept a variable shift count, since shifts by
11980 ;; zero don't affect the flags.  We assume that shifts by constant
11981 ;; zero are optimized away.
11982 (define_insn "*lshrqi2_one_bit_cmp"
11983   [(set (reg FLAGS_REG)
11984         (compare
11985           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11986                        (match_operand:QI 2 "const1_operand" ""))
11987           (const_int 0)))
11988    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11989         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11990   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11991    && ix86_match_ccmode (insn, CCGOCmode)
11992    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11993   "shr{b}\t%0"
11994   [(set_attr "type" "ishift")
11995    (set_attr "length_immediate" "0")
11996    (set_attr "mode" "QI")])
11997
11998 (define_insn "*lshrqi2_one_bit_cconly"
11999   [(set (reg FLAGS_REG)
12000         (compare
12001           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002                        (match_operand:QI 2 "const1_operand" ""))
12003           (const_int 0)))
12004    (clobber (match_scratch:QI 0 "=q"))]
12005   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12006    && ix86_match_ccmode (insn, CCGOCmode)
12007    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12008   "shr{b}\t%0"
12009   [(set_attr "type" "ishift")
12010    (set_attr "length_immediate" "0")
12011    (set_attr "mode" "QI")])
12012
12013 ;; This pattern can't accept a variable shift count, since shifts by
12014 ;; zero don't affect the flags.  We assume that shifts by constant
12015 ;; zero are optimized away.
12016 (define_insn "*lshrqi2_cmp"
12017   [(set (reg FLAGS_REG)
12018         (compare
12019           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12020                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12021           (const_int 0)))
12022    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12023         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12024   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12025    && ix86_match_ccmode (insn, CCGOCmode)
12026    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12027   "shr{b}\t{%2, %0|%0, %2}"
12028   [(set_attr "type" "ishift")
12029    (set_attr "mode" "QI")])
12030
12031 (define_insn "*lshrqi2_cconly"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036           (const_int 0)))
12037    (clobber (match_scratch:QI 0 "=q"))]
12038   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12039    && ix86_match_ccmode (insn, CCGOCmode)
12040    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12041   "shr{b}\t{%2, %0|%0, %2}"
12042   [(set_attr "type" "ishift")
12043    (set_attr "mode" "QI")])
12044 \f
12045 ;; Rotate instructions
12046
12047 (define_expand "rotldi3"
12048   [(set (match_operand:DI 0 "shiftdi_operand" "")
12049         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12050                    (match_operand:QI 2 "nonmemory_operand" "")))]
12051  ""
12052 {
12053   if (TARGET_64BIT)
12054     {
12055       ix86_expand_binary_operator (ROTATE, DImode, operands);
12056       DONE;
12057     }
12058   if (!const_1_to_31_operand (operands[2], VOIDmode))
12059     FAIL;
12060   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12061   DONE;
12062 })
12063
12064 ;; Implement rotation using two double-precision shift instructions
12065 ;; and a scratch register.
12066 (define_insn_and_split "ix86_rotldi3"
12067  [(set (match_operand:DI 0 "register_operand" "=r")
12068        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12069                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12070   (clobber (reg:CC FLAGS_REG))
12071   (clobber (match_scratch:SI 3 "=&r"))]
12072  "!TARGET_64BIT"
12073  ""
12074  "&& reload_completed"
12075  [(set (match_dup 3) (match_dup 4))
12076   (parallel
12077    [(set (match_dup 4)
12078          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12079                  (lshiftrt:SI (match_dup 5)
12080                               (minus:QI (const_int 32) (match_dup 2)))))
12081     (clobber (reg:CC FLAGS_REG))])
12082   (parallel
12083    [(set (match_dup 5)
12084          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12085                  (lshiftrt:SI (match_dup 3)
12086                               (minus:QI (const_int 32) (match_dup 2)))))
12087     (clobber (reg:CC FLAGS_REG))])]
12088  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12089
12090 (define_insn "*rotlsi3_1_one_bit_rex64"
12091   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12092         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093                    (match_operand:QI 2 "const1_operand" "")))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_64BIT
12096    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12097    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12098   "rol{q}\t%0"
12099   [(set_attr "type" "rotate")
12100    (set_attr "length_immediate" "0")
12101    (set_attr "mode" "DI")])
12102
12103 (define_insn "*rotldi3_1_rex64"
12104   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12105         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12106                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12109   "@
12110    rol{q}\t{%2, %0|%0, %2}
12111    rol{q}\t{%b2, %0|%0, %b2}"
12112   [(set_attr "type" "rotate")
12113    (set_attr "mode" "DI")])
12114
12115 (define_expand "rotlsi3"
12116   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12117         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12118                    (match_operand:QI 2 "nonmemory_operand" "")))]
12119   ""
12120   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12121
12122 (define_insn "*rotlsi3_1_one_bit"
12123   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12124         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12125                    (match_operand:QI 2 "const1_operand" "")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12128    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12129   "rol{l}\t%0"
12130   [(set_attr "type" "rotate")
12131    (set_attr "length_immediate" "0")
12132    (set_attr "mode" "SI")])
12133
12134 (define_insn "*rotlsi3_1_one_bit_zext"
12135   [(set (match_operand:DI 0 "register_operand" "=r")
12136         (zero_extend:DI
12137           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12138                      (match_operand:QI 2 "const1_operand" ""))))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "TARGET_64BIT
12141    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12142    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12143   "rol{l}\t%k0"
12144   [(set_attr "type" "rotate")
12145    (set_attr "length_immediate" "0")
12146    (set_attr "mode" "SI")])
12147
12148 (define_insn "*rotlsi3_1"
12149   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12150         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12151                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12152    (clobber (reg:CC FLAGS_REG))]
12153   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12154   "@
12155    rol{l}\t{%2, %0|%0, %2}
12156    rol{l}\t{%b2, %0|%0, %b2}"
12157   [(set_attr "type" "rotate")
12158    (set_attr "mode" "SI")])
12159
12160 (define_insn "*rotlsi3_1_zext"
12161   [(set (match_operand:DI 0 "register_operand" "=r,r")
12162         (zero_extend:DI
12163           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12164                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12165    (clobber (reg:CC FLAGS_REG))]
12166   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12167   "@
12168    rol{l}\t{%2, %k0|%k0, %2}
12169    rol{l}\t{%b2, %k0|%k0, %b2}"
12170   [(set_attr "type" "rotate")
12171    (set_attr "mode" "SI")])
12172
12173 (define_expand "rotlhi3"
12174   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12175         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12176                    (match_operand:QI 2 "nonmemory_operand" "")))]
12177   "TARGET_HIMODE_MATH"
12178   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12179
12180 (define_insn "*rotlhi3_1_one_bit"
12181   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12182         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12183                    (match_operand:QI 2 "const1_operand" "")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12186    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12187   "rol{w}\t%0"
12188   [(set_attr "type" "rotate")
12189    (set_attr "length_immediate" "0")
12190    (set_attr "mode" "HI")])
12191
12192 (define_insn "*rotlhi3_1"
12193   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12194         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12195                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12196    (clobber (reg:CC FLAGS_REG))]
12197   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12198   "@
12199    rol{w}\t{%2, %0|%0, %2}
12200    rol{w}\t{%b2, %0|%0, %b2}"
12201   [(set_attr "type" "rotate")
12202    (set_attr "mode" "HI")])
12203
12204 (define_split
12205  [(set (match_operand:HI 0 "register_operand" "")
12206        (rotate:HI (match_dup 0) (const_int 8)))
12207   (clobber (reg:CC FLAGS_REG))]
12208  "reload_completed"
12209  [(parallel [(set (strict_low_part (match_dup 0))
12210                   (bswap:HI (match_dup 0)))
12211              (clobber (reg:CC FLAGS_REG))])]
12212  "")
12213
12214 (define_expand "rotlqi3"
12215   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12216         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12217                    (match_operand:QI 2 "nonmemory_operand" "")))]
12218   "TARGET_QIMODE_MATH"
12219   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12220
12221 (define_insn "*rotlqi3_1_one_bit_slp"
12222   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12223         (rotate:QI (match_dup 0)
12224                    (match_operand:QI 1 "const1_operand" "")))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12227    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12228   "rol{b}\t%0"
12229   [(set_attr "type" "rotate1")
12230    (set_attr "length_immediate" "0")
12231    (set_attr "mode" "QI")])
12232
12233 (define_insn "*rotlqi3_1_one_bit"
12234   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236                    (match_operand:QI 2 "const1_operand" "")))
12237    (clobber (reg:CC FLAGS_REG))]
12238   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12240   "rol{b}\t%0"
12241   [(set_attr "type" "rotate")
12242    (set_attr "length_immediate" "0")
12243    (set_attr "mode" "QI")])
12244
12245 (define_insn "*rotlqi3_1_slp"
12246   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247         (rotate:QI (match_dup 0)
12248                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12251    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12252   "@
12253    rol{b}\t{%1, %0|%0, %1}
12254    rol{b}\t{%b1, %0|%0, %b1}"
12255   [(set_attr "type" "rotate1")
12256    (set_attr "mode" "QI")])
12257
12258 (define_insn "*rotlqi3_1"
12259   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12260         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12261                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12264   "@
12265    rol{b}\t{%2, %0|%0, %2}
12266    rol{b}\t{%b2, %0|%0, %b2}"
12267   [(set_attr "type" "rotate")
12268    (set_attr "mode" "QI")])
12269
12270 (define_expand "rotrdi3"
12271   [(set (match_operand:DI 0 "shiftdi_operand" "")
12272         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12273                    (match_operand:QI 2 "nonmemory_operand" "")))]
12274  ""
12275 {
12276   if (TARGET_64BIT)
12277     {
12278       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12279       DONE;
12280     }
12281   if (!const_1_to_31_operand (operands[2], VOIDmode))
12282     FAIL;
12283   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12284   DONE;
12285 })
12286
12287 ;; Implement rotation using two double-precision shift instructions
12288 ;; and a scratch register.
12289 (define_insn_and_split "ix86_rotrdi3"
12290  [(set (match_operand:DI 0 "register_operand" "=r")
12291        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12292                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12293   (clobber (reg:CC FLAGS_REG))
12294   (clobber (match_scratch:SI 3 "=&r"))]
12295  "!TARGET_64BIT"
12296  ""
12297  "&& reload_completed"
12298  [(set (match_dup 3) (match_dup 4))
12299   (parallel
12300    [(set (match_dup 4)
12301          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12302                  (ashift:SI (match_dup 5)
12303                             (minus:QI (const_int 32) (match_dup 2)))))
12304     (clobber (reg:CC FLAGS_REG))])
12305   (parallel
12306    [(set (match_dup 5)
12307          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12308                  (ashift:SI (match_dup 3)
12309                             (minus:QI (const_int 32) (match_dup 2)))))
12310     (clobber (reg:CC FLAGS_REG))])]
12311  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12312
12313 (define_insn "*rotrdi3_1_one_bit_rex64"
12314   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12315         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12316                      (match_operand:QI 2 "const1_operand" "")))
12317    (clobber (reg:CC FLAGS_REG))]
12318   "TARGET_64BIT
12319    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12320    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12321   "ror{q}\t%0"
12322   [(set_attr "type" "rotate")
12323    (set_attr "length_immediate" "0")
12324    (set_attr "mode" "DI")])
12325
12326 (define_insn "*rotrdi3_1_rex64"
12327   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12328         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12329                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12330    (clobber (reg:CC FLAGS_REG))]
12331   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12332   "@
12333    ror{q}\t{%2, %0|%0, %2}
12334    ror{q}\t{%b2, %0|%0, %b2}"
12335   [(set_attr "type" "rotate")
12336    (set_attr "mode" "DI")])
12337
12338 (define_expand "rotrsi3"
12339   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12340         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12341                      (match_operand:QI 2 "nonmemory_operand" "")))]
12342   ""
12343   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12344
12345 (define_insn "*rotrsi3_1_one_bit"
12346   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12347         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12348                      (match_operand:QI 2 "const1_operand" "")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12351    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12352   "ror{l}\t%0"
12353   [(set_attr "type" "rotate")
12354    (set_attr "length_immediate" "0")
12355    (set_attr "mode" "SI")])
12356
12357 (define_insn "*rotrsi3_1_one_bit_zext"
12358   [(set (match_operand:DI 0 "register_operand" "=r")
12359         (zero_extend:DI
12360           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12361                        (match_operand:QI 2 "const1_operand" ""))))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT
12364    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12365    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12366   "ror{l}\t%k0"
12367   [(set_attr "type" "rotate")
12368    (set_attr "length_immediate" "0")
12369    (set_attr "mode" "SI")])
12370
12371 (define_insn "*rotrsi3_1"
12372   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12373         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12374                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12375    (clobber (reg:CC FLAGS_REG))]
12376   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12377   "@
12378    ror{l}\t{%2, %0|%0, %2}
12379    ror{l}\t{%b2, %0|%0, %b2}"
12380   [(set_attr "type" "rotate")
12381    (set_attr "mode" "SI")])
12382
12383 (define_insn "*rotrsi3_1_zext"
12384   [(set (match_operand:DI 0 "register_operand" "=r,r")
12385         (zero_extend:DI
12386           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12387                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12388    (clobber (reg:CC FLAGS_REG))]
12389   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12390   "@
12391    ror{l}\t{%2, %k0|%k0, %2}
12392    ror{l}\t{%b2, %k0|%k0, %b2}"
12393   [(set_attr "type" "rotate")
12394    (set_attr "mode" "SI")])
12395
12396 (define_expand "rotrhi3"
12397   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12398         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12399                      (match_operand:QI 2 "nonmemory_operand" "")))]
12400   "TARGET_HIMODE_MATH"
12401   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12402
12403 (define_insn "*rotrhi3_one_bit"
12404   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12405         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12406                      (match_operand:QI 2 "const1_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12409    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12410   "ror{w}\t%0"
12411   [(set_attr "type" "rotate")
12412    (set_attr "length_immediate" "0")
12413    (set_attr "mode" "HI")])
12414
12415 (define_insn "*rotrhi3_1"
12416   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12417         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12418                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12421   "@
12422    ror{w}\t{%2, %0|%0, %2}
12423    ror{w}\t{%b2, %0|%0, %b2}"
12424   [(set_attr "type" "rotate")
12425    (set_attr "mode" "HI")])
12426
12427 (define_split
12428  [(set (match_operand:HI 0 "register_operand" "")
12429        (rotatert:HI (match_dup 0) (const_int 8)))
12430   (clobber (reg:CC FLAGS_REG))]
12431  "reload_completed"
12432  [(parallel [(set (strict_low_part (match_dup 0))
12433                   (bswap:HI (match_dup 0)))
12434              (clobber (reg:CC FLAGS_REG))])]
12435  "")
12436
12437 (define_expand "rotrqi3"
12438   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12439         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12440                      (match_operand:QI 2 "nonmemory_operand" "")))]
12441   "TARGET_QIMODE_MATH"
12442   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12443
12444 (define_insn "*rotrqi3_1_one_bit"
12445   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12446         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12447                      (match_operand:QI 2 "const1_operand" "")))
12448    (clobber (reg:CC FLAGS_REG))]
12449   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12450    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12451   "ror{b}\t%0"
12452   [(set_attr "type" "rotate")
12453    (set_attr "length_immediate" "0")
12454    (set_attr "mode" "QI")])
12455
12456 (define_insn "*rotrqi3_1_one_bit_slp"
12457   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12458         (rotatert:QI (match_dup 0)
12459                      (match_operand:QI 1 "const1_operand" "")))
12460    (clobber (reg:CC FLAGS_REG))]
12461   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12462    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12463   "ror{b}\t%0"
12464   [(set_attr "type" "rotate1")
12465    (set_attr "length_immediate" "0")
12466    (set_attr "mode" "QI")])
12467
12468 (define_insn "*rotrqi3_1"
12469   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12470         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12471                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12474   "@
12475    ror{b}\t{%2, %0|%0, %2}
12476    ror{b}\t{%b2, %0|%0, %b2}"
12477   [(set_attr "type" "rotate")
12478    (set_attr "mode" "QI")])
12479
12480 (define_insn "*rotrqi3_1_slp"
12481   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12482         (rotatert:QI (match_dup 0)
12483                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12486    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12487   "@
12488    ror{b}\t{%1, %0|%0, %1}
12489    ror{b}\t{%b1, %0|%0, %b1}"
12490   [(set_attr "type" "rotate1")
12491    (set_attr "mode" "QI")])
12492 \f
12493 ;; Bit set / bit test instructions
12494
12495 (define_expand "extv"
12496   [(set (match_operand:SI 0 "register_operand" "")
12497         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12498                          (match_operand:SI 2 "const8_operand" "")
12499                          (match_operand:SI 3 "const8_operand" "")))]
12500   ""
12501 {
12502   /* Handle extractions from %ah et al.  */
12503   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12504     FAIL;
12505
12506   /* From mips.md: extract_bit_field doesn't verify that our source
12507      matches the predicate, so check it again here.  */
12508   if (! ext_register_operand (operands[1], VOIDmode))
12509     FAIL;
12510 })
12511
12512 (define_expand "extzv"
12513   [(set (match_operand:SI 0 "register_operand" "")
12514         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12515                          (match_operand:SI 2 "const8_operand" "")
12516                          (match_operand:SI 3 "const8_operand" "")))]
12517   ""
12518 {
12519   /* Handle extractions from %ah et al.  */
12520   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12521     FAIL;
12522
12523   /* From mips.md: extract_bit_field doesn't verify that our source
12524      matches the predicate, so check it again here.  */
12525   if (! ext_register_operand (operands[1], VOIDmode))
12526     FAIL;
12527 })
12528
12529 (define_expand "insv"
12530   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12531                       (match_operand 1 "const8_operand" "")
12532                       (match_operand 2 "const8_operand" ""))
12533         (match_operand 3 "register_operand" ""))]
12534   ""
12535 {
12536   /* Handle insertions to %ah et al.  */
12537   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12538     FAIL;
12539
12540   /* From mips.md: insert_bit_field doesn't verify that our source
12541      matches the predicate, so check it again here.  */
12542   if (! ext_register_operand (operands[0], VOIDmode))
12543     FAIL;
12544
12545   if (TARGET_64BIT)
12546     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12547   else
12548     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12549
12550   DONE;
12551 })
12552
12553 ;; %%% bts, btr, btc, bt.
12554 ;; In general these instructions are *slow* when applied to memory,
12555 ;; since they enforce atomic operation.  When applied to registers,
12556 ;; it depends on the cpu implementation.  They're never faster than
12557 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12558 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12559 ;; within the instruction itself, so operating on bits in the high
12560 ;; 32-bits of a register becomes easier.
12561 ;;
12562 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12563 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12564 ;; negdf respectively, so they can never be disabled entirely.
12565
12566 (define_insn "*btsq"
12567   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12568                          (const_int 1)
12569                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12570         (const_int 1))
12571    (clobber (reg:CC FLAGS_REG))]
12572   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12573   "bts{q}\t{%1, %0|%0, %1}"
12574   [(set_attr "type" "alu1")
12575    (set_attr "prefix_0f" "1")
12576    (set_attr "mode" "DI")])
12577
12578 (define_insn "*btrq"
12579   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12580                          (const_int 1)
12581                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12582         (const_int 0))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12585   "btr{q}\t{%1, %0|%0, %1}"
12586   [(set_attr "type" "alu1")
12587    (set_attr "prefix_0f" "1")
12588    (set_attr "mode" "DI")])
12589
12590 (define_insn "*btcq"
12591   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12592                          (const_int 1)
12593                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12594         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12597   "btc{q}\t{%1, %0|%0, %1}"
12598   [(set_attr "type" "alu1")
12599    (set_attr "prefix_0f" "1")
12600    (set_attr "mode" "DI")])
12601
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12603
12604 (define_peephole2
12605   [(match_scratch:DI 2 "r")
12606    (parallel [(set (zero_extract:DI
12607                      (match_operand:DI 0 "register_operand" "")
12608                      (const_int 1)
12609                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12610                    (const_int 1))
12611               (clobber (reg:CC FLAGS_REG))])]
12612   "TARGET_64BIT && !TARGET_USE_BT"
12613   [(const_int 0)]
12614 {
12615   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616   rtx op1;
12617
12618   if (HOST_BITS_PER_WIDE_INT >= 64)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else if (i < HOST_BITS_PER_WIDE_INT)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else
12623     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624
12625   op1 = immed_double_const (lo, hi, DImode);
12626   if (i >= 31)
12627     {
12628       emit_move_insn (operands[2], op1);
12629       op1 = operands[2];
12630     }
12631
12632   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12633   DONE;
12634 })
12635
12636 (define_peephole2
12637   [(match_scratch:DI 2 "r")
12638    (parallel [(set (zero_extract:DI
12639                      (match_operand:DI 0 "register_operand" "")
12640                      (const_int 1)
12641                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12642                    (const_int 0))
12643               (clobber (reg:CC FLAGS_REG))])]
12644   "TARGET_64BIT && !TARGET_USE_BT"
12645   [(const_int 0)]
12646 {
12647   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648   rtx op1;
12649
12650   if (HOST_BITS_PER_WIDE_INT >= 64)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else if (i < HOST_BITS_PER_WIDE_INT)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else
12655     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656
12657   op1 = immed_double_const (~lo, ~hi, DImode);
12658   if (i >= 32)
12659     {
12660       emit_move_insn (operands[2], op1);
12661       op1 = operands[2];
12662     }
12663
12664   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12665   DONE;
12666 })
12667
12668 (define_peephole2
12669   [(match_scratch:DI 2 "r")
12670    (parallel [(set (zero_extract:DI
12671                      (match_operand:DI 0 "register_operand" "")
12672                      (const_int 1)
12673                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12674               (not:DI (zero_extract:DI
12675                         (match_dup 0) (const_int 1) (match_dup 1))))
12676               (clobber (reg:CC FLAGS_REG))])]
12677   "TARGET_64BIT && !TARGET_USE_BT"
12678   [(const_int 0)]
12679 {
12680   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12681   rtx op1;
12682
12683   if (HOST_BITS_PER_WIDE_INT >= 64)
12684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685   else if (i < HOST_BITS_PER_WIDE_INT)
12686     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687   else
12688     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12689
12690   op1 = immed_double_const (lo, hi, DImode);
12691   if (i >= 31)
12692     {
12693       emit_move_insn (operands[2], op1);
12694       op1 = operands[2];
12695     }
12696
12697   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12698   DONE;
12699 })
12700
12701 (define_insn "*btdi_rex64"
12702   [(set (reg:CCC FLAGS_REG)
12703         (compare:CCC
12704           (zero_extract:DI
12705             (match_operand:DI 0 "register_operand" "r")
12706             (const_int 1)
12707             (match_operand:DI 1 "nonmemory_operand" "rN"))
12708           (const_int 0)))]
12709   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12710   "bt{q}\t{%1, %0|%0, %1}"
12711   [(set_attr "type" "alu1")
12712    (set_attr "prefix_0f" "1")
12713    (set_attr "mode" "DI")])
12714
12715 (define_insn "*btsi"
12716   [(set (reg:CCC FLAGS_REG)
12717         (compare:CCC
12718           (zero_extract:SI
12719             (match_operand:SI 0 "register_operand" "r")
12720             (const_int 1)
12721             (match_operand:SI 1 "nonmemory_operand" "rN"))
12722           (const_int 0)))]
12723   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12724   "bt{l}\t{%1, %0|%0, %1}"
12725   [(set_attr "type" "alu1")
12726    (set_attr "prefix_0f" "1")
12727    (set_attr "mode" "SI")])
12728 \f
12729 ;; Store-flag instructions.
12730
12731 ;; For all sCOND expanders, also expand the compare or test insn that
12732 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12733
12734 (define_insn_and_split "*setcc_di_1"
12735   [(set (match_operand:DI 0 "register_operand" "=q")
12736         (match_operator:DI 1 "ix86_comparison_operator"
12737           [(reg FLAGS_REG) (const_int 0)]))]
12738   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12739   "#"
12740   "&& reload_completed"
12741   [(set (match_dup 2) (match_dup 1))
12742    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12743 {
12744   PUT_MODE (operands[1], QImode);
12745   operands[2] = gen_lowpart (QImode, operands[0]);
12746 })
12747
12748 (define_insn_and_split "*setcc_si_1_and"
12749   [(set (match_operand:SI 0 "register_operand" "=q")
12750         (match_operator:SI 1 "ix86_comparison_operator"
12751           [(reg FLAGS_REG) (const_int 0)]))
12752    (clobber (reg:CC FLAGS_REG))]
12753   "!TARGET_PARTIAL_REG_STALL
12754    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12755   "#"
12756   "&& reload_completed"
12757   [(set (match_dup 2) (match_dup 1))
12758    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12759               (clobber (reg:CC FLAGS_REG))])]
12760 {
12761   PUT_MODE (operands[1], QImode);
12762   operands[2] = gen_lowpart (QImode, operands[0]);
12763 })
12764
12765 (define_insn_and_split "*setcc_si_1_movzbl"
12766   [(set (match_operand:SI 0 "register_operand" "=q")
12767         (match_operator:SI 1 "ix86_comparison_operator"
12768           [(reg FLAGS_REG) (const_int 0)]))]
12769   "!TARGET_PARTIAL_REG_STALL
12770    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12771   "#"
12772   "&& reload_completed"
12773   [(set (match_dup 2) (match_dup 1))
12774    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12775 {
12776   PUT_MODE (operands[1], QImode);
12777   operands[2] = gen_lowpart (QImode, operands[0]);
12778 })
12779
12780 (define_insn "*setcc_qi"
12781   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12782         (match_operator:QI 1 "ix86_comparison_operator"
12783           [(reg FLAGS_REG) (const_int 0)]))]
12784   ""
12785   "set%C1\t%0"
12786   [(set_attr "type" "setcc")
12787    (set_attr "mode" "QI")])
12788
12789 (define_insn "*setcc_qi_slp"
12790   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12791         (match_operator:QI 1 "ix86_comparison_operator"
12792           [(reg FLAGS_REG) (const_int 0)]))]
12793   ""
12794   "set%C1\t%0"
12795   [(set_attr "type" "setcc")
12796    (set_attr "mode" "QI")])
12797
12798 ;; In general it is not safe to assume too much about CCmode registers,
12799 ;; so simplify-rtx stops when it sees a second one.  Under certain
12800 ;; conditions this is safe on x86, so help combine not create
12801 ;;
12802 ;;      seta    %al
12803 ;;      testb   %al, %al
12804 ;;      sete    %al
12805
12806 (define_split
12807   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12808         (ne:QI (match_operator 1 "ix86_comparison_operator"
12809                  [(reg FLAGS_REG) (const_int 0)])
12810             (const_int 0)))]
12811   ""
12812   [(set (match_dup 0) (match_dup 1))]
12813 {
12814   PUT_MODE (operands[1], QImode);
12815 })
12816
12817 (define_split
12818   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12819         (ne:QI (match_operator 1 "ix86_comparison_operator"
12820                  [(reg FLAGS_REG) (const_int 0)])
12821             (const_int 0)))]
12822   ""
12823   [(set (match_dup 0) (match_dup 1))]
12824 {
12825   PUT_MODE (operands[1], QImode);
12826 })
12827
12828 (define_split
12829   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12830         (eq:QI (match_operator 1 "ix86_comparison_operator"
12831                  [(reg FLAGS_REG) (const_int 0)])
12832             (const_int 0)))]
12833   ""
12834   [(set (match_dup 0) (match_dup 1))]
12835 {
12836   rtx new_op1 = copy_rtx (operands[1]);
12837   operands[1] = new_op1;
12838   PUT_MODE (new_op1, QImode);
12839   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12840                                              GET_MODE (XEXP (new_op1, 0))));
12841
12842   /* Make sure that (a) the CCmode we have for the flags is strong
12843      enough for the reversed compare or (b) we have a valid FP compare.  */
12844   if (! ix86_comparison_operator (new_op1, VOIDmode))
12845     FAIL;
12846 })
12847
12848 (define_split
12849   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12850         (eq:QI (match_operator 1 "ix86_comparison_operator"
12851                  [(reg FLAGS_REG) (const_int 0)])
12852             (const_int 0)))]
12853   ""
12854   [(set (match_dup 0) (match_dup 1))]
12855 {
12856   rtx new_op1 = copy_rtx (operands[1]);
12857   operands[1] = new_op1;
12858   PUT_MODE (new_op1, QImode);
12859   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12860                                              GET_MODE (XEXP (new_op1, 0))));
12861
12862   /* Make sure that (a) the CCmode we have for the flags is strong
12863      enough for the reversed compare or (b) we have a valid FP compare.  */
12864   if (! ix86_comparison_operator (new_op1, VOIDmode))
12865     FAIL;
12866 })
12867
12868 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12869 ;; subsequent logical operations are used to imitate conditional moves.
12870 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12871 ;; it directly.
12872
12873 (define_insn "*avx_setcc<mode>"
12874   [(set (match_operand:MODEF 0 "register_operand" "=x")
12875         (match_operator:MODEF 1 "avx_comparison_float_operator"
12876           [(match_operand:MODEF 2 "register_operand" "x")
12877            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12878   "TARGET_AVX"
12879   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12880   [(set_attr "type" "ssecmp")
12881    (set_attr "prefix" "vex")
12882    (set_attr "length_immediate" "1")
12883    (set_attr "mode" "<MODE>")])
12884
12885 (define_insn "*sse_setcc<mode>"
12886   [(set (match_operand:MODEF 0 "register_operand" "=x")
12887         (match_operator:MODEF 1 "sse_comparison_operator"
12888           [(match_operand:MODEF 2 "register_operand" "0")
12889            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12890   "SSE_FLOAT_MODE_P (<MODE>mode)"
12891   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12892   [(set_attr "type" "ssecmp")
12893    (set_attr "length_immediate" "1")
12894    (set_attr "mode" "<MODE>")])
12895 \f
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12898
12899 (define_insn "*jcc_1"
12900   [(set (pc)
12901         (if_then_else (match_operator 1 "ix86_comparison_operator"
12902                                       [(reg FLAGS_REG) (const_int 0)])
12903                       (label_ref (match_operand 0 "" ""))
12904                       (pc)))]
12905   ""
12906   "%+j%C1\t%l0"
12907   [(set_attr "type" "ibr")
12908    (set_attr "modrm" "0")
12909    (set (attr "length")
12910            (if_then_else (and (ge (minus (match_dup 0) (pc))
12911                                   (const_int -126))
12912                               (lt (minus (match_dup 0) (pc))
12913                                   (const_int 128)))
12914              (const_int 2)
12915              (const_int 6)))])
12916
12917 (define_insn "*jcc_2"
12918   [(set (pc)
12919         (if_then_else (match_operator 1 "ix86_comparison_operator"
12920                                       [(reg FLAGS_REG) (const_int 0)])
12921                       (pc)
12922                       (label_ref (match_operand 0 "" ""))))]
12923   ""
12924   "%+j%c1\t%l0"
12925   [(set_attr "type" "ibr")
12926    (set_attr "modrm" "0")
12927    (set (attr "length")
12928            (if_then_else (and (ge (minus (match_dup 0) (pc))
12929                                   (const_int -126))
12930                               (lt (minus (match_dup 0) (pc))
12931                                   (const_int 128)))
12932              (const_int 2)
12933              (const_int 6)))])
12934
12935 ;; In general it is not safe to assume too much about CCmode registers,
12936 ;; so simplify-rtx stops when it sees a second one.  Under certain
12937 ;; conditions this is safe on x86, so help combine not create
12938 ;;
12939 ;;      seta    %al
12940 ;;      testb   %al, %al
12941 ;;      je      Lfoo
12942
12943 (define_split
12944   [(set (pc)
12945         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12946                                       [(reg FLAGS_REG) (const_int 0)])
12947                           (const_int 0))
12948                       (label_ref (match_operand 1 "" ""))
12949                       (pc)))]
12950   ""
12951   [(set (pc)
12952         (if_then_else (match_dup 0)
12953                       (label_ref (match_dup 1))
12954                       (pc)))]
12955 {
12956   PUT_MODE (operands[0], VOIDmode);
12957 })
12958
12959 (define_split
12960   [(set (pc)
12961         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12962                                       [(reg FLAGS_REG) (const_int 0)])
12963                           (const_int 0))
12964                       (label_ref (match_operand 1 "" ""))
12965                       (pc)))]
12966   ""
12967   [(set (pc)
12968         (if_then_else (match_dup 0)
12969                       (label_ref (match_dup 1))
12970                       (pc)))]
12971 {
12972   rtx new_op0 = copy_rtx (operands[0]);
12973   operands[0] = new_op0;
12974   PUT_MODE (new_op0, VOIDmode);
12975   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12976                                              GET_MODE (XEXP (new_op0, 0))));
12977
12978   /* Make sure that (a) the CCmode we have for the flags is strong
12979      enough for the reversed compare or (b) we have a valid FP compare.  */
12980   if (! ix86_comparison_operator (new_op0, VOIDmode))
12981     FAIL;
12982 })
12983
12984 ;; zero_extend in SImode is correct, since this is what combine pass
12985 ;; generates from shift insn with QImode operand.  Actually, the mode of
12986 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12987 ;; appropriate modulo of the bit offset value.
12988
12989 (define_insn_and_split "*jcc_btdi_rex64"
12990   [(set (pc)
12991         (if_then_else (match_operator 0 "bt_comparison_operator"
12992                         [(zero_extract:DI
12993                            (match_operand:DI 1 "register_operand" "r")
12994                            (const_int 1)
12995                            (zero_extend:SI
12996                              (match_operand:QI 2 "register_operand" "r")))
12997                          (const_int 0)])
12998                       (label_ref (match_operand 3 "" ""))
12999                       (pc)))
13000    (clobber (reg:CC FLAGS_REG))]
13001   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13002   "#"
13003   "&& 1"
13004   [(set (reg:CCC FLAGS_REG)
13005         (compare:CCC
13006           (zero_extract:DI
13007             (match_dup 1)
13008             (const_int 1)
13009             (match_dup 2))
13010           (const_int 0)))
13011    (set (pc)
13012         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13013                       (label_ref (match_dup 3))
13014                       (pc)))]
13015 {
13016   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13017
13018   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13019 })
13020
13021 ;; avoid useless masking of bit offset operand
13022 (define_insn_and_split "*jcc_btdi_mask_rex64"
13023   [(set (pc)
13024         (if_then_else (match_operator 0 "bt_comparison_operator"
13025                         [(zero_extract:DI
13026                            (match_operand:DI 1 "register_operand" "r")
13027                            (const_int 1)
13028                            (and:SI
13029                              (match_operand:SI 2 "register_operand" "r")
13030                              (match_operand:SI 3 "const_int_operand" "n")))])
13031                       (label_ref (match_operand 4 "" ""))
13032                       (pc)))
13033    (clobber (reg:CC FLAGS_REG))]
13034   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13035    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13036   "#"
13037   "&& 1"
13038   [(set (reg:CCC FLAGS_REG)
13039         (compare:CCC
13040           (zero_extract:DI
13041             (match_dup 1)
13042             (const_int 1)
13043             (match_dup 2))
13044           (const_int 0)))
13045    (set (pc)
13046         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13047                       (label_ref (match_dup 4))
13048                       (pc)))]
13049 {
13050   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13051
13052   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13053 })
13054
13055 (define_insn_and_split "*jcc_btsi"
13056   [(set (pc)
13057         (if_then_else (match_operator 0 "bt_comparison_operator"
13058                         [(zero_extract:SI
13059                            (match_operand:SI 1 "register_operand" "r")
13060                            (const_int 1)
13061                            (zero_extend:SI
13062                              (match_operand:QI 2 "register_operand" "r")))
13063                          (const_int 0)])
13064                       (label_ref (match_operand 3 "" ""))
13065                       (pc)))
13066    (clobber (reg:CC FLAGS_REG))]
13067   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13068   "#"
13069   "&& 1"
13070   [(set (reg:CCC FLAGS_REG)
13071         (compare:CCC
13072           (zero_extract:SI
13073             (match_dup 1)
13074             (const_int 1)
13075             (match_dup 2))
13076           (const_int 0)))
13077    (set (pc)
13078         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13079                       (label_ref (match_dup 3))
13080                       (pc)))]
13081 {
13082   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13083
13084   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13085 })
13086
13087 ;; avoid useless masking of bit offset operand
13088 (define_insn_and_split "*jcc_btsi_mask"
13089   [(set (pc)
13090         (if_then_else (match_operator 0 "bt_comparison_operator"
13091                         [(zero_extract:SI
13092                            (match_operand:SI 1 "register_operand" "r")
13093                            (const_int 1)
13094                            (and:SI
13095                              (match_operand:SI 2 "register_operand" "r")
13096                              (match_operand:SI 3 "const_int_operand" "n")))])
13097                       (label_ref (match_operand 4 "" ""))
13098                       (pc)))
13099    (clobber (reg:CC FLAGS_REG))]
13100   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13101    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13102   "#"
13103   "&& 1"
13104   [(set (reg:CCC FLAGS_REG)
13105         (compare:CCC
13106           (zero_extract:SI
13107             (match_dup 1)
13108             (const_int 1)
13109             (match_dup 2))
13110           (const_int 0)))
13111    (set (pc)
13112         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13113                       (label_ref (match_dup 4))
13114                       (pc)))]
13115   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13116
13117 (define_insn_and_split "*jcc_btsi_1"
13118   [(set (pc)
13119         (if_then_else (match_operator 0 "bt_comparison_operator"
13120                         [(and:SI
13121                            (lshiftrt:SI
13122                              (match_operand:SI 1 "register_operand" "r")
13123                              (match_operand:QI 2 "register_operand" "r"))
13124                            (const_int 1))
13125                          (const_int 0)])
13126                       (label_ref (match_operand 3 "" ""))
13127                       (pc)))
13128    (clobber (reg:CC FLAGS_REG))]
13129   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13130   "#"
13131   "&& 1"
13132   [(set (reg:CCC FLAGS_REG)
13133         (compare:CCC
13134           (zero_extract:SI
13135             (match_dup 1)
13136             (const_int 1)
13137             (match_dup 2))
13138           (const_int 0)))
13139    (set (pc)
13140         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13141                       (label_ref (match_dup 3))
13142                       (pc)))]
13143 {
13144   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13145
13146   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13147 })
13148
13149 ;; avoid useless masking of bit offset operand
13150 (define_insn_and_split "*jcc_btsi_mask_1"
13151   [(set (pc)
13152         (if_then_else
13153           (match_operator 0 "bt_comparison_operator"
13154             [(and:SI
13155                (lshiftrt:SI
13156                  (match_operand:SI 1 "register_operand" "r")
13157                  (subreg:QI
13158                    (and:SI
13159                      (match_operand:SI 2 "register_operand" "r")
13160                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13161                (const_int 1))
13162              (const_int 0)])
13163           (label_ref (match_operand 4 "" ""))
13164           (pc)))
13165    (clobber (reg:CC FLAGS_REG))]
13166   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13167    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13168   "#"
13169   "&& 1"
13170   [(set (reg:CCC FLAGS_REG)
13171         (compare:CCC
13172           (zero_extract:SI
13173             (match_dup 1)
13174             (const_int 1)
13175             (match_dup 2))
13176           (const_int 0)))
13177    (set (pc)
13178         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13179                       (label_ref (match_dup 4))
13180                       (pc)))]
13181   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13182
13183 ;; Define combination compare-and-branch fp compare instructions to help
13184 ;; combine.
13185
13186 (define_insn "*fp_jcc_3_387"
13187   [(set (pc)
13188         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13189                         [(match_operand 1 "register_operand" "f")
13190                          (match_operand 2 "nonimmediate_operand" "fm")])
13191           (label_ref (match_operand 3 "" ""))
13192           (pc)))
13193    (clobber (reg:CCFP FPSR_REG))
13194    (clobber (reg:CCFP FLAGS_REG))
13195    (clobber (match_scratch:HI 4 "=a"))]
13196   "TARGET_80387
13197    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13198    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199    && SELECT_CC_MODE (GET_CODE (operands[0]),
13200                       operands[1], operands[2]) == CCFPmode
13201    && !TARGET_CMOVE"
13202   "#")
13203
13204 (define_insn "*fp_jcc_4_387"
13205   [(set (pc)
13206         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13207                         [(match_operand 1 "register_operand" "f")
13208                          (match_operand 2 "nonimmediate_operand" "fm")])
13209           (pc)
13210           (label_ref (match_operand 3 "" ""))))
13211    (clobber (reg:CCFP FPSR_REG))
13212    (clobber (reg:CCFP FLAGS_REG))
13213    (clobber (match_scratch:HI 4 "=a"))]
13214   "TARGET_80387
13215    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13216    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217    && SELECT_CC_MODE (GET_CODE (operands[0]),
13218                       operands[1], operands[2]) == CCFPmode
13219    && !TARGET_CMOVE"
13220   "#")
13221
13222 (define_insn "*fp_jcc_5_387"
13223   [(set (pc)
13224         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13225                         [(match_operand 1 "register_operand" "f")
13226                          (match_operand 2 "register_operand" "f")])
13227           (label_ref (match_operand 3 "" ""))
13228           (pc)))
13229    (clobber (reg:CCFP FPSR_REG))
13230    (clobber (reg:CCFP FLAGS_REG))
13231    (clobber (match_scratch:HI 4 "=a"))]
13232   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13233    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13234    && !TARGET_CMOVE"
13235   "#")
13236
13237 (define_insn "*fp_jcc_6_387"
13238   [(set (pc)
13239         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13240                         [(match_operand 1 "register_operand" "f")
13241                          (match_operand 2 "register_operand" "f")])
13242           (pc)
13243           (label_ref (match_operand 3 "" ""))))
13244    (clobber (reg:CCFP FPSR_REG))
13245    (clobber (reg:CCFP FLAGS_REG))
13246    (clobber (match_scratch:HI 4 "=a"))]
13247   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13248    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13249    && !TARGET_CMOVE"
13250   "#")
13251
13252 (define_insn "*fp_jcc_7_387"
13253   [(set (pc)
13254         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13255                         [(match_operand 1 "register_operand" "f")
13256                          (match_operand 2 "const0_operand" "")])
13257           (label_ref (match_operand 3 "" ""))
13258           (pc)))
13259    (clobber (reg:CCFP FPSR_REG))
13260    (clobber (reg:CCFP FLAGS_REG))
13261    (clobber (match_scratch:HI 4 "=a"))]
13262   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13263    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13264    && SELECT_CC_MODE (GET_CODE (operands[0]),
13265                       operands[1], operands[2]) == CCFPmode
13266    && !TARGET_CMOVE"
13267   "#")
13268
13269 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13270 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13271 ;; with a precedence over other operators and is always put in the first
13272 ;; place. Swap condition and operands to match ficom instruction.
13273
13274 (define_insn "*fp_jcc_8<mode>_387"
13275   [(set (pc)
13276         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13277                         [(match_operator 1 "float_operator"
13278                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13279                            (match_operand 3 "register_operand" "f,f")])
13280           (label_ref (match_operand 4 "" ""))
13281           (pc)))
13282    (clobber (reg:CCFP FPSR_REG))
13283    (clobber (reg:CCFP FLAGS_REG))
13284    (clobber (match_scratch:HI 5 "=a,a"))]
13285   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13286    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13287    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13288    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13289    && !TARGET_CMOVE"
13290   "#")
13291
13292 (define_split
13293   [(set (pc)
13294         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13295                         [(match_operand 1 "register_operand" "")
13296                          (match_operand 2 "nonimmediate_operand" "")])
13297           (match_operand 3 "" "")
13298           (match_operand 4 "" "")))
13299    (clobber (reg:CCFP FPSR_REG))
13300    (clobber (reg:CCFP FLAGS_REG))]
13301   "reload_completed"
13302   [(const_int 0)]
13303 {
13304   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13305                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13306   DONE;
13307 })
13308
13309 (define_split
13310   [(set (pc)
13311         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13312                         [(match_operand 1 "register_operand" "")
13313                          (match_operand 2 "general_operand" "")])
13314           (match_operand 3 "" "")
13315           (match_operand 4 "" "")))
13316    (clobber (reg:CCFP FPSR_REG))
13317    (clobber (reg:CCFP FLAGS_REG))
13318    (clobber (match_scratch:HI 5 "=a"))]
13319   "reload_completed"
13320   [(const_int 0)]
13321 {
13322   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13323                         operands[3], operands[4], operands[5], NULL_RTX);
13324   DONE;
13325 })
13326
13327 (define_split
13328   [(set (pc)
13329         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13330                         [(match_operator 1 "float_operator"
13331                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13332                            (match_operand 3 "register_operand" "")])
13333           (match_operand 4 "" "")
13334           (match_operand 5 "" "")))
13335    (clobber (reg:CCFP FPSR_REG))
13336    (clobber (reg:CCFP FLAGS_REG))
13337    (clobber (match_scratch:HI 6 "=a"))]
13338   "reload_completed"
13339   [(const_int 0)]
13340 {
13341   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13342   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13343                         operands[3], operands[7],
13344                         operands[4], operands[5], operands[6], NULL_RTX);
13345   DONE;
13346 })
13347
13348 ;; %%% Kill this when reload knows how to do it.
13349 (define_split
13350   [(set (pc)
13351         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13352                         [(match_operator 1 "float_operator"
13353                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13354                            (match_operand 3 "register_operand" "")])
13355           (match_operand 4 "" "")
13356           (match_operand 5 "" "")))
13357    (clobber (reg:CCFP FPSR_REG))
13358    (clobber (reg:CCFP FLAGS_REG))
13359    (clobber (match_scratch:HI 6 "=a"))]
13360   "reload_completed"
13361   [(const_int 0)]
13362 {
13363   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13364   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13365   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13366                         operands[3], operands[7],
13367                         operands[4], operands[5], operands[6], operands[2]);
13368   DONE;
13369 })
13370 \f
13371 ;; Unconditional and other jump instructions
13372
13373 (define_insn "jump"
13374   [(set (pc)
13375         (label_ref (match_operand 0 "" "")))]
13376   ""
13377   "jmp\t%l0"
13378   [(set_attr "type" "ibr")
13379    (set (attr "length")
13380            (if_then_else (and (ge (minus (match_dup 0) (pc))
13381                                   (const_int -126))
13382                               (lt (minus (match_dup 0) (pc))
13383                                   (const_int 128)))
13384              (const_int 2)
13385              (const_int 5)))
13386    (set_attr "modrm" "0")])
13387
13388 (define_expand "indirect_jump"
13389   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13390   ""
13391   "")
13392
13393 (define_insn "*indirect_jump"
13394   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13395   ""
13396   "jmp\t%A0"
13397   [(set_attr "type" "ibr")
13398    (set_attr "length_immediate" "0")])
13399
13400 (define_expand "tablejump"
13401   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13402               (use (label_ref (match_operand 1 "" "")))])]
13403   ""
13404 {
13405   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13406      relative.  Convert the relative address to an absolute address.  */
13407   if (flag_pic)
13408     {
13409       rtx op0, op1;
13410       enum rtx_code code;
13411
13412       /* We can't use @GOTOFF for text labels on VxWorks;
13413          see gotoff_operand.  */
13414       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13415         {
13416           code = PLUS;
13417           op0 = operands[0];
13418           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13419         }
13420       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13421         {
13422           code = PLUS;
13423           op0 = operands[0];
13424           op1 = pic_offset_table_rtx;
13425         }
13426       else
13427         {
13428           code = MINUS;
13429           op0 = pic_offset_table_rtx;
13430           op1 = operands[0];
13431         }
13432
13433       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13434                                          OPTAB_DIRECT);
13435     }
13436 })
13437
13438 (define_insn "*tablejump_1"
13439   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13440    (use (label_ref (match_operand 1 "" "")))]
13441   ""
13442   "jmp\t%A0"
13443   [(set_attr "type" "ibr")
13444    (set_attr "length_immediate" "0")])
13445 \f
13446 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13447
13448 (define_peephole2
13449   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13450    (set (match_operand:QI 1 "register_operand" "")
13451         (match_operator:QI 2 "ix86_comparison_operator"
13452           [(reg FLAGS_REG) (const_int 0)]))
13453    (set (match_operand 3 "q_regs_operand" "")
13454         (zero_extend (match_dup 1)))]
13455   "(peep2_reg_dead_p (3, operands[1])
13456     || operands_match_p (operands[1], operands[3]))
13457    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13458   [(set (match_dup 4) (match_dup 0))
13459    (set (strict_low_part (match_dup 5))
13460         (match_dup 2))]
13461 {
13462   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13463   operands[5] = gen_lowpart (QImode, operands[3]);
13464   ix86_expand_clear (operands[3]);
13465 })
13466
13467 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13468
13469 (define_peephole2
13470   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13471    (set (match_operand:QI 1 "register_operand" "")
13472         (match_operator:QI 2 "ix86_comparison_operator"
13473           [(reg FLAGS_REG) (const_int 0)]))
13474    (parallel [(set (match_operand 3 "q_regs_operand" "")
13475                    (zero_extend (match_dup 1)))
13476               (clobber (reg:CC FLAGS_REG))])]
13477   "(peep2_reg_dead_p (3, operands[1])
13478     || operands_match_p (operands[1], operands[3]))
13479    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13480   [(set (match_dup 4) (match_dup 0))
13481    (set (strict_low_part (match_dup 5))
13482         (match_dup 2))]
13483 {
13484   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13485   operands[5] = gen_lowpart (QImode, operands[3]);
13486   ix86_expand_clear (operands[3]);
13487 })
13488 \f
13489 ;; Call instructions.
13490
13491 ;; The predicates normally associated with named expanders are not properly
13492 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13493 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13494
13495 ;; P6 processors will jump to the address after the decrement when %esp
13496 ;; is used as a call operand, so they will execute return address as a code.
13497 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13498  
13499 ;; Call subroutine returning no value.
13500
13501 (define_expand "call_pop"
13502   [(parallel [(call (match_operand:QI 0 "" "")
13503                     (match_operand:SI 1 "" ""))
13504               (set (reg:SI SP_REG)
13505                    (plus:SI (reg:SI SP_REG)
13506                             (match_operand:SI 3 "" "")))])]
13507   "!TARGET_64BIT"
13508 {
13509   ix86_expand_call (NULL, operands[0], operands[1],
13510                     operands[2], operands[3], 0);
13511   DONE;
13512 })
13513
13514 (define_insn "*call_pop_0"
13515   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13516          (match_operand:SI 1 "" ""))
13517    (set (reg:SI SP_REG)
13518         (plus:SI (reg:SI SP_REG)
13519                  (match_operand:SI 2 "immediate_operand" "")))]
13520   "!TARGET_64BIT"
13521 {
13522   if (SIBLING_CALL_P (insn))
13523     return "jmp\t%P0";
13524   else
13525     return "call\t%P0";
13526 }
13527   [(set_attr "type" "call")])
13528
13529 (define_insn "*call_pop_1"
13530   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13531          (match_operand:SI 1 "" ""))
13532    (set (reg:SI SP_REG)
13533         (plus:SI (reg:SI SP_REG)
13534                  (match_operand:SI 2 "immediate_operand" "i")))]
13535   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13536 {
13537   if (constant_call_address_operand (operands[0], Pmode))
13538     return "call\t%P0";
13539   return "call\t%A0";
13540 }
13541   [(set_attr "type" "call")])
13542
13543 (define_insn "*sibcall_pop_1"
13544   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13545          (match_operand:SI 1 "" ""))
13546    (set (reg:SI SP_REG)
13547         (plus:SI (reg:SI SP_REG)
13548                  (match_operand:SI 2 "immediate_operand" "i,i")))]
13549   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13550   "@
13551    jmp\t%P0
13552    jmp\t%A0"
13553   [(set_attr "type" "call")])
13554
13555 (define_expand "call"
13556   [(call (match_operand:QI 0 "" "")
13557          (match_operand 1 "" ""))
13558    (use (match_operand 2 "" ""))]
13559   ""
13560 {
13561   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13562   DONE;
13563 })
13564
13565 (define_expand "sibcall"
13566   [(call (match_operand:QI 0 "" "")
13567          (match_operand 1 "" ""))
13568    (use (match_operand 2 "" ""))]
13569   ""
13570 {
13571   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13572   DONE;
13573 })
13574
13575 (define_insn "*call_0"
13576   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13577          (match_operand 1 "" ""))]
13578   ""
13579 {
13580   if (SIBLING_CALL_P (insn))
13581     return "jmp\t%P0";
13582   else
13583     return "call\t%P0";
13584 }
13585   [(set_attr "type" "call")])
13586
13587 (define_insn "*call_1"
13588   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13589          (match_operand 1 "" ""))]
13590   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13591 {
13592   if (constant_call_address_operand (operands[0], Pmode))
13593     return "call\t%P0";
13594   return "call\t%A0";
13595 }
13596   [(set_attr "type" "call")])
13597
13598 (define_insn "*sibcall_1"
13599   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13600          (match_operand 1 "" ""))]
13601   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13602   "@
13603    jmp\t%P0
13604    jmp\t%A0"
13605   [(set_attr "type" "call")])
13606
13607 (define_insn "*call_1_rex64"
13608   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13609          (match_operand 1 "" ""))]
13610   "TARGET_64BIT && !SIBLING_CALL_P (insn)
13611    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13612 {
13613   if (constant_call_address_operand (operands[0], Pmode))
13614     return "call\t%P0";
13615   return "call\t%A0";
13616 }
13617   [(set_attr "type" "call")])
13618
13619 (define_insn "*call_1_rex64_ms_sysv"
13620   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13621          (match_operand 1 "" ""))
13622    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13623    (clobber (reg:TI XMM6_REG))
13624    (clobber (reg:TI XMM7_REG))
13625    (clobber (reg:TI XMM8_REG))
13626    (clobber (reg:TI XMM9_REG))
13627    (clobber (reg:TI XMM10_REG))
13628    (clobber (reg:TI XMM11_REG))
13629    (clobber (reg:TI XMM12_REG))
13630    (clobber (reg:TI XMM13_REG))
13631    (clobber (reg:TI XMM14_REG))
13632    (clobber (reg:TI XMM15_REG))
13633    (clobber (reg:DI SI_REG))
13634    (clobber (reg:DI DI_REG))]
13635   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13636 {
13637   if (constant_call_address_operand (operands[0], Pmode))
13638     return "call\t%P0";
13639   return "call\t%A0";
13640 }
13641   [(set_attr "type" "call")])
13642
13643 (define_insn "*call_1_rex64_large"
13644   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13645          (match_operand 1 "" ""))]
13646   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13647   "call\t%A0"
13648   [(set_attr "type" "call")])
13649
13650 (define_insn "*sibcall_1_rex64"
13651   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13652          (match_operand 1 "" ""))]
13653   "TARGET_64BIT && SIBLING_CALL_P (insn)"
13654   "@
13655    jmp\t%P0
13656    jmp\t%A0"
13657   [(set_attr "type" "call")])
13658
13659 ;; Call subroutine, returning value in operand 0
13660 (define_expand "call_value_pop"
13661   [(parallel [(set (match_operand 0 "" "")
13662                    (call (match_operand:QI 1 "" "")
13663                          (match_operand:SI 2 "" "")))
13664               (set (reg:SI SP_REG)
13665                    (plus:SI (reg:SI SP_REG)
13666                             (match_operand:SI 4 "" "")))])]
13667   "!TARGET_64BIT"
13668 {
13669   ix86_expand_call (operands[0], operands[1], operands[2],
13670                     operands[3], operands[4], 0);
13671   DONE;
13672 })
13673
13674 (define_expand "call_value"
13675   [(set (match_operand 0 "" "")
13676         (call (match_operand:QI 1 "" "")
13677               (match_operand:SI 2 "" "")))
13678    (use (match_operand:SI 3 "" ""))]
13679   ;; Operand 3 is not used on the i386.
13680   ""
13681 {
13682   ix86_expand_call (operands[0], operands[1], operands[2],
13683                     operands[3], NULL, 0);
13684   DONE;
13685 })
13686
13687 (define_expand "sibcall_value"
13688   [(set (match_operand 0 "" "")
13689         (call (match_operand:QI 1 "" "")
13690               (match_operand:SI 2 "" "")))
13691    (use (match_operand:SI 3 "" ""))]
13692   ;; Operand 3 is not used on the i386.
13693   ""
13694 {
13695   ix86_expand_call (operands[0], operands[1], operands[2],
13696                     operands[3], NULL, 1);
13697   DONE;
13698 })
13699
13700 ;; Call subroutine returning any type.
13701
13702 (define_expand "untyped_call"
13703   [(parallel [(call (match_operand 0 "" "")
13704                     (const_int 0))
13705               (match_operand 1 "" "")
13706               (match_operand 2 "" "")])]
13707   ""
13708 {
13709   int i;
13710
13711   /* In order to give reg-stack an easier job in validating two
13712      coprocessor registers as containing a possible return value,
13713      simply pretend the untyped call returns a complex long double
13714      value. 
13715
13716      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13717      and should have the default ABI.  */
13718
13719   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13720                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13721                     operands[0], const0_rtx,
13722                     GEN_INT ((TARGET_64BIT
13723                               ? (ix86_abi == SYSV_ABI
13724                                  ? X86_64_SSE_REGPARM_MAX
13725                                  : X86_64_MS_SSE_REGPARM_MAX)
13726                               : X86_32_SSE_REGPARM_MAX)
13727                              - 1),
13728                     NULL, 0);
13729
13730   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13731     {
13732       rtx set = XVECEXP (operands[2], 0, i);
13733       emit_move_insn (SET_DEST (set), SET_SRC (set));
13734     }
13735
13736   /* The optimizer does not know that the call sets the function value
13737      registers we stored in the result block.  We avoid problems by
13738      claiming that all hard registers are used and clobbered at this
13739      point.  */
13740   emit_insn (gen_blockage ());
13741
13742   DONE;
13743 })
13744 \f
13745 ;; Prologue and epilogue instructions
13746
13747 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13748 ;; all of memory.  This blocks insns from being moved across this point.
13749
13750 (define_insn "blockage"
13751   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13752   ""
13753   ""
13754   [(set_attr "length" "0")])
13755
13756 ;; Do not schedule instructions accessing memory across this point.
13757
13758 (define_expand "memory_blockage"
13759   [(set (match_dup 0)
13760         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13761   ""
13762 {
13763   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13764   MEM_VOLATILE_P (operands[0]) = 1;
13765 })
13766
13767 (define_insn "*memory_blockage"
13768   [(set (match_operand:BLK 0 "" "")
13769         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13770   ""
13771   ""
13772   [(set_attr "length" "0")])
13773
13774 ;; As USE insns aren't meaningful after reload, this is used instead
13775 ;; to prevent deleting instructions setting registers for PIC code
13776 (define_insn "prologue_use"
13777   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13778   ""
13779   ""
13780   [(set_attr "length" "0")])
13781
13782 ;; Insn emitted into the body of a function to return from a function.
13783 ;; This is only done if the function's epilogue is known to be simple.
13784 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13785
13786 (define_expand "return"
13787   [(return)]
13788   "ix86_can_use_return_insn_p ()"
13789 {
13790   if (crtl->args.pops_args)
13791     {
13792       rtx popc = GEN_INT (crtl->args.pops_args);
13793       emit_jump_insn (gen_return_pop_internal (popc));
13794       DONE;
13795     }
13796 })
13797
13798 (define_insn "return_internal"
13799   [(return)]
13800   "reload_completed"
13801   "ret"
13802   [(set_attr "length" "1")
13803    (set_attr "atom_unit" "jeu")
13804    (set_attr "length_immediate" "0")
13805    (set_attr "modrm" "0")])
13806
13807 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13808 ;; instruction Athlon and K8 have.
13809
13810 (define_insn "return_internal_long"
13811   [(return)
13812    (unspec [(const_int 0)] UNSPEC_REP)]
13813   "reload_completed"
13814   "rep\;ret"
13815   [(set_attr "length" "2")
13816    (set_attr "atom_unit" "jeu")
13817    (set_attr "length_immediate" "0")
13818    (set_attr "prefix_rep" "1")
13819    (set_attr "modrm" "0")])
13820
13821 (define_insn "return_pop_internal"
13822   [(return)
13823    (use (match_operand:SI 0 "const_int_operand" ""))]
13824   "reload_completed"
13825   "ret\t%0"
13826   [(set_attr "length" "3")
13827    (set_attr "atom_unit" "jeu")
13828    (set_attr "length_immediate" "2")
13829    (set_attr "modrm" "0")])
13830
13831 (define_insn "return_indirect_internal"
13832   [(return)
13833    (use (match_operand:SI 0 "register_operand" "r"))]
13834   "reload_completed"
13835   "jmp\t%A0"
13836   [(set_attr "type" "ibr")
13837    (set_attr "length_immediate" "0")])
13838
13839 (define_insn "nop"
13840   [(const_int 0)]
13841   ""
13842   "nop"
13843   [(set_attr "length" "1")
13844    (set_attr "length_immediate" "0")
13845    (set_attr "modrm" "0")])
13846
13847 (define_insn "vswapmov"
13848   [(set (match_operand:SI 0 "register_operand" "=r")
13849         (match_operand:SI 1 "register_operand" "r"))
13850    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13851   ""
13852   "movl.s\t{%1, %0|%0, %1}"
13853   [(set_attr "length" "2")
13854    (set_attr "length_immediate" "0")
13855    (set_attr "modrm" "0")])
13856
13857 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13858 ;; branch prediction penalty for the third jump in a 16-byte
13859 ;; block on K8.
13860
13861 (define_insn "pad"
13862   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13863   ""
13864 {
13865 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13866   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13867 #else
13868   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13869      The align insn is used to avoid 3 jump instructions in the row to improve
13870      branch prediction and the benefits hardly outweigh the cost of extra 8
13871      nops on the average inserted by full alignment pseudo operation.  */
13872 #endif
13873   return "";
13874 }
13875   [(set_attr "length" "16")])
13876
13877 (define_expand "prologue"
13878   [(const_int 0)]
13879   ""
13880   "ix86_expand_prologue (); DONE;")
13881
13882 (define_insn "set_got"
13883   [(set (match_operand:SI 0 "register_operand" "=r")
13884         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13885    (clobber (reg:CC FLAGS_REG))]
13886   "!TARGET_64BIT"
13887   { return output_set_got (operands[0], NULL_RTX); }
13888   [(set_attr "type" "multi")
13889    (set_attr "length" "12")])
13890
13891 (define_insn "set_got_labelled"
13892   [(set (match_operand:SI 0 "register_operand" "=r")
13893         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13894          UNSPEC_SET_GOT))
13895    (clobber (reg:CC FLAGS_REG))]
13896   "!TARGET_64BIT"
13897   { return output_set_got (operands[0], operands[1]); }
13898   [(set_attr "type" "multi")
13899    (set_attr "length" "12")])
13900
13901 (define_insn "set_got_rex64"
13902   [(set (match_operand:DI 0 "register_operand" "=r")
13903         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13904   "TARGET_64BIT"
13905   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13906   [(set_attr "type" "lea")
13907    (set_attr "length_address" "4")
13908    (set_attr "mode" "DI")])
13909
13910 (define_insn "set_rip_rex64"
13911   [(set (match_operand:DI 0 "register_operand" "=r")
13912         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13913   "TARGET_64BIT"
13914   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13915   [(set_attr "type" "lea")
13916    (set_attr "length_address" "4")
13917    (set_attr "mode" "DI")])
13918
13919 (define_insn "set_got_offset_rex64"
13920   [(set (match_operand:DI 0 "register_operand" "=r")
13921         (unspec:DI
13922           [(label_ref (match_operand 1 "" ""))]
13923           UNSPEC_SET_GOT_OFFSET))]
13924   "TARGET_64BIT"
13925   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13926   [(set_attr "type" "imov")
13927    (set_attr "length_immediate" "0")
13928    (set_attr "length_address" "8")
13929    (set_attr "mode" "DI")])
13930
13931 (define_expand "epilogue"
13932   [(const_int 0)]
13933   ""
13934   "ix86_expand_epilogue (1); DONE;")
13935
13936 (define_expand "sibcall_epilogue"
13937   [(const_int 0)]
13938   ""
13939   "ix86_expand_epilogue (0); DONE;")
13940
13941 (define_expand "eh_return"
13942   [(use (match_operand 0 "register_operand" ""))]
13943   ""
13944 {
13945   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13946
13947   /* Tricky bit: we write the address of the handler to which we will
13948      be returning into someone else's stack frame, one word below the
13949      stack address we wish to restore.  */
13950   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13951   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13952   tmp = gen_rtx_MEM (Pmode, tmp);
13953   emit_move_insn (tmp, ra);
13954
13955   emit_jump_insn (gen_eh_return_internal ());
13956   emit_barrier ();
13957   DONE;
13958 })
13959
13960 (define_insn_and_split "eh_return_internal"
13961   [(eh_return)]
13962   ""
13963   "#"
13964   "epilogue_completed"
13965   [(const_int 0)]
13966   "ix86_expand_epilogue (2); DONE;")
13967
13968 (define_insn "leave"
13969   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13970    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13971    (clobber (mem:BLK (scratch)))]
13972   "!TARGET_64BIT"
13973   "leave"
13974   [(set_attr "type" "leave")])
13975
13976 (define_insn "leave_rex64"
13977   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13978    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13979    (clobber (mem:BLK (scratch)))]
13980   "TARGET_64BIT"
13981   "leave"
13982   [(set_attr "type" "leave")])
13983 \f
13984 (define_expand "ffssi2"
13985   [(parallel
13986      [(set (match_operand:SI 0 "register_operand" "")
13987            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13988       (clobber (match_scratch:SI 2 ""))
13989       (clobber (reg:CC FLAGS_REG))])]
13990   ""
13991 {
13992   if (TARGET_CMOVE)
13993     {
13994       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13995       DONE;
13996     }
13997 })
13998
13999 (define_expand "ffs_cmove"
14000   [(set (match_dup 2) (const_int -1))
14001    (parallel [(set (reg:CCZ FLAGS_REG)
14002                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14003                                 (const_int 0)))
14004               (set (match_operand:SI 0 "register_operand" "")
14005                    (ctz:SI (match_dup 1)))])
14006    (set (match_dup 0) (if_then_else:SI
14007                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14008                         (match_dup 2)
14009                         (match_dup 0)))
14010    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14011               (clobber (reg:CC FLAGS_REG))])]
14012   "TARGET_CMOVE"
14013   "operands[2] = gen_reg_rtx (SImode);")
14014
14015 (define_insn_and_split "*ffs_no_cmove"
14016   [(set (match_operand:SI 0 "register_operand" "=r")
14017         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:SI 2 "=&q"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   "!TARGET_CMOVE"
14021   "#"
14022   "&& reload_completed"
14023   [(parallel [(set (reg:CCZ FLAGS_REG)
14024                    (compare:CCZ (match_dup 1) (const_int 0)))
14025               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14026    (set (strict_low_part (match_dup 3))
14027         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14028    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14029               (clobber (reg:CC FLAGS_REG))])
14030    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14031               (clobber (reg:CC FLAGS_REG))])
14032    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14033               (clobber (reg:CC FLAGS_REG))])]
14034 {
14035   operands[3] = gen_lowpart (QImode, operands[2]);
14036   ix86_expand_clear (operands[2]);
14037 })
14038
14039 (define_insn "*ffssi_1"
14040   [(set (reg:CCZ FLAGS_REG)
14041         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14042                      (const_int 0)))
14043    (set (match_operand:SI 0 "register_operand" "=r")
14044         (ctz:SI (match_dup 1)))]
14045   ""
14046   "bsf{l}\t{%1, %0|%0, %1}"
14047   [(set_attr "type" "alu1")
14048    (set_attr "prefix_0f" "1")
14049    (set_attr "mode" "SI")])
14050
14051 (define_expand "ffsdi2"
14052   [(set (match_dup 2) (const_int -1))
14053    (parallel [(set (reg:CCZ FLAGS_REG)
14054                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14055                                 (const_int 0)))
14056               (set (match_operand:DI 0 "register_operand" "")
14057                    (ctz:DI (match_dup 1)))])
14058    (set (match_dup 0) (if_then_else:DI
14059                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14060                         (match_dup 2)
14061                         (match_dup 0)))
14062    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14063               (clobber (reg:CC FLAGS_REG))])]
14064   "TARGET_64BIT"
14065   "operands[2] = gen_reg_rtx (DImode);")
14066
14067 (define_insn "*ffsdi_1"
14068   [(set (reg:CCZ FLAGS_REG)
14069         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14070                      (const_int 0)))
14071    (set (match_operand:DI 0 "register_operand" "=r")
14072         (ctz:DI (match_dup 1)))]
14073   "TARGET_64BIT"
14074   "bsf{q}\t{%1, %0|%0, %1}"
14075   [(set_attr "type" "alu1")
14076    (set_attr "prefix_0f" "1")
14077    (set_attr "mode" "DI")])
14078
14079 (define_insn "ctzsi2"
14080   [(set (match_operand:SI 0 "register_operand" "=r")
14081         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14082    (clobber (reg:CC FLAGS_REG))]
14083   ""
14084   "bsf{l}\t{%1, %0|%0, %1}"
14085   [(set_attr "type" "alu1")
14086    (set_attr "prefix_0f" "1")
14087    (set_attr "mode" "SI")])
14088
14089 (define_insn "ctzdi2"
14090   [(set (match_operand:DI 0 "register_operand" "=r")
14091         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14092    (clobber (reg:CC FLAGS_REG))]
14093   "TARGET_64BIT"
14094   "bsf{q}\t{%1, %0|%0, %1}"
14095   [(set_attr "type" "alu1")
14096    (set_attr "prefix_0f" "1")
14097    (set_attr "mode" "DI")])
14098
14099 (define_expand "clzsi2"
14100   [(parallel
14101      [(set (match_operand:SI 0 "register_operand" "")
14102            (minus:SI (const_int 31)
14103                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14104       (clobber (reg:CC FLAGS_REG))])
14105    (parallel
14106      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14107       (clobber (reg:CC FLAGS_REG))])]
14108   ""
14109 {
14110   if (TARGET_ABM)
14111     {
14112       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14113       DONE;
14114     }
14115 })
14116
14117 (define_insn "clzsi2_abm"
14118   [(set (match_operand:SI 0 "register_operand" "=r")
14119         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "TARGET_ABM"
14122   "lzcnt{l}\t{%1, %0|%0, %1}"
14123   [(set_attr "prefix_rep" "1")
14124    (set_attr "type" "bitmanip")
14125    (set_attr "mode" "SI")])
14126
14127 (define_insn "bsr"
14128   [(set (match_operand:SI 0 "register_operand" "=r")
14129         (minus:SI (const_int 31)
14130                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14131    (clobber (reg:CC FLAGS_REG))]
14132   ""
14133   "bsr{l}\t{%1, %0|%0, %1}"
14134   [(set_attr "type" "alu1")
14135    (set_attr "prefix_0f" "1")
14136    (set_attr "mode" "SI")])
14137
14138 (define_insn "popcount<mode>2"
14139   [(set (match_operand:SWI248 0 "register_operand" "=r")
14140         (popcount:SWI248
14141           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "TARGET_POPCNT"
14144 {
14145 #if TARGET_MACHO
14146   return "popcnt\t{%1, %0|%0, %1}";
14147 #else
14148   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14149 #endif
14150 }
14151   [(set_attr "prefix_rep" "1")
14152    (set_attr "type" "bitmanip")
14153    (set_attr "mode" "<MODE>")])
14154
14155 (define_insn "*popcount<mode>2_cmp"
14156   [(set (reg FLAGS_REG)
14157         (compare
14158           (popcount:SWI248
14159             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14160           (const_int 0)))
14161    (set (match_operand:SWI248 0 "register_operand" "=r")
14162         (popcount:SWI248 (match_dup 1)))]
14163   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14164 {
14165 #if TARGET_MACHO
14166   return "popcnt\t{%1, %0|%0, %1}";
14167 #else
14168   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14169 #endif
14170 }
14171   [(set_attr "prefix_rep" "1")
14172    (set_attr "type" "bitmanip")
14173    (set_attr "mode" "<MODE>")])
14174
14175 (define_insn "*popcountsi2_cmp_zext"
14176   [(set (reg FLAGS_REG)
14177         (compare
14178           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14179           (const_int 0)))
14180    (set (match_operand:DI 0 "register_operand" "=r")
14181         (zero_extend:DI(popcount:SI (match_dup 1))))]
14182   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14183 {
14184 #if TARGET_MACHO
14185   return "popcnt\t{%1, %0|%0, %1}";
14186 #else
14187   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14188 #endif
14189 }
14190   [(set_attr "prefix_rep" "1")
14191    (set_attr "type" "bitmanip")
14192    (set_attr "mode" "SI")])
14193
14194 (define_expand "bswapsi2"
14195   [(set (match_operand:SI 0 "register_operand" "")
14196         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14197   ""
14198 {
14199   if (!(TARGET_BSWAP || TARGET_MOVBE))
14200     {
14201       rtx x = operands[0];
14202
14203       emit_move_insn (x, operands[1]);
14204       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14205       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14206       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14207       DONE;
14208     }
14209 })
14210
14211 (define_insn "*bswapsi_movbe"
14212   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14213         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14214   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14215   "@
14216     bswap\t%0
14217     movbe\t{%1, %0|%0, %1}
14218     movbe\t{%1, %0|%0, %1}"
14219   [(set_attr "type" "*,imov,imov")
14220    (set_attr "modrm" "*,1,1")
14221    (set_attr "prefix_0f" "1")
14222    (set_attr "prefix_extra" "*,1,1")
14223    (set_attr "length" "2,*,*")
14224    (set_attr "mode" "SI")])
14225
14226 (define_insn "*bswapsi_1"
14227   [(set (match_operand:SI 0 "register_operand" "=r")
14228         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14229   "TARGET_BSWAP"
14230   "bswap\t%0"
14231   [(set_attr "prefix_0f" "1")
14232    (set_attr "length" "2")])
14233
14234 (define_insn "*bswaphi_lowpart_1"
14235   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14236         (bswap:HI (match_dup 0)))
14237    (clobber (reg:CC FLAGS_REG))]
14238   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14239   "@
14240     xchg{b}\t{%h0, %b0|%b0, %h0}
14241     rol{w}\t{$8, %0|%0, 8}"
14242   [(set_attr "length" "2,4")
14243    (set_attr "mode" "QI,HI")])
14244
14245 (define_insn "bswaphi_lowpart"
14246   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14247         (bswap:HI (match_dup 0)))
14248    (clobber (reg:CC FLAGS_REG))]
14249   ""
14250   "rol{w}\t{$8, %0|%0, 8}"
14251   [(set_attr "length" "4")
14252    (set_attr "mode" "HI")])
14253
14254 (define_expand "bswapdi2"
14255   [(set (match_operand:DI 0 "register_operand" "")
14256         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14257   "TARGET_64BIT"
14258   "")
14259
14260 (define_insn "*bswapdi_movbe"
14261   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14262         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14263   "TARGET_64BIT && TARGET_MOVBE
14264    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14265   "@
14266     bswap\t%0
14267     movbe\t{%1, %0|%0, %1}
14268     movbe\t{%1, %0|%0, %1}"
14269   [(set_attr "type" "*,imov,imov")
14270    (set_attr "modrm" "*,1,1")
14271    (set_attr "prefix_0f" "1")
14272    (set_attr "prefix_extra" "*,1,1")
14273    (set_attr "length" "3,*,*")
14274    (set_attr "mode" "DI")])
14275
14276 (define_insn "*bswapdi_1"
14277   [(set (match_operand:DI 0 "register_operand" "=r")
14278         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14279   "TARGET_64BIT"
14280   "bswap\t%0"
14281   [(set_attr "prefix_0f" "1")
14282    (set_attr "length" "3")])
14283
14284 (define_expand "clzdi2"
14285   [(parallel
14286      [(set (match_operand:DI 0 "register_operand" "")
14287            (minus:DI (const_int 63)
14288                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14289       (clobber (reg:CC FLAGS_REG))])
14290    (parallel
14291      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14292       (clobber (reg:CC FLAGS_REG))])]
14293   "TARGET_64BIT"
14294 {
14295   if (TARGET_ABM)
14296     {
14297       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14298       DONE;
14299     }
14300 })
14301
14302 (define_insn "clzdi2_abm"
14303   [(set (match_operand:DI 0 "register_operand" "=r")
14304         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14305    (clobber (reg:CC FLAGS_REG))]
14306   "TARGET_64BIT && TARGET_ABM"
14307   "lzcnt{q}\t{%1, %0|%0, %1}"
14308   [(set_attr "prefix_rep" "1")
14309    (set_attr "type" "bitmanip")
14310    (set_attr "mode" "DI")])
14311
14312 (define_insn "bsr_rex64"
14313   [(set (match_operand:DI 0 "register_operand" "=r")
14314         (minus:DI (const_int 63)
14315                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14316    (clobber (reg:CC FLAGS_REG))]
14317   "TARGET_64BIT"
14318   "bsr{q}\t{%1, %0|%0, %1}"
14319   [(set_attr "type" "alu1")
14320    (set_attr "prefix_0f" "1")
14321    (set_attr "mode" "DI")])
14322
14323 (define_expand "clzhi2"
14324   [(parallel
14325      [(set (match_operand:HI 0 "register_operand" "")
14326            (minus:HI (const_int 15)
14327                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14328       (clobber (reg:CC FLAGS_REG))])
14329    (parallel
14330      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14331       (clobber (reg:CC FLAGS_REG))])]
14332   ""
14333 {
14334   if (TARGET_ABM)
14335     {
14336       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14337       DONE;
14338     }
14339 })
14340
14341 (define_insn "clzhi2_abm"
14342   [(set (match_operand:HI 0 "register_operand" "=r")
14343         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14344    (clobber (reg:CC FLAGS_REG))]
14345   "TARGET_ABM"
14346   "lzcnt{w}\t{%1, %0|%0, %1}"
14347   [(set_attr "prefix_rep" "1")
14348    (set_attr "type" "bitmanip")
14349    (set_attr "mode" "HI")])
14350
14351 (define_insn "*bsrhi"
14352   [(set (match_operand:HI 0 "register_operand" "=r")
14353         (minus:HI (const_int 15)
14354                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14355    (clobber (reg:CC FLAGS_REG))]
14356   ""
14357   "bsr{w}\t{%1, %0|%0, %1}"
14358   [(set_attr "type" "alu1")
14359    (set_attr "prefix_0f" "1")
14360    (set_attr "mode" "HI")])
14361
14362 (define_expand "paritydi2"
14363   [(set (match_operand:DI 0 "register_operand" "")
14364         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14365   "! TARGET_POPCNT"
14366 {
14367   rtx scratch = gen_reg_rtx (QImode);
14368   rtx cond;
14369
14370   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14371                                 NULL_RTX, operands[1]));
14372
14373   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14374                          gen_rtx_REG (CCmode, FLAGS_REG),
14375                          const0_rtx);
14376   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14377
14378   if (TARGET_64BIT)
14379     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14380   else
14381     {
14382       rtx tmp = gen_reg_rtx (SImode);
14383
14384       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14385       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14386     }
14387   DONE;
14388 })
14389
14390 (define_insn_and_split "paritydi2_cmp"
14391   [(set (reg:CC FLAGS_REG)
14392         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14393    (clobber (match_scratch:DI 0 "=r"))
14394    (clobber (match_scratch:SI 1 "=&r"))
14395    (clobber (match_scratch:HI 2 "=Q"))]
14396   "! TARGET_POPCNT"
14397   "#"
14398   "&& reload_completed"
14399   [(parallel
14400      [(set (match_dup 1)
14401            (xor:SI (match_dup 1) (match_dup 4)))
14402       (clobber (reg:CC FLAGS_REG))])
14403    (parallel
14404      [(set (reg:CC FLAGS_REG)
14405            (parity:CC (match_dup 1)))
14406       (clobber (match_dup 1))
14407       (clobber (match_dup 2))])]
14408 {
14409   operands[4] = gen_lowpart (SImode, operands[3]);
14410
14411   if (TARGET_64BIT)
14412     {
14413       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14414       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14415     }
14416   else
14417     operands[1] = gen_highpart (SImode, operands[3]);
14418 })
14419
14420 (define_expand "paritysi2"
14421   [(set (match_operand:SI 0 "register_operand" "")
14422         (parity:SI (match_operand:SI 1 "register_operand" "")))]
14423   "! TARGET_POPCNT"
14424 {
14425   rtx scratch = gen_reg_rtx (QImode);
14426   rtx cond;
14427
14428   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14429
14430   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14431                          gen_rtx_REG (CCmode, FLAGS_REG),
14432                          const0_rtx);
14433   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14434
14435   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14436   DONE;
14437 })
14438
14439 (define_insn_and_split "paritysi2_cmp"
14440   [(set (reg:CC FLAGS_REG)
14441         (parity:CC (match_operand:SI 2 "register_operand" "0")))
14442    (clobber (match_scratch:SI 0 "=r"))
14443    (clobber (match_scratch:HI 1 "=&Q"))]
14444   "! TARGET_POPCNT"
14445   "#"
14446   "&& reload_completed"
14447   [(parallel
14448      [(set (match_dup 1)
14449            (xor:HI (match_dup 1) (match_dup 3)))
14450       (clobber (reg:CC FLAGS_REG))])
14451    (parallel
14452      [(set (reg:CC FLAGS_REG)
14453            (parity:CC (match_dup 1)))
14454       (clobber (match_dup 1))])]
14455 {
14456   operands[3] = gen_lowpart (HImode, operands[2]);
14457
14458   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14459   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14460 })
14461
14462 (define_insn "*parityhi2_cmp"
14463   [(set (reg:CC FLAGS_REG)
14464         (parity:CC (match_operand:HI 1 "register_operand" "0")))
14465    (clobber (match_scratch:HI 0 "=Q"))]
14466   "! TARGET_POPCNT"
14467   "xor{b}\t{%h0, %b0|%b0, %h0}"
14468   [(set_attr "length" "2")
14469    (set_attr "mode" "HI")])
14470
14471 (define_insn "*parityqi2_cmp"
14472   [(set (reg:CC FLAGS_REG)
14473         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14474   "! TARGET_POPCNT"
14475   "test{b}\t%0, %0"
14476   [(set_attr "length" "2")
14477    (set_attr "mode" "QI")])
14478 \f
14479 ;; Thread-local storage patterns for ELF.
14480 ;;
14481 ;; Note that these code sequences must appear exactly as shown
14482 ;; in order to allow linker relaxation.
14483
14484 (define_insn "*tls_global_dynamic_32_gnu"
14485   [(set (match_operand:SI 0 "register_operand" "=a")
14486         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14487                     (match_operand:SI 2 "tls_symbolic_operand" "")
14488                     (match_operand:SI 3 "call_insn_operand" "")]
14489                     UNSPEC_TLS_GD))
14490    (clobber (match_scratch:SI 4 "=d"))
14491    (clobber (match_scratch:SI 5 "=c"))
14492    (clobber (reg:CC FLAGS_REG))]
14493   "!TARGET_64BIT && TARGET_GNU_TLS"
14494   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14495   [(set_attr "type" "multi")
14496    (set_attr "length" "12")])
14497
14498 (define_insn "*tls_global_dynamic_32_sun"
14499   [(set (match_operand:SI 0 "register_operand" "=a")
14500         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14501                     (match_operand:SI 2 "tls_symbolic_operand" "")
14502                     (match_operand:SI 3 "call_insn_operand" "")]
14503                     UNSPEC_TLS_GD))
14504    (clobber (match_scratch:SI 4 "=d"))
14505    (clobber (match_scratch:SI 5 "=c"))
14506    (clobber (reg:CC FLAGS_REG))]
14507   "!TARGET_64BIT && TARGET_SUN_TLS"
14508   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14509         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14510   [(set_attr "type" "multi")
14511    (set_attr "length" "14")])
14512
14513 (define_expand "tls_global_dynamic_32"
14514   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14515                    (unspec:SI
14516                     [(match_dup 2)
14517                      (match_operand:SI 1 "tls_symbolic_operand" "")
14518                      (match_dup 3)]
14519                     UNSPEC_TLS_GD))
14520               (clobber (match_scratch:SI 4 ""))
14521               (clobber (match_scratch:SI 5 ""))
14522               (clobber (reg:CC FLAGS_REG))])]
14523   ""
14524 {
14525   if (flag_pic)
14526     operands[2] = pic_offset_table_rtx;
14527   else
14528     {
14529       operands[2] = gen_reg_rtx (Pmode);
14530       emit_insn (gen_set_got (operands[2]));
14531     }
14532   if (TARGET_GNU2_TLS)
14533     {
14534        emit_insn (gen_tls_dynamic_gnu2_32
14535                   (operands[0], operands[1], operands[2]));
14536        DONE;
14537     }
14538   operands[3] = ix86_tls_get_addr ();
14539 })
14540
14541 (define_insn "*tls_global_dynamic_64"
14542   [(set (match_operand:DI 0 "register_operand" "=a")
14543         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14544                  (match_operand:DI 3 "" "")))
14545    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14546               UNSPEC_TLS_GD)]
14547   "TARGET_64BIT"
14548   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
14549   [(set_attr "type" "multi")
14550    (set_attr "length" "16")])
14551
14552 (define_expand "tls_global_dynamic_64"
14553   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14554                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14555               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14556                          UNSPEC_TLS_GD)])]
14557   ""
14558 {
14559   if (TARGET_GNU2_TLS)
14560     {
14561        emit_insn (gen_tls_dynamic_gnu2_64
14562                   (operands[0], operands[1]));
14563        DONE;
14564     }
14565   operands[2] = ix86_tls_get_addr ();
14566 })
14567
14568 (define_insn "*tls_local_dynamic_base_32_gnu"
14569   [(set (match_operand:SI 0 "register_operand" "=a")
14570         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14571                     (match_operand:SI 2 "call_insn_operand" "")]
14572                    UNSPEC_TLS_LD_BASE))
14573    (clobber (match_scratch:SI 3 "=d"))
14574    (clobber (match_scratch:SI 4 "=c"))
14575    (clobber (reg:CC FLAGS_REG))]
14576   "!TARGET_64BIT && TARGET_GNU_TLS"
14577   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14578   [(set_attr "type" "multi")
14579    (set_attr "length" "11")])
14580
14581 (define_insn "*tls_local_dynamic_base_32_sun"
14582   [(set (match_operand:SI 0 "register_operand" "=a")
14583         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14584                     (match_operand:SI 2 "call_insn_operand" "")]
14585                    UNSPEC_TLS_LD_BASE))
14586    (clobber (match_scratch:SI 3 "=d"))
14587    (clobber (match_scratch:SI 4 "=c"))
14588    (clobber (reg:CC FLAGS_REG))]
14589   "!TARGET_64BIT && TARGET_SUN_TLS"
14590   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14591         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14592   [(set_attr "type" "multi")
14593    (set_attr "length" "13")])
14594
14595 (define_expand "tls_local_dynamic_base_32"
14596   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14597                    (unspec:SI [(match_dup 1) (match_dup 2)]
14598                               UNSPEC_TLS_LD_BASE))
14599               (clobber (match_scratch:SI 3 ""))
14600               (clobber (match_scratch:SI 4 ""))
14601               (clobber (reg:CC FLAGS_REG))])]
14602   ""
14603 {
14604   if (flag_pic)
14605     operands[1] = pic_offset_table_rtx;
14606   else
14607     {
14608       operands[1] = gen_reg_rtx (Pmode);
14609       emit_insn (gen_set_got (operands[1]));
14610     }
14611   if (TARGET_GNU2_TLS)
14612     {
14613        emit_insn (gen_tls_dynamic_gnu2_32
14614                   (operands[0], ix86_tls_module_base (), operands[1]));
14615        DONE;
14616     }
14617   operands[2] = ix86_tls_get_addr ();
14618 })
14619
14620 (define_insn "*tls_local_dynamic_base_64"
14621   [(set (match_operand:DI 0 "register_operand" "=a")
14622         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14623                  (match_operand:DI 2 "" "")))
14624    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14625   "TARGET_64BIT"
14626   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
14627   [(set_attr "type" "multi")
14628    (set_attr "length" "12")])
14629
14630 (define_expand "tls_local_dynamic_base_64"
14631   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14632                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14633               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14634   ""
14635 {
14636   if (TARGET_GNU2_TLS)
14637     {
14638        emit_insn (gen_tls_dynamic_gnu2_64
14639                   (operands[0], ix86_tls_module_base ()));
14640        DONE;
14641     }
14642   operands[1] = ix86_tls_get_addr ();
14643 })
14644
14645 ;; Local dynamic of a single variable is a lose.  Show combine how
14646 ;; to convert that back to global dynamic.
14647
14648 (define_insn_and_split "*tls_local_dynamic_32_once"
14649   [(set (match_operand:SI 0 "register_operand" "=a")
14650         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14651                              (match_operand:SI 2 "call_insn_operand" "")]
14652                             UNSPEC_TLS_LD_BASE)
14653                  (const:SI (unspec:SI
14654                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14655                             UNSPEC_DTPOFF))))
14656    (clobber (match_scratch:SI 4 "=d"))
14657    (clobber (match_scratch:SI 5 "=c"))
14658    (clobber (reg:CC FLAGS_REG))]
14659   ""
14660   "#"
14661   ""
14662   [(parallel [(set (match_dup 0)
14663                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14664                               UNSPEC_TLS_GD))
14665               (clobber (match_dup 4))
14666               (clobber (match_dup 5))
14667               (clobber (reg:CC FLAGS_REG))])]
14668   "")
14669
14670 ;; Load and add the thread base pointer from %gs:0.
14671
14672 (define_insn "*load_tp_si"
14673   [(set (match_operand:SI 0 "register_operand" "=r")
14674         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14675   "!TARGET_64BIT"
14676   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14677   [(set_attr "type" "imov")
14678    (set_attr "modrm" "0")
14679    (set_attr "length" "7")
14680    (set_attr "memory" "load")
14681    (set_attr "imm_disp" "false")])
14682
14683 (define_insn "*add_tp_si"
14684   [(set (match_operand:SI 0 "register_operand" "=r")
14685         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14686                  (match_operand:SI 1 "register_operand" "0")))
14687    (clobber (reg:CC FLAGS_REG))]
14688   "!TARGET_64BIT"
14689   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14690   [(set_attr "type" "alu")
14691    (set_attr "modrm" "0")
14692    (set_attr "length" "7")
14693    (set_attr "memory" "load")
14694    (set_attr "imm_disp" "false")])
14695
14696 (define_insn "*load_tp_di"
14697   [(set (match_operand:DI 0 "register_operand" "=r")
14698         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14699   "TARGET_64BIT"
14700   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14701   [(set_attr "type" "imov")
14702    (set_attr "modrm" "0")
14703    (set_attr "length" "7")
14704    (set_attr "memory" "load")
14705    (set_attr "imm_disp" "false")])
14706
14707 (define_insn "*add_tp_di"
14708   [(set (match_operand:DI 0 "register_operand" "=r")
14709         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14710                  (match_operand:DI 1 "register_operand" "0")))
14711    (clobber (reg:CC FLAGS_REG))]
14712   "TARGET_64BIT"
14713   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14714   [(set_attr "type" "alu")
14715    (set_attr "modrm" "0")
14716    (set_attr "length" "7")
14717    (set_attr "memory" "load")
14718    (set_attr "imm_disp" "false")])
14719
14720 ;; GNU2 TLS patterns can be split.
14721
14722 (define_expand "tls_dynamic_gnu2_32"
14723   [(set (match_dup 3)
14724         (plus:SI (match_operand:SI 2 "register_operand" "")
14725                  (const:SI
14726                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14727                              UNSPEC_TLSDESC))))
14728    (parallel
14729     [(set (match_operand:SI 0 "register_operand" "")
14730           (unspec:SI [(match_dup 1) (match_dup 3)
14731                       (match_dup 2) (reg:SI SP_REG)]
14732                       UNSPEC_TLSDESC))
14733      (clobber (reg:CC FLAGS_REG))])]
14734   "!TARGET_64BIT && TARGET_GNU2_TLS"
14735 {
14736   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14737   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14738 })
14739
14740 (define_insn "*tls_dynamic_lea_32"
14741   [(set (match_operand:SI 0 "register_operand" "=r")
14742         (plus:SI (match_operand:SI 1 "register_operand" "b")
14743                  (const:SI
14744                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14745                               UNSPEC_TLSDESC))))]
14746   "!TARGET_64BIT && TARGET_GNU2_TLS"
14747   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14748   [(set_attr "type" "lea")
14749    (set_attr "mode" "SI")
14750    (set_attr "length" "6")
14751    (set_attr "length_address" "4")])
14752
14753 (define_insn "*tls_dynamic_call_32"
14754   [(set (match_operand:SI 0 "register_operand" "=a")
14755         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14756                     (match_operand:SI 2 "register_operand" "0")
14757                     ;; we have to make sure %ebx still points to the GOT
14758                     (match_operand:SI 3 "register_operand" "b")
14759                     (reg:SI SP_REG)]
14760                    UNSPEC_TLSDESC))
14761    (clobber (reg:CC FLAGS_REG))]
14762   "!TARGET_64BIT && TARGET_GNU2_TLS"
14763   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14764   [(set_attr "type" "call")
14765    (set_attr "length" "2")
14766    (set_attr "length_address" "0")])
14767
14768 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14769   [(set (match_operand:SI 0 "register_operand" "=&a")
14770         (plus:SI
14771          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14772                      (match_operand:SI 4 "" "")
14773                      (match_operand:SI 2 "register_operand" "b")
14774                      (reg:SI SP_REG)]
14775                     UNSPEC_TLSDESC)
14776          (const:SI (unspec:SI
14777                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14778                     UNSPEC_DTPOFF))))
14779    (clobber (reg:CC FLAGS_REG))]
14780   "!TARGET_64BIT && TARGET_GNU2_TLS"
14781   "#"
14782   ""
14783   [(set (match_dup 0) (match_dup 5))]
14784 {
14785   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14786   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14787 })
14788
14789 (define_expand "tls_dynamic_gnu2_64"
14790   [(set (match_dup 2)
14791         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14792                    UNSPEC_TLSDESC))
14793    (parallel
14794     [(set (match_operand:DI 0 "register_operand" "")
14795           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14796                      UNSPEC_TLSDESC))
14797      (clobber (reg:CC FLAGS_REG))])]
14798   "TARGET_64BIT && TARGET_GNU2_TLS"
14799 {
14800   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14801   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14802 })
14803
14804 (define_insn "*tls_dynamic_lea_64"
14805   [(set (match_operand:DI 0 "register_operand" "=r")
14806         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14807                    UNSPEC_TLSDESC))]
14808   "TARGET_64BIT && TARGET_GNU2_TLS"
14809   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14810   [(set_attr "type" "lea")
14811    (set_attr "mode" "DI")
14812    (set_attr "length" "7")
14813    (set_attr "length_address" "4")])
14814
14815 (define_insn "*tls_dynamic_call_64"
14816   [(set (match_operand:DI 0 "register_operand" "=a")
14817         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14818                     (match_operand:DI 2 "register_operand" "0")
14819                     (reg:DI SP_REG)]
14820                    UNSPEC_TLSDESC))
14821    (clobber (reg:CC FLAGS_REG))]
14822   "TARGET_64BIT && TARGET_GNU2_TLS"
14823   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14824   [(set_attr "type" "call")
14825    (set_attr "length" "2")
14826    (set_attr "length_address" "0")])
14827
14828 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14829   [(set (match_operand:DI 0 "register_operand" "=&a")
14830         (plus:DI
14831          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14832                      (match_operand:DI 3 "" "")
14833                      (reg:DI SP_REG)]
14834                     UNSPEC_TLSDESC)
14835          (const:DI (unspec:DI
14836                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14837                     UNSPEC_DTPOFF))))
14838    (clobber (reg:CC FLAGS_REG))]
14839   "TARGET_64BIT && TARGET_GNU2_TLS"
14840   "#"
14841   ""
14842   [(set (match_dup 0) (match_dup 4))]
14843 {
14844   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14845   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14846 })
14847
14848 ;;
14849 \f
14850 ;; These patterns match the binary 387 instructions for addM3, subM3,
14851 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14852 ;; SFmode.  The first is the normal insn, the second the same insn but
14853 ;; with one operand a conversion, and the third the same insn but with
14854 ;; the other operand a conversion.  The conversion may be SFmode or
14855 ;; SImode if the target mode DFmode, but only SImode if the target mode
14856 ;; is SFmode.
14857
14858 ;; Gcc is slightly more smart about handling normal two address instructions
14859 ;; so use special patterns for add and mull.
14860
14861 (define_insn "*fop_<mode>_comm_mixed_avx"
14862   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14863         (match_operator:MODEF 3 "binary_fp_operator"
14864           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14865            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14866   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14867    && COMMUTATIVE_ARITH_P (operands[3])
14868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14869   "* return output_387_binary_op (insn, operands);"
14870   [(set (attr "type")
14871         (if_then_else (eq_attr "alternative" "1")
14872            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14873               (const_string "ssemul")
14874               (const_string "sseadd"))
14875            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14876               (const_string "fmul")
14877               (const_string "fop"))))
14878    (set_attr "prefix" "orig,maybe_vex")
14879    (set_attr "mode" "<MODE>")])
14880
14881 (define_insn "*fop_<mode>_comm_mixed"
14882   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14883         (match_operator:MODEF 3 "binary_fp_operator"
14884           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14885            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14886   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14887    && COMMUTATIVE_ARITH_P (operands[3])
14888    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14889   "* return output_387_binary_op (insn, operands);"
14890   [(set (attr "type")
14891         (if_then_else (eq_attr "alternative" "1")
14892            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14893               (const_string "ssemul")
14894               (const_string "sseadd"))
14895            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14896               (const_string "fmul")
14897               (const_string "fop"))))
14898    (set_attr "mode" "<MODE>")])
14899
14900 (define_insn "*fop_<mode>_comm_avx"
14901   [(set (match_operand:MODEF 0 "register_operand" "=x")
14902         (match_operator:MODEF 3 "binary_fp_operator"
14903           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14904            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14905   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14906    && COMMUTATIVE_ARITH_P (operands[3])
14907    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14908   "* return output_387_binary_op (insn, operands);"
14909   [(set (attr "type")
14910         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14911            (const_string "ssemul")
14912            (const_string "sseadd")))
14913    (set_attr "prefix" "vex")
14914    (set_attr "mode" "<MODE>")])
14915
14916 (define_insn "*fop_<mode>_comm_sse"
14917   [(set (match_operand:MODEF 0 "register_operand" "=x")
14918         (match_operator:MODEF 3 "binary_fp_operator"
14919           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14920            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14921   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14922    && COMMUTATIVE_ARITH_P (operands[3])
14923    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14924   "* return output_387_binary_op (insn, operands);"
14925   [(set (attr "type")
14926         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14927            (const_string "ssemul")
14928            (const_string "sseadd")))
14929    (set_attr "mode" "<MODE>")])
14930
14931 (define_insn "*fop_<mode>_comm_i387"
14932   [(set (match_operand:MODEF 0 "register_operand" "=f")
14933         (match_operator:MODEF 3 "binary_fp_operator"
14934           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14935            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14936   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14937    && COMMUTATIVE_ARITH_P (operands[3])
14938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14939   "* return output_387_binary_op (insn, operands);"
14940   [(set (attr "type")
14941         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14942            (const_string "fmul")
14943            (const_string "fop")))
14944    (set_attr "mode" "<MODE>")])
14945
14946 (define_insn "*fop_<mode>_1_mixed_avx"
14947   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14948         (match_operator:MODEF 3 "binary_fp_operator"
14949           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14950            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14951   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14952    && !COMMUTATIVE_ARITH_P (operands[3])
14953    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14954   "* return output_387_binary_op (insn, operands);"
14955   [(set (attr "type")
14956         (cond [(and (eq_attr "alternative" "2")
14957                     (match_operand:MODEF 3 "mult_operator" ""))
14958                  (const_string "ssemul")
14959                (and (eq_attr "alternative" "2")
14960                     (match_operand:MODEF 3 "div_operator" ""))
14961                  (const_string "ssediv")
14962                (eq_attr "alternative" "2")
14963                  (const_string "sseadd")
14964                (match_operand:MODEF 3 "mult_operator" "")
14965                  (const_string "fmul")
14966                (match_operand:MODEF 3 "div_operator" "")
14967                  (const_string "fdiv")
14968               ]
14969               (const_string "fop")))
14970    (set_attr "prefix" "orig,orig,maybe_vex")
14971    (set_attr "mode" "<MODE>")])
14972
14973 (define_insn "*fop_<mode>_1_mixed"
14974   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14975         (match_operator:MODEF 3 "binary_fp_operator"
14976           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14977            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14978   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14979    && !COMMUTATIVE_ARITH_P (operands[3])
14980    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14981   "* return output_387_binary_op (insn, operands);"
14982   [(set (attr "type")
14983         (cond [(and (eq_attr "alternative" "2")
14984                     (match_operand:MODEF 3 "mult_operator" ""))
14985                  (const_string "ssemul")
14986                (and (eq_attr "alternative" "2")
14987                     (match_operand:MODEF 3 "div_operator" ""))
14988                  (const_string "ssediv")
14989                (eq_attr "alternative" "2")
14990                  (const_string "sseadd")
14991                (match_operand:MODEF 3 "mult_operator" "")
14992                  (const_string "fmul")
14993                (match_operand:MODEF 3 "div_operator" "")
14994                  (const_string "fdiv")
14995               ]
14996               (const_string "fop")))
14997    (set_attr "mode" "<MODE>")])
14998
14999 (define_insn "*rcpsf2_sse"
15000   [(set (match_operand:SF 0 "register_operand" "=x")
15001         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15002                    UNSPEC_RCP))]
15003   "TARGET_SSE_MATH"
15004   "%vrcpss\t{%1, %d0|%d0, %1}"
15005   [(set_attr "type" "sse")
15006    (set_attr "atom_sse_attr" "rcp")
15007    (set_attr "prefix" "maybe_vex")
15008    (set_attr "mode" "SF")])
15009
15010 (define_insn "*fop_<mode>_1_avx"
15011   [(set (match_operand:MODEF 0 "register_operand" "=x")
15012         (match_operator:MODEF 3 "binary_fp_operator"
15013           [(match_operand:MODEF 1 "register_operand" "x")
15014            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15015   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15016    && !COMMUTATIVE_ARITH_P (operands[3])"
15017   "* return output_387_binary_op (insn, operands);"
15018   [(set (attr "type")
15019         (cond [(match_operand:MODEF 3 "mult_operator" "")
15020                  (const_string "ssemul")
15021                (match_operand:MODEF 3 "div_operator" "")
15022                  (const_string "ssediv")
15023               ]
15024               (const_string "sseadd")))
15025    (set_attr "prefix" "vex")
15026    (set_attr "mode" "<MODE>")])
15027
15028 (define_insn "*fop_<mode>_1_sse"
15029   [(set (match_operand:MODEF 0 "register_operand" "=x")
15030         (match_operator:MODEF 3 "binary_fp_operator"
15031           [(match_operand:MODEF 1 "register_operand" "0")
15032            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15033   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15034    && !COMMUTATIVE_ARITH_P (operands[3])"
15035   "* return output_387_binary_op (insn, operands);"
15036   [(set (attr "type")
15037         (cond [(match_operand:MODEF 3 "mult_operator" "")
15038                  (const_string "ssemul")
15039                (match_operand:MODEF 3 "div_operator" "")
15040                  (const_string "ssediv")
15041               ]
15042               (const_string "sseadd")))
15043    (set_attr "mode" "<MODE>")])
15044
15045 ;; This pattern is not fully shadowed by the pattern above.
15046 (define_insn "*fop_<mode>_1_i387"
15047   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15048         (match_operator:MODEF 3 "binary_fp_operator"
15049           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15050            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15051   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15052    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15053    && !COMMUTATIVE_ARITH_P (operands[3])
15054    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15055   "* return output_387_binary_op (insn, operands);"
15056   [(set (attr "type")
15057         (cond [(match_operand:MODEF 3 "mult_operator" "")
15058                  (const_string "fmul")
15059                (match_operand:MODEF 3 "div_operator" "")
15060                  (const_string "fdiv")
15061               ]
15062               (const_string "fop")))
15063    (set_attr "mode" "<MODE>")])
15064
15065 ;; ??? Add SSE splitters for these!
15066 (define_insn "*fop_<MODEF:mode>_2_i387"
15067   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15068         (match_operator:MODEF 3 "binary_fp_operator"
15069           [(float:MODEF
15070              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15071            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15072   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15073    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15074    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15075   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15076   [(set (attr "type")
15077         (cond [(match_operand:MODEF 3 "mult_operator" "")
15078                  (const_string "fmul")
15079                (match_operand:MODEF 3 "div_operator" "")
15080                  (const_string "fdiv")
15081               ]
15082               (const_string "fop")))
15083    (set_attr "fp_int_src" "true")
15084    (set_attr "mode" "<X87MODEI12:MODE>")])
15085
15086 (define_insn "*fop_<MODEF:mode>_3_i387"
15087   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15088         (match_operator:MODEF 3 "binary_fp_operator"
15089           [(match_operand:MODEF 1 "register_operand" "0,0")
15090            (float:MODEF
15091              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15092   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15093    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15094    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15095   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15096   [(set (attr "type")
15097         (cond [(match_operand:MODEF 3 "mult_operator" "")
15098                  (const_string "fmul")
15099                (match_operand:MODEF 3 "div_operator" "")
15100                  (const_string "fdiv")
15101               ]
15102               (const_string "fop")))
15103    (set_attr "fp_int_src" "true")
15104    (set_attr "mode" "<MODE>")])
15105
15106 (define_insn "*fop_df_4_i387"
15107   [(set (match_operand:DF 0 "register_operand" "=f,f")
15108         (match_operator:DF 3 "binary_fp_operator"
15109            [(float_extend:DF
15110              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15111             (match_operand:DF 2 "register_operand" "0,f")]))]
15112   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15113    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15114    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15115   "* return output_387_binary_op (insn, operands);"
15116   [(set (attr "type")
15117         (cond [(match_operand:DF 3 "mult_operator" "")
15118                  (const_string "fmul")
15119                (match_operand:DF 3 "div_operator" "")
15120                  (const_string "fdiv")
15121               ]
15122               (const_string "fop")))
15123    (set_attr "mode" "SF")])
15124
15125 (define_insn "*fop_df_5_i387"
15126   [(set (match_operand:DF 0 "register_operand" "=f,f")
15127         (match_operator:DF 3 "binary_fp_operator"
15128           [(match_operand:DF 1 "register_operand" "0,f")
15129            (float_extend:DF
15130             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15131   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15132    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15133   "* return output_387_binary_op (insn, operands);"
15134   [(set (attr "type")
15135         (cond [(match_operand:DF 3 "mult_operator" "")
15136                  (const_string "fmul")
15137                (match_operand:DF 3 "div_operator" "")
15138                  (const_string "fdiv")
15139               ]
15140               (const_string "fop")))
15141    (set_attr "mode" "SF")])
15142
15143 (define_insn "*fop_df_6_i387"
15144   [(set (match_operand:DF 0 "register_operand" "=f,f")
15145         (match_operator:DF 3 "binary_fp_operator"
15146           [(float_extend:DF
15147             (match_operand:SF 1 "register_operand" "0,f"))
15148            (float_extend:DF
15149             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15150   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15151    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15152   "* return output_387_binary_op (insn, operands);"
15153   [(set (attr "type")
15154         (cond [(match_operand:DF 3 "mult_operator" "")
15155                  (const_string "fmul")
15156                (match_operand:DF 3 "div_operator" "")
15157                  (const_string "fdiv")
15158               ]
15159               (const_string "fop")))
15160    (set_attr "mode" "SF")])
15161
15162 (define_insn "*fop_xf_comm_i387"
15163   [(set (match_operand:XF 0 "register_operand" "=f")
15164         (match_operator:XF 3 "binary_fp_operator"
15165                         [(match_operand:XF 1 "register_operand" "%0")
15166                          (match_operand:XF 2 "register_operand" "f")]))]
15167   "TARGET_80387
15168    && COMMUTATIVE_ARITH_P (operands[3])"
15169   "* return output_387_binary_op (insn, operands);"
15170   [(set (attr "type")
15171         (if_then_else (match_operand:XF 3 "mult_operator" "")
15172            (const_string "fmul")
15173            (const_string "fop")))
15174    (set_attr "mode" "XF")])
15175
15176 (define_insn "*fop_xf_1_i387"
15177   [(set (match_operand:XF 0 "register_operand" "=f,f")
15178         (match_operator:XF 3 "binary_fp_operator"
15179                         [(match_operand:XF 1 "register_operand" "0,f")
15180                          (match_operand:XF 2 "register_operand" "f,0")]))]
15181   "TARGET_80387
15182    && !COMMUTATIVE_ARITH_P (operands[3])"
15183   "* return output_387_binary_op (insn, operands);"
15184   [(set (attr "type")
15185         (cond [(match_operand:XF 3 "mult_operator" "")
15186                  (const_string "fmul")
15187                (match_operand:XF 3 "div_operator" "")
15188                  (const_string "fdiv")
15189               ]
15190               (const_string "fop")))
15191    (set_attr "mode" "XF")])
15192
15193 (define_insn "*fop_xf_2_i387"
15194   [(set (match_operand:XF 0 "register_operand" "=f,f")
15195         (match_operator:XF 3 "binary_fp_operator"
15196           [(float:XF
15197              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15198            (match_operand:XF 2 "register_operand" "0,0")]))]
15199   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15200   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15201   [(set (attr "type")
15202         (cond [(match_operand:XF 3 "mult_operator" "")
15203                  (const_string "fmul")
15204                (match_operand:XF 3 "div_operator" "")
15205                  (const_string "fdiv")
15206               ]
15207               (const_string "fop")))
15208    (set_attr "fp_int_src" "true")
15209    (set_attr "mode" "<MODE>")])
15210
15211 (define_insn "*fop_xf_3_i387"
15212   [(set (match_operand:XF 0 "register_operand" "=f,f")
15213         (match_operator:XF 3 "binary_fp_operator"
15214           [(match_operand:XF 1 "register_operand" "0,0")
15215            (float:XF
15216              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15217   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15218   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15219   [(set (attr "type")
15220         (cond [(match_operand:XF 3 "mult_operator" "")
15221                  (const_string "fmul")
15222                (match_operand:XF 3 "div_operator" "")
15223                  (const_string "fdiv")
15224               ]
15225               (const_string "fop")))
15226    (set_attr "fp_int_src" "true")
15227    (set_attr "mode" "<MODE>")])
15228
15229 (define_insn "*fop_xf_4_i387"
15230   [(set (match_operand:XF 0 "register_operand" "=f,f")
15231         (match_operator:XF 3 "binary_fp_operator"
15232            [(float_extend:XF
15233               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15234             (match_operand:XF 2 "register_operand" "0,f")]))]
15235   "TARGET_80387"
15236   "* return output_387_binary_op (insn, operands);"
15237   [(set (attr "type")
15238         (cond [(match_operand:XF 3 "mult_operator" "")
15239                  (const_string "fmul")
15240                (match_operand:XF 3 "div_operator" "")
15241                  (const_string "fdiv")
15242               ]
15243               (const_string "fop")))
15244    (set_attr "mode" "<MODE>")])
15245
15246 (define_insn "*fop_xf_5_i387"
15247   [(set (match_operand:XF 0 "register_operand" "=f,f")
15248         (match_operator:XF 3 "binary_fp_operator"
15249           [(match_operand:XF 1 "register_operand" "0,f")
15250            (float_extend:XF
15251              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15252   "TARGET_80387"
15253   "* return output_387_binary_op (insn, operands);"
15254   [(set (attr "type")
15255         (cond [(match_operand:XF 3 "mult_operator" "")
15256                  (const_string "fmul")
15257                (match_operand:XF 3 "div_operator" "")
15258                  (const_string "fdiv")
15259               ]
15260               (const_string "fop")))
15261    (set_attr "mode" "<MODE>")])
15262
15263 (define_insn "*fop_xf_6_i387"
15264   [(set (match_operand:XF 0 "register_operand" "=f,f")
15265         (match_operator:XF 3 "binary_fp_operator"
15266           [(float_extend:XF
15267              (match_operand:MODEF 1 "register_operand" "0,f"))
15268            (float_extend:XF
15269              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15270   "TARGET_80387"
15271   "* return output_387_binary_op (insn, operands);"
15272   [(set (attr "type")
15273         (cond [(match_operand:XF 3 "mult_operator" "")
15274                  (const_string "fmul")
15275                (match_operand:XF 3 "div_operator" "")
15276                  (const_string "fdiv")
15277               ]
15278               (const_string "fop")))
15279    (set_attr "mode" "<MODE>")])
15280
15281 (define_split
15282   [(set (match_operand 0 "register_operand" "")
15283         (match_operator 3 "binary_fp_operator"
15284            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15285             (match_operand 2 "register_operand" "")]))]
15286   "reload_completed
15287    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15288    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15289   [(const_int 0)]
15290 {
15291   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15292   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15293   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15294                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15295                                           GET_MODE (operands[3]),
15296                                           operands[4],
15297                                           operands[2])));
15298   ix86_free_from_memory (GET_MODE (operands[1]));
15299   DONE;
15300 })
15301
15302 (define_split
15303   [(set (match_operand 0 "register_operand" "")
15304         (match_operator 3 "binary_fp_operator"
15305            [(match_operand 1 "register_operand" "")
15306             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15307   "reload_completed
15308    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15309    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15310   [(const_int 0)]
15311 {
15312   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15313   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15314   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15315                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15316                                           GET_MODE (operands[3]),
15317                                           operands[1],
15318                                           operands[4])));
15319   ix86_free_from_memory (GET_MODE (operands[2]));
15320   DONE;
15321 })
15322 \f
15323 ;; FPU special functions.
15324
15325 ;; This pattern implements a no-op XFmode truncation for
15326 ;; all fancy i386 XFmode math functions.
15327
15328 (define_insn "truncxf<mode>2_i387_noop_unspec"
15329   [(set (match_operand:MODEF 0 "register_operand" "=f")
15330         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15331         UNSPEC_TRUNC_NOOP))]
15332   "TARGET_USE_FANCY_MATH_387"
15333   "* return output_387_reg_move (insn, operands);"
15334   [(set_attr "type" "fmov")
15335    (set_attr "mode" "<MODE>")])
15336
15337 (define_insn "sqrtxf2"
15338   [(set (match_operand:XF 0 "register_operand" "=f")
15339         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15340   "TARGET_USE_FANCY_MATH_387"
15341   "fsqrt"
15342   [(set_attr "type" "fpspc")
15343    (set_attr "mode" "XF")
15344    (set_attr "athlon_decode" "direct")
15345    (set_attr "amdfam10_decode" "direct")])
15346
15347 (define_insn "sqrt_extend<mode>xf2_i387"
15348   [(set (match_operand:XF 0 "register_operand" "=f")
15349         (sqrt:XF
15350           (float_extend:XF
15351             (match_operand:MODEF 1 "register_operand" "0"))))]
15352   "TARGET_USE_FANCY_MATH_387"
15353   "fsqrt"
15354   [(set_attr "type" "fpspc")
15355    (set_attr "mode" "XF")
15356    (set_attr "athlon_decode" "direct")
15357    (set_attr "amdfam10_decode" "direct")])
15358
15359 (define_insn "*rsqrtsf2_sse"
15360   [(set (match_operand:SF 0 "register_operand" "=x")
15361         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15362                    UNSPEC_RSQRT))]
15363   "TARGET_SSE_MATH"
15364   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15365   [(set_attr "type" "sse")
15366    (set_attr "atom_sse_attr" "rcp")
15367    (set_attr "prefix" "maybe_vex")
15368    (set_attr "mode" "SF")])
15369
15370 (define_expand "rsqrtsf2"
15371   [(set (match_operand:SF 0 "register_operand" "")
15372         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15373                    UNSPEC_RSQRT))]
15374   "TARGET_SSE_MATH"
15375 {
15376   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15377   DONE;
15378 })
15379
15380 (define_insn "*sqrt<mode>2_sse"
15381   [(set (match_operand:MODEF 0 "register_operand" "=x")
15382         (sqrt:MODEF
15383           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15384   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15385   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15386   [(set_attr "type" "sse")
15387    (set_attr "atom_sse_attr" "sqrt")
15388    (set_attr "prefix" "maybe_vex")
15389    (set_attr "mode" "<MODE>")
15390    (set_attr "athlon_decode" "*")
15391    (set_attr "amdfam10_decode" "*")])
15392
15393 (define_expand "sqrt<mode>2"
15394   [(set (match_operand:MODEF 0 "register_operand" "")
15395         (sqrt:MODEF
15396           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15397   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15398    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15399 {
15400   if (<MODE>mode == SFmode
15401       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15402       && flag_finite_math_only && !flag_trapping_math
15403       && flag_unsafe_math_optimizations)
15404     {
15405       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15406       DONE;
15407     }
15408
15409   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15410     {
15411       rtx op0 = gen_reg_rtx (XFmode);
15412       rtx op1 = force_reg (<MODE>mode, operands[1]);
15413
15414       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15415       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15416       DONE;
15417    }
15418 })
15419
15420 (define_insn "fpremxf4_i387"
15421   [(set (match_operand:XF 0 "register_operand" "=f")
15422         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15423                     (match_operand:XF 3 "register_operand" "1")]
15424                    UNSPEC_FPREM_F))
15425    (set (match_operand:XF 1 "register_operand" "=u")
15426         (unspec:XF [(match_dup 2) (match_dup 3)]
15427                    UNSPEC_FPREM_U))
15428    (set (reg:CCFP FPSR_REG)
15429         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15430                      UNSPEC_C2_FLAG))]
15431   "TARGET_USE_FANCY_MATH_387"
15432   "fprem"
15433   [(set_attr "type" "fpspc")
15434    (set_attr "mode" "XF")])
15435
15436 (define_expand "fmodxf3"
15437   [(use (match_operand:XF 0 "register_operand" ""))
15438    (use (match_operand:XF 1 "general_operand" ""))
15439    (use (match_operand:XF 2 "general_operand" ""))]
15440   "TARGET_USE_FANCY_MATH_387"
15441 {
15442   rtx label = gen_label_rtx ();
15443
15444   rtx op1 = gen_reg_rtx (XFmode);
15445   rtx op2 = gen_reg_rtx (XFmode);
15446
15447   emit_move_insn (op2, operands[2]);
15448   emit_move_insn (op1, operands[1]);
15449
15450   emit_label (label);
15451   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15452   ix86_emit_fp_unordered_jump (label);
15453   LABEL_NUSES (label) = 1;
15454
15455   emit_move_insn (operands[0], op1);
15456   DONE;
15457 })
15458
15459 (define_expand "fmod<mode>3"
15460   [(use (match_operand:MODEF 0 "register_operand" ""))
15461    (use (match_operand:MODEF 1 "general_operand" ""))
15462    (use (match_operand:MODEF 2 "general_operand" ""))]
15463   "TARGET_USE_FANCY_MATH_387"
15464 {
15465   rtx label = gen_label_rtx ();
15466
15467   rtx op1 = gen_reg_rtx (XFmode);
15468   rtx op2 = gen_reg_rtx (XFmode);
15469
15470   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15471   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15472
15473   emit_label (label);
15474   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15475   ix86_emit_fp_unordered_jump (label);
15476   LABEL_NUSES (label) = 1;
15477
15478   /* Truncate the result properly for strict SSE math.  */
15479   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15480       && !TARGET_MIX_SSE_I387)
15481     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15482   else
15483     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15484
15485   DONE;
15486 })
15487
15488 (define_insn "fprem1xf4_i387"
15489   [(set (match_operand:XF 0 "register_operand" "=f")
15490         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15491                     (match_operand:XF 3 "register_operand" "1")]
15492                    UNSPEC_FPREM1_F))
15493    (set (match_operand:XF 1 "register_operand" "=u")
15494         (unspec:XF [(match_dup 2) (match_dup 3)]
15495                    UNSPEC_FPREM1_U))
15496    (set (reg:CCFP FPSR_REG)
15497         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15498                      UNSPEC_C2_FLAG))]
15499   "TARGET_USE_FANCY_MATH_387"
15500   "fprem1"
15501   [(set_attr "type" "fpspc")
15502    (set_attr "mode" "XF")])
15503
15504 (define_expand "remainderxf3"
15505   [(use (match_operand:XF 0 "register_operand" ""))
15506    (use (match_operand:XF 1 "general_operand" ""))
15507    (use (match_operand:XF 2 "general_operand" ""))]
15508   "TARGET_USE_FANCY_MATH_387"
15509 {
15510   rtx label = gen_label_rtx ();
15511
15512   rtx op1 = gen_reg_rtx (XFmode);
15513   rtx op2 = gen_reg_rtx (XFmode);
15514
15515   emit_move_insn (op2, operands[2]);
15516   emit_move_insn (op1, operands[1]);
15517
15518   emit_label (label);
15519   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15520   ix86_emit_fp_unordered_jump (label);
15521   LABEL_NUSES (label) = 1;
15522
15523   emit_move_insn (operands[0], op1);
15524   DONE;
15525 })
15526
15527 (define_expand "remainder<mode>3"
15528   [(use (match_operand:MODEF 0 "register_operand" ""))
15529    (use (match_operand:MODEF 1 "general_operand" ""))
15530    (use (match_operand:MODEF 2 "general_operand" ""))]
15531   "TARGET_USE_FANCY_MATH_387"
15532 {
15533   rtx label = gen_label_rtx ();
15534
15535   rtx op1 = gen_reg_rtx (XFmode);
15536   rtx op2 = gen_reg_rtx (XFmode);
15537
15538   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15539   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15540
15541   emit_label (label);
15542
15543   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15544   ix86_emit_fp_unordered_jump (label);
15545   LABEL_NUSES (label) = 1;
15546
15547   /* Truncate the result properly for strict SSE math.  */
15548   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15549       && !TARGET_MIX_SSE_I387)
15550     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15551   else
15552     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15553
15554   DONE;
15555 })
15556
15557 (define_insn "*sinxf2_i387"
15558   [(set (match_operand:XF 0 "register_operand" "=f")
15559         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15560   "TARGET_USE_FANCY_MATH_387
15561    && flag_unsafe_math_optimizations"
15562   "fsin"
15563   [(set_attr "type" "fpspc")
15564    (set_attr "mode" "XF")])
15565
15566 (define_insn "*sin_extend<mode>xf2_i387"
15567   [(set (match_operand:XF 0 "register_operand" "=f")
15568         (unspec:XF [(float_extend:XF
15569                       (match_operand:MODEF 1 "register_operand" "0"))]
15570                    UNSPEC_SIN))]
15571   "TARGET_USE_FANCY_MATH_387
15572    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15573        || TARGET_MIX_SSE_I387)
15574    && flag_unsafe_math_optimizations"
15575   "fsin"
15576   [(set_attr "type" "fpspc")
15577    (set_attr "mode" "XF")])
15578
15579 (define_insn "*cosxf2_i387"
15580   [(set (match_operand:XF 0 "register_operand" "=f")
15581         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15582   "TARGET_USE_FANCY_MATH_387
15583    && flag_unsafe_math_optimizations"
15584   "fcos"
15585   [(set_attr "type" "fpspc")
15586    (set_attr "mode" "XF")])
15587
15588 (define_insn "*cos_extend<mode>xf2_i387"
15589   [(set (match_operand:XF 0 "register_operand" "=f")
15590         (unspec:XF [(float_extend:XF
15591                       (match_operand:MODEF 1 "register_operand" "0"))]
15592                    UNSPEC_COS))]
15593   "TARGET_USE_FANCY_MATH_387
15594    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15595        || TARGET_MIX_SSE_I387)
15596    && flag_unsafe_math_optimizations"
15597   "fcos"
15598   [(set_attr "type" "fpspc")
15599    (set_attr "mode" "XF")])
15600
15601 ;; When sincos pattern is defined, sin and cos builtin functions will be
15602 ;; expanded to sincos pattern with one of its outputs left unused.
15603 ;; CSE pass will figure out if two sincos patterns can be combined,
15604 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15605 ;; depending on the unused output.
15606
15607 (define_insn "sincosxf3"
15608   [(set (match_operand:XF 0 "register_operand" "=f")
15609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15610                    UNSPEC_SINCOS_COS))
15611    (set (match_operand:XF 1 "register_operand" "=u")
15612         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15613   "TARGET_USE_FANCY_MATH_387
15614    && flag_unsafe_math_optimizations"
15615   "fsincos"
15616   [(set_attr "type" "fpspc")
15617    (set_attr "mode" "XF")])
15618
15619 (define_split
15620   [(set (match_operand:XF 0 "register_operand" "")
15621         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15622                    UNSPEC_SINCOS_COS))
15623    (set (match_operand:XF 1 "register_operand" "")
15624         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15625   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15626    && !(reload_completed || reload_in_progress)"
15627   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15628   "")
15629
15630 (define_split
15631   [(set (match_operand:XF 0 "register_operand" "")
15632         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15633                    UNSPEC_SINCOS_COS))
15634    (set (match_operand:XF 1 "register_operand" "")
15635         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15636   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15637    && !(reload_completed || reload_in_progress)"
15638   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15639   "")
15640
15641 (define_insn "sincos_extend<mode>xf3_i387"
15642   [(set (match_operand:XF 0 "register_operand" "=f")
15643         (unspec:XF [(float_extend:XF
15644                       (match_operand:MODEF 2 "register_operand" "0"))]
15645                    UNSPEC_SINCOS_COS))
15646    (set (match_operand:XF 1 "register_operand" "=u")
15647         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15648   "TARGET_USE_FANCY_MATH_387
15649    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15650        || TARGET_MIX_SSE_I387)
15651    && flag_unsafe_math_optimizations"
15652   "fsincos"
15653   [(set_attr "type" "fpspc")
15654    (set_attr "mode" "XF")])
15655
15656 (define_split
15657   [(set (match_operand:XF 0 "register_operand" "")
15658         (unspec:XF [(float_extend:XF
15659                       (match_operand:MODEF 2 "register_operand" ""))]
15660                    UNSPEC_SINCOS_COS))
15661    (set (match_operand:XF 1 "register_operand" "")
15662         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15663   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15664    && !(reload_completed || reload_in_progress)"
15665   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15666   "")
15667
15668 (define_split
15669   [(set (match_operand:XF 0 "register_operand" "")
15670         (unspec:XF [(float_extend:XF
15671                       (match_operand:MODEF 2 "register_operand" ""))]
15672                    UNSPEC_SINCOS_COS))
15673    (set (match_operand:XF 1 "register_operand" "")
15674         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15675   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15676    && !(reload_completed || reload_in_progress)"
15677   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15678   "")
15679
15680 (define_expand "sincos<mode>3"
15681   [(use (match_operand:MODEF 0 "register_operand" ""))
15682    (use (match_operand:MODEF 1 "register_operand" ""))
15683    (use (match_operand:MODEF 2 "register_operand" ""))]
15684   "TARGET_USE_FANCY_MATH_387
15685    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15686        || TARGET_MIX_SSE_I387)
15687    && flag_unsafe_math_optimizations"
15688 {
15689   rtx op0 = gen_reg_rtx (XFmode);
15690   rtx op1 = gen_reg_rtx (XFmode);
15691
15692   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15693   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15694   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15695   DONE;
15696 })
15697
15698 (define_insn "fptanxf4_i387"
15699   [(set (match_operand:XF 0 "register_operand" "=f")
15700         (match_operand:XF 3 "const_double_operand" "F"))
15701    (set (match_operand:XF 1 "register_operand" "=u")
15702         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15703                    UNSPEC_TAN))]
15704   "TARGET_USE_FANCY_MATH_387
15705    && flag_unsafe_math_optimizations
15706    && standard_80387_constant_p (operands[3]) == 2"
15707   "fptan"
15708   [(set_attr "type" "fpspc")
15709    (set_attr "mode" "XF")])
15710
15711 (define_insn "fptan_extend<mode>xf4_i387"
15712   [(set (match_operand:MODEF 0 "register_operand" "=f")
15713         (match_operand:MODEF 3 "const_double_operand" "F"))
15714    (set (match_operand:XF 1 "register_operand" "=u")
15715         (unspec:XF [(float_extend:XF
15716                       (match_operand:MODEF 2 "register_operand" "0"))]
15717                    UNSPEC_TAN))]
15718   "TARGET_USE_FANCY_MATH_387
15719    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15720        || TARGET_MIX_SSE_I387)
15721    && flag_unsafe_math_optimizations
15722    && standard_80387_constant_p (operands[3]) == 2"
15723   "fptan"
15724   [(set_attr "type" "fpspc")
15725    (set_attr "mode" "XF")])
15726
15727 (define_expand "tanxf2"
15728   [(use (match_operand:XF 0 "register_operand" ""))
15729    (use (match_operand:XF 1 "register_operand" ""))]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15732 {
15733   rtx one = gen_reg_rtx (XFmode);
15734   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15735
15736   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15737   DONE;
15738 })
15739
15740 (define_expand "tan<mode>2"
15741   [(use (match_operand:MODEF 0 "register_operand" ""))
15742    (use (match_operand:MODEF 1 "register_operand" ""))]
15743   "TARGET_USE_FANCY_MATH_387
15744    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15745        || TARGET_MIX_SSE_I387)
15746    && flag_unsafe_math_optimizations"
15747 {
15748   rtx op0 = gen_reg_rtx (XFmode);
15749
15750   rtx one = gen_reg_rtx (<MODE>mode);
15751   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15752
15753   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15754                                              operands[1], op2));
15755   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15756   DONE;
15757 })
15758
15759 (define_insn "*fpatanxf3_i387"
15760   [(set (match_operand:XF 0 "register_operand" "=f")
15761         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15762                     (match_operand:XF 2 "register_operand" "u")]
15763                    UNSPEC_FPATAN))
15764    (clobber (match_scratch:XF 3 "=2"))]
15765   "TARGET_USE_FANCY_MATH_387
15766    && flag_unsafe_math_optimizations"
15767   "fpatan"
15768   [(set_attr "type" "fpspc")
15769    (set_attr "mode" "XF")])
15770
15771 (define_insn "fpatan_extend<mode>xf3_i387"
15772   [(set (match_operand:XF 0 "register_operand" "=f")
15773         (unspec:XF [(float_extend:XF
15774                       (match_operand:MODEF 1 "register_operand" "0"))
15775                     (float_extend:XF
15776                       (match_operand:MODEF 2 "register_operand" "u"))]
15777                    UNSPEC_FPATAN))
15778    (clobber (match_scratch:XF 3 "=2"))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15781        || TARGET_MIX_SSE_I387)
15782    && flag_unsafe_math_optimizations"
15783   "fpatan"
15784   [(set_attr "type" "fpspc")
15785    (set_attr "mode" "XF")])
15786
15787 (define_expand "atan2xf3"
15788   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15789                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15790                                (match_operand:XF 1 "register_operand" "")]
15791                               UNSPEC_FPATAN))
15792               (clobber (match_scratch:XF 3 ""))])]
15793   "TARGET_USE_FANCY_MATH_387
15794    && flag_unsafe_math_optimizations"
15795   "")
15796
15797 (define_expand "atan2<mode>3"
15798   [(use (match_operand:MODEF 0 "register_operand" ""))
15799    (use (match_operand:MODEF 1 "register_operand" ""))
15800    (use (match_operand:MODEF 2 "register_operand" ""))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15803        || TARGET_MIX_SSE_I387)
15804    && flag_unsafe_math_optimizations"
15805 {
15806   rtx op0 = gen_reg_rtx (XFmode);
15807
15808   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15809   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15810   DONE;
15811 })
15812
15813 (define_expand "atanxf2"
15814   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15815                    (unspec:XF [(match_dup 2)
15816                                (match_operand:XF 1 "register_operand" "")]
15817                               UNSPEC_FPATAN))
15818               (clobber (match_scratch:XF 3 ""))])]
15819   "TARGET_USE_FANCY_MATH_387
15820    && flag_unsafe_math_optimizations"
15821 {
15822   operands[2] = gen_reg_rtx (XFmode);
15823   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15824 })
15825
15826 (define_expand "atan<mode>2"
15827   [(use (match_operand:MODEF 0 "register_operand" ""))
15828    (use (match_operand:MODEF 1 "register_operand" ""))]
15829   "TARGET_USE_FANCY_MATH_387
15830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15831        || TARGET_MIX_SSE_I387)
15832    && flag_unsafe_math_optimizations"
15833 {
15834   rtx op0 = gen_reg_rtx (XFmode);
15835
15836   rtx op2 = gen_reg_rtx (<MODE>mode);
15837   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15838
15839   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15840   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15841   DONE;
15842 })
15843
15844 (define_expand "asinxf2"
15845   [(set (match_dup 2)
15846         (mult:XF (match_operand:XF 1 "register_operand" "")
15847                  (match_dup 1)))
15848    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15849    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15850    (parallel [(set (match_operand:XF 0 "register_operand" "")
15851                    (unspec:XF [(match_dup 5) (match_dup 1)]
15852                               UNSPEC_FPATAN))
15853               (clobber (match_scratch:XF 6 ""))])]
15854   "TARGET_USE_FANCY_MATH_387
15855    && flag_unsafe_math_optimizations"
15856 {
15857   int i;
15858
15859   if (optimize_insn_for_size_p ())
15860     FAIL;
15861
15862   for (i = 2; i < 6; i++)
15863     operands[i] = gen_reg_rtx (XFmode);
15864
15865   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15866 })
15867
15868 (define_expand "asin<mode>2"
15869   [(use (match_operand:MODEF 0 "register_operand" ""))
15870    (use (match_operand:MODEF 1 "general_operand" ""))]
15871  "TARGET_USE_FANCY_MATH_387
15872    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15873        || TARGET_MIX_SSE_I387)
15874    && flag_unsafe_math_optimizations"
15875 {
15876   rtx op0 = gen_reg_rtx (XFmode);
15877   rtx op1 = gen_reg_rtx (XFmode);
15878
15879   if (optimize_insn_for_size_p ())
15880     FAIL;
15881
15882   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15883   emit_insn (gen_asinxf2 (op0, op1));
15884   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15885   DONE;
15886 })
15887
15888 (define_expand "acosxf2"
15889   [(set (match_dup 2)
15890         (mult:XF (match_operand:XF 1 "register_operand" "")
15891                  (match_dup 1)))
15892    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15893    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15894    (parallel [(set (match_operand:XF 0 "register_operand" "")
15895                    (unspec:XF [(match_dup 1) (match_dup 5)]
15896                               UNSPEC_FPATAN))
15897               (clobber (match_scratch:XF 6 ""))])]
15898   "TARGET_USE_FANCY_MATH_387
15899    && flag_unsafe_math_optimizations"
15900 {
15901   int i;
15902
15903   if (optimize_insn_for_size_p ())
15904     FAIL;
15905
15906   for (i = 2; i < 6; i++)
15907     operands[i] = gen_reg_rtx (XFmode);
15908
15909   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15910 })
15911
15912 (define_expand "acos<mode>2"
15913   [(use (match_operand:MODEF 0 "register_operand" ""))
15914    (use (match_operand:MODEF 1 "general_operand" ""))]
15915  "TARGET_USE_FANCY_MATH_387
15916    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15917        || TARGET_MIX_SSE_I387)
15918    && flag_unsafe_math_optimizations"
15919 {
15920   rtx op0 = gen_reg_rtx (XFmode);
15921   rtx op1 = gen_reg_rtx (XFmode);
15922
15923   if (optimize_insn_for_size_p ())
15924     FAIL;
15925
15926   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15927   emit_insn (gen_acosxf2 (op0, op1));
15928   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15929   DONE;
15930 })
15931
15932 (define_insn "fyl2xxf3_i387"
15933   [(set (match_operand:XF 0 "register_operand" "=f")
15934         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15935                     (match_operand:XF 2 "register_operand" "u")]
15936                    UNSPEC_FYL2X))
15937    (clobber (match_scratch:XF 3 "=2"))]
15938   "TARGET_USE_FANCY_MATH_387
15939    && flag_unsafe_math_optimizations"
15940   "fyl2x"
15941   [(set_attr "type" "fpspc")
15942    (set_attr "mode" "XF")])
15943
15944 (define_insn "fyl2x_extend<mode>xf3_i387"
15945   [(set (match_operand:XF 0 "register_operand" "=f")
15946         (unspec:XF [(float_extend:XF
15947                       (match_operand:MODEF 1 "register_operand" "0"))
15948                     (match_operand:XF 2 "register_operand" "u")]
15949                    UNSPEC_FYL2X))
15950    (clobber (match_scratch:XF 3 "=2"))]
15951   "TARGET_USE_FANCY_MATH_387
15952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15953        || TARGET_MIX_SSE_I387)
15954    && flag_unsafe_math_optimizations"
15955   "fyl2x"
15956   [(set_attr "type" "fpspc")
15957    (set_attr "mode" "XF")])
15958
15959 (define_expand "logxf2"
15960   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15961                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15962                                (match_dup 2)] UNSPEC_FYL2X))
15963               (clobber (match_scratch:XF 3 ""))])]
15964   "TARGET_USE_FANCY_MATH_387
15965    && flag_unsafe_math_optimizations"
15966 {
15967   operands[2] = gen_reg_rtx (XFmode);
15968   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15969 })
15970
15971 (define_expand "log<mode>2"
15972   [(use (match_operand:MODEF 0 "register_operand" ""))
15973    (use (match_operand:MODEF 1 "register_operand" ""))]
15974   "TARGET_USE_FANCY_MATH_387
15975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15976        || TARGET_MIX_SSE_I387)
15977    && flag_unsafe_math_optimizations"
15978 {
15979   rtx op0 = gen_reg_rtx (XFmode);
15980
15981   rtx op2 = gen_reg_rtx (XFmode);
15982   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15983
15984   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15985   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15986   DONE;
15987 })
15988
15989 (define_expand "log10xf2"
15990   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15991                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15992                                (match_dup 2)] UNSPEC_FYL2X))
15993               (clobber (match_scratch:XF 3 ""))])]
15994   "TARGET_USE_FANCY_MATH_387
15995    && flag_unsafe_math_optimizations"
15996 {
15997   operands[2] = gen_reg_rtx (XFmode);
15998   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15999 })
16000
16001 (define_expand "log10<mode>2"
16002   [(use (match_operand:MODEF 0 "register_operand" ""))
16003    (use (match_operand:MODEF 1 "register_operand" ""))]
16004   "TARGET_USE_FANCY_MATH_387
16005    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16006        || TARGET_MIX_SSE_I387)
16007    && flag_unsafe_math_optimizations"
16008 {
16009   rtx op0 = gen_reg_rtx (XFmode);
16010
16011   rtx op2 = gen_reg_rtx (XFmode);
16012   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16013
16014   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16015   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16016   DONE;
16017 })
16018
16019 (define_expand "log2xf2"
16020   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16021                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16022                                (match_dup 2)] UNSPEC_FYL2X))
16023               (clobber (match_scratch:XF 3 ""))])]
16024   "TARGET_USE_FANCY_MATH_387
16025    && flag_unsafe_math_optimizations"
16026 {
16027   operands[2] = gen_reg_rtx (XFmode);
16028   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16029 })
16030
16031 (define_expand "log2<mode>2"
16032   [(use (match_operand:MODEF 0 "register_operand" ""))
16033    (use (match_operand:MODEF 1 "register_operand" ""))]
16034   "TARGET_USE_FANCY_MATH_387
16035    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16036        || TARGET_MIX_SSE_I387)
16037    && flag_unsafe_math_optimizations"
16038 {
16039   rtx op0 = gen_reg_rtx (XFmode);
16040
16041   rtx op2 = gen_reg_rtx (XFmode);
16042   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16043
16044   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16045   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16046   DONE;
16047 })
16048
16049 (define_insn "fyl2xp1xf3_i387"
16050   [(set (match_operand:XF 0 "register_operand" "=f")
16051         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16052                     (match_operand:XF 2 "register_operand" "u")]
16053                    UNSPEC_FYL2XP1))
16054    (clobber (match_scratch:XF 3 "=2"))]
16055   "TARGET_USE_FANCY_MATH_387
16056    && flag_unsafe_math_optimizations"
16057   "fyl2xp1"
16058   [(set_attr "type" "fpspc")
16059    (set_attr "mode" "XF")])
16060
16061 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16062   [(set (match_operand:XF 0 "register_operand" "=f")
16063         (unspec:XF [(float_extend:XF
16064                       (match_operand:MODEF 1 "register_operand" "0"))
16065                     (match_operand:XF 2 "register_operand" "u")]
16066                    UNSPEC_FYL2XP1))
16067    (clobber (match_scratch:XF 3 "=2"))]
16068   "TARGET_USE_FANCY_MATH_387
16069    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16070        || TARGET_MIX_SSE_I387)
16071    && flag_unsafe_math_optimizations"
16072   "fyl2xp1"
16073   [(set_attr "type" "fpspc")
16074    (set_attr "mode" "XF")])
16075
16076 (define_expand "log1pxf2"
16077   [(use (match_operand:XF 0 "register_operand" ""))
16078    (use (match_operand:XF 1 "register_operand" ""))]
16079   "TARGET_USE_FANCY_MATH_387
16080    && flag_unsafe_math_optimizations"
16081 {
16082   if (optimize_insn_for_size_p ())
16083     FAIL;
16084
16085   ix86_emit_i387_log1p (operands[0], operands[1]);
16086   DONE;
16087 })
16088
16089 (define_expand "log1p<mode>2"
16090   [(use (match_operand:MODEF 0 "register_operand" ""))
16091    (use (match_operand:MODEF 1 "register_operand" ""))]
16092   "TARGET_USE_FANCY_MATH_387
16093    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16094        || TARGET_MIX_SSE_I387)
16095    && flag_unsafe_math_optimizations"
16096 {
16097   rtx op0;
16098
16099   if (optimize_insn_for_size_p ())
16100     FAIL;
16101
16102   op0 = gen_reg_rtx (XFmode);
16103
16104   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16105
16106   ix86_emit_i387_log1p (op0, operands[1]);
16107   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16108   DONE;
16109 })
16110
16111 (define_insn "fxtractxf3_i387"
16112   [(set (match_operand:XF 0 "register_operand" "=f")
16113         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16114                    UNSPEC_XTRACT_FRACT))
16115    (set (match_operand:XF 1 "register_operand" "=u")
16116         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16117   "TARGET_USE_FANCY_MATH_387
16118    && flag_unsafe_math_optimizations"
16119   "fxtract"
16120   [(set_attr "type" "fpspc")
16121    (set_attr "mode" "XF")])
16122
16123 (define_insn "fxtract_extend<mode>xf3_i387"
16124   [(set (match_operand:XF 0 "register_operand" "=f")
16125         (unspec:XF [(float_extend:XF
16126                       (match_operand:MODEF 2 "register_operand" "0"))]
16127                    UNSPEC_XTRACT_FRACT))
16128    (set (match_operand:XF 1 "register_operand" "=u")
16129         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16130   "TARGET_USE_FANCY_MATH_387
16131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16132        || TARGET_MIX_SSE_I387)
16133    && flag_unsafe_math_optimizations"
16134   "fxtract"
16135   [(set_attr "type" "fpspc")
16136    (set_attr "mode" "XF")])
16137
16138 (define_expand "logbxf2"
16139   [(parallel [(set (match_dup 2)
16140                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16141                               UNSPEC_XTRACT_FRACT))
16142               (set (match_operand:XF 0 "register_operand" "")
16143                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16144   "TARGET_USE_FANCY_MATH_387
16145    && flag_unsafe_math_optimizations"
16146 {
16147   operands[2] = gen_reg_rtx (XFmode);
16148 })
16149
16150 (define_expand "logb<mode>2"
16151   [(use (match_operand:MODEF 0 "register_operand" ""))
16152    (use (match_operand:MODEF 1 "register_operand" ""))]
16153   "TARGET_USE_FANCY_MATH_387
16154    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16155        || TARGET_MIX_SSE_I387)
16156    && flag_unsafe_math_optimizations"
16157 {
16158   rtx op0 = gen_reg_rtx (XFmode);
16159   rtx op1 = gen_reg_rtx (XFmode);
16160
16161   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16162   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16163   DONE;
16164 })
16165
16166 (define_expand "ilogbxf2"
16167   [(use (match_operand:SI 0 "register_operand" ""))
16168    (use (match_operand:XF 1 "register_operand" ""))]
16169   "TARGET_USE_FANCY_MATH_387
16170    && flag_unsafe_math_optimizations"
16171 {
16172   rtx op0, op1;
16173
16174   if (optimize_insn_for_size_p ())
16175     FAIL;
16176
16177   op0 = gen_reg_rtx (XFmode);
16178   op1 = gen_reg_rtx (XFmode);
16179
16180   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16181   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16182   DONE;
16183 })
16184
16185 (define_expand "ilogb<mode>2"
16186   [(use (match_operand:SI 0 "register_operand" ""))
16187    (use (match_operand:MODEF 1 "register_operand" ""))]
16188   "TARGET_USE_FANCY_MATH_387
16189    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16190        || TARGET_MIX_SSE_I387)
16191    && flag_unsafe_math_optimizations"
16192 {
16193   rtx op0, op1;
16194
16195   if (optimize_insn_for_size_p ())
16196     FAIL;
16197
16198   op0 = gen_reg_rtx (XFmode);
16199   op1 = gen_reg_rtx (XFmode);
16200
16201   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16202   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16203   DONE;
16204 })
16205
16206 (define_insn "*f2xm1xf2_i387"
16207   [(set (match_operand:XF 0 "register_operand" "=f")
16208         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16209                    UNSPEC_F2XM1))]
16210   "TARGET_USE_FANCY_MATH_387
16211    && flag_unsafe_math_optimizations"
16212   "f2xm1"
16213   [(set_attr "type" "fpspc")
16214    (set_attr "mode" "XF")])
16215
16216 (define_insn "*fscalexf4_i387"
16217   [(set (match_operand:XF 0 "register_operand" "=f")
16218         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16219                     (match_operand:XF 3 "register_operand" "1")]
16220                    UNSPEC_FSCALE_FRACT))
16221    (set (match_operand:XF 1 "register_operand" "=u")
16222         (unspec:XF [(match_dup 2) (match_dup 3)]
16223                    UNSPEC_FSCALE_EXP))]
16224   "TARGET_USE_FANCY_MATH_387
16225    && flag_unsafe_math_optimizations"
16226   "fscale"
16227   [(set_attr "type" "fpspc")
16228    (set_attr "mode" "XF")])
16229
16230 (define_expand "expNcorexf3"
16231   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16232                                (match_operand:XF 2 "register_operand" "")))
16233    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16234    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16235    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16236    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16237    (parallel [(set (match_operand:XF 0 "register_operand" "")
16238                    (unspec:XF [(match_dup 8) (match_dup 4)]
16239                               UNSPEC_FSCALE_FRACT))
16240               (set (match_dup 9)
16241                    (unspec:XF [(match_dup 8) (match_dup 4)]
16242                               UNSPEC_FSCALE_EXP))])]
16243   "TARGET_USE_FANCY_MATH_387
16244    && flag_unsafe_math_optimizations"
16245 {
16246   int i;
16247
16248   if (optimize_insn_for_size_p ())
16249     FAIL;
16250
16251   for (i = 3; i < 10; i++)
16252     operands[i] = gen_reg_rtx (XFmode);
16253
16254   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16255 })
16256
16257 (define_expand "expxf2"
16258   [(use (match_operand:XF 0 "register_operand" ""))
16259    (use (match_operand:XF 1 "register_operand" ""))]
16260   "TARGET_USE_FANCY_MATH_387
16261    && flag_unsafe_math_optimizations"
16262 {
16263   rtx op2;
16264
16265   if (optimize_insn_for_size_p ())
16266     FAIL;
16267
16268   op2 = gen_reg_rtx (XFmode);
16269   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16270
16271   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16272   DONE;
16273 })
16274
16275 (define_expand "exp<mode>2"
16276   [(use (match_operand:MODEF 0 "register_operand" ""))
16277    (use (match_operand:MODEF 1 "general_operand" ""))]
16278  "TARGET_USE_FANCY_MATH_387
16279    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16280        || TARGET_MIX_SSE_I387)
16281    && flag_unsafe_math_optimizations"
16282 {
16283   rtx op0, op1;
16284
16285   if (optimize_insn_for_size_p ())
16286     FAIL;
16287
16288   op0 = gen_reg_rtx (XFmode);
16289   op1 = gen_reg_rtx (XFmode);
16290
16291   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16292   emit_insn (gen_expxf2 (op0, op1));
16293   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16294   DONE;
16295 })
16296
16297 (define_expand "exp10xf2"
16298   [(use (match_operand:XF 0 "register_operand" ""))
16299    (use (match_operand:XF 1 "register_operand" ""))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && flag_unsafe_math_optimizations"
16302 {
16303   rtx op2;
16304
16305   if (optimize_insn_for_size_p ())
16306     FAIL;
16307
16308   op2 = gen_reg_rtx (XFmode);
16309   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16310
16311   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16312   DONE;
16313 })
16314
16315 (define_expand "exp10<mode>2"
16316   [(use (match_operand:MODEF 0 "register_operand" ""))
16317    (use (match_operand:MODEF 1 "general_operand" ""))]
16318  "TARGET_USE_FANCY_MATH_387
16319    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16320        || TARGET_MIX_SSE_I387)
16321    && flag_unsafe_math_optimizations"
16322 {
16323   rtx op0, op1;
16324
16325   if (optimize_insn_for_size_p ())
16326     FAIL;
16327
16328   op0 = gen_reg_rtx (XFmode);
16329   op1 = gen_reg_rtx (XFmode);
16330
16331   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16332   emit_insn (gen_exp10xf2 (op0, op1));
16333   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16334   DONE;
16335 })
16336
16337 (define_expand "exp2xf2"
16338   [(use (match_operand:XF 0 "register_operand" ""))
16339    (use (match_operand:XF 1 "register_operand" ""))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342 {
16343   rtx op2;
16344
16345   if (optimize_insn_for_size_p ())
16346     FAIL;
16347
16348   op2 = gen_reg_rtx (XFmode);
16349   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16350
16351   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16352   DONE;
16353 })
16354
16355 (define_expand "exp2<mode>2"
16356   [(use (match_operand:MODEF 0 "register_operand" ""))
16357    (use (match_operand:MODEF 1 "general_operand" ""))]
16358  "TARGET_USE_FANCY_MATH_387
16359    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16360        || TARGET_MIX_SSE_I387)
16361    && flag_unsafe_math_optimizations"
16362 {
16363   rtx op0, op1;
16364
16365   if (optimize_insn_for_size_p ())
16366     FAIL;
16367
16368   op0 = gen_reg_rtx (XFmode);
16369   op1 = gen_reg_rtx (XFmode);
16370
16371   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16372   emit_insn (gen_exp2xf2 (op0, op1));
16373   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16374   DONE;
16375 })
16376
16377 (define_expand "expm1xf2"
16378   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16379                                (match_dup 2)))
16380    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16381    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16382    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16383    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16384    (parallel [(set (match_dup 7)
16385                    (unspec:XF [(match_dup 6) (match_dup 4)]
16386                               UNSPEC_FSCALE_FRACT))
16387               (set (match_dup 8)
16388                    (unspec:XF [(match_dup 6) (match_dup 4)]
16389                               UNSPEC_FSCALE_EXP))])
16390    (parallel [(set (match_dup 10)
16391                    (unspec:XF [(match_dup 9) (match_dup 8)]
16392                               UNSPEC_FSCALE_FRACT))
16393               (set (match_dup 11)
16394                    (unspec:XF [(match_dup 9) (match_dup 8)]
16395                               UNSPEC_FSCALE_EXP))])
16396    (set (match_dup 12) (minus:XF (match_dup 10)
16397                                  (float_extend:XF (match_dup 13))))
16398    (set (match_operand:XF 0 "register_operand" "")
16399         (plus:XF (match_dup 12) (match_dup 7)))]
16400   "TARGET_USE_FANCY_MATH_387
16401    && flag_unsafe_math_optimizations"
16402 {
16403   int i;
16404
16405   if (optimize_insn_for_size_p ())
16406     FAIL;
16407
16408   for (i = 2; i < 13; i++)
16409     operands[i] = gen_reg_rtx (XFmode);
16410
16411   operands[13]
16412     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16413
16414   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16415 })
16416
16417 (define_expand "expm1<mode>2"
16418   [(use (match_operand:MODEF 0 "register_operand" ""))
16419    (use (match_operand:MODEF 1 "general_operand" ""))]
16420  "TARGET_USE_FANCY_MATH_387
16421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16422        || TARGET_MIX_SSE_I387)
16423    && flag_unsafe_math_optimizations"
16424 {
16425   rtx op0, op1;
16426
16427   if (optimize_insn_for_size_p ())
16428     FAIL;
16429
16430   op0 = gen_reg_rtx (XFmode);
16431   op1 = gen_reg_rtx (XFmode);
16432
16433   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16434   emit_insn (gen_expm1xf2 (op0, op1));
16435   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16436   DONE;
16437 })
16438
16439 (define_expand "ldexpxf3"
16440   [(set (match_dup 3)
16441         (float:XF (match_operand:SI 2 "register_operand" "")))
16442    (parallel [(set (match_operand:XF 0 " register_operand" "")
16443                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16444                                (match_dup 3)]
16445                               UNSPEC_FSCALE_FRACT))
16446               (set (match_dup 4)
16447                    (unspec:XF [(match_dup 1) (match_dup 3)]
16448                               UNSPEC_FSCALE_EXP))])]
16449   "TARGET_USE_FANCY_MATH_387
16450    && flag_unsafe_math_optimizations"
16451 {
16452   if (optimize_insn_for_size_p ())
16453     FAIL;
16454
16455   operands[3] = gen_reg_rtx (XFmode);
16456   operands[4] = gen_reg_rtx (XFmode);
16457 })
16458
16459 (define_expand "ldexp<mode>3"
16460   [(use (match_operand:MODEF 0 "register_operand" ""))
16461    (use (match_operand:MODEF 1 "general_operand" ""))
16462    (use (match_operand:SI 2 "register_operand" ""))]
16463  "TARGET_USE_FANCY_MATH_387
16464    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16465        || TARGET_MIX_SSE_I387)
16466    && flag_unsafe_math_optimizations"
16467 {
16468   rtx op0, op1;
16469
16470   if (optimize_insn_for_size_p ())
16471     FAIL;
16472
16473   op0 = gen_reg_rtx (XFmode);
16474   op1 = gen_reg_rtx (XFmode);
16475
16476   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16477   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16478   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16479   DONE;
16480 })
16481
16482 (define_expand "scalbxf3"
16483   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16484                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16485                                (match_operand:XF 2 "register_operand" "")]
16486                               UNSPEC_FSCALE_FRACT))
16487               (set (match_dup 3)
16488                    (unspec:XF [(match_dup 1) (match_dup 2)]
16489                               UNSPEC_FSCALE_EXP))])]
16490   "TARGET_USE_FANCY_MATH_387
16491    && flag_unsafe_math_optimizations"
16492 {
16493   if (optimize_insn_for_size_p ())
16494     FAIL;
16495
16496   operands[3] = gen_reg_rtx (XFmode);
16497 })
16498
16499 (define_expand "scalb<mode>3"
16500   [(use (match_operand:MODEF 0 "register_operand" ""))
16501    (use (match_operand:MODEF 1 "general_operand" ""))
16502    (use (match_operand:MODEF 2 "general_operand" ""))]
16503  "TARGET_USE_FANCY_MATH_387
16504    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16505        || TARGET_MIX_SSE_I387)
16506    && flag_unsafe_math_optimizations"
16507 {
16508   rtx op0, op1, op2;
16509
16510   if (optimize_insn_for_size_p ())
16511     FAIL;
16512
16513   op0 = gen_reg_rtx (XFmode);
16514   op1 = gen_reg_rtx (XFmode);
16515   op2 = gen_reg_rtx (XFmode);
16516
16517   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16518   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16519   emit_insn (gen_scalbxf3 (op0, op1, op2));
16520   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16521   DONE;
16522 })
16523
16524 (define_expand "significandxf2"
16525   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16526                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16527                               UNSPEC_XTRACT_FRACT))
16528               (set (match_dup 2)
16529                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16530   "TARGET_USE_FANCY_MATH_387
16531    && flag_unsafe_math_optimizations"
16532 {
16533   operands[2] = gen_reg_rtx (XFmode);
16534 })
16535
16536 (define_expand "significand<mode>2"
16537   [(use (match_operand:MODEF 0 "register_operand" ""))
16538    (use (match_operand:MODEF 1 "register_operand" ""))]
16539   "TARGET_USE_FANCY_MATH_387
16540    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16541        || TARGET_MIX_SSE_I387)
16542    && flag_unsafe_math_optimizations"
16543 {
16544   rtx op0 = gen_reg_rtx (XFmode);
16545   rtx op1 = gen_reg_rtx (XFmode);
16546
16547   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16548   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16549   DONE;
16550 })
16551 \f
16552
16553 (define_insn "sse4_1_round<mode>2"
16554   [(set (match_operand:MODEF 0 "register_operand" "=x")
16555         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16556                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
16557                       UNSPEC_ROUND))]
16558   "TARGET_ROUND"
16559   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16560   [(set_attr "type" "ssecvt")
16561    (set_attr "prefix_extra" "1")
16562    (set_attr "prefix" "maybe_vex")
16563    (set_attr "mode" "<MODE>")])
16564
16565 (define_insn "rintxf2"
16566   [(set (match_operand:XF 0 "register_operand" "=f")
16567         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16568                    UNSPEC_FRNDINT))]
16569   "TARGET_USE_FANCY_MATH_387
16570    && flag_unsafe_math_optimizations"
16571   "frndint"
16572   [(set_attr "type" "fpspc")
16573    (set_attr "mode" "XF")])
16574
16575 (define_expand "rint<mode>2"
16576   [(use (match_operand:MODEF 0 "register_operand" ""))
16577    (use (match_operand:MODEF 1 "register_operand" ""))]
16578   "(TARGET_USE_FANCY_MATH_387
16579     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580         || TARGET_MIX_SSE_I387)
16581     && flag_unsafe_math_optimizations)
16582    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16583        && !flag_trapping_math)"
16584 {
16585   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16586       && !flag_trapping_math)
16587     {
16588       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16589         FAIL;
16590       if (TARGET_ROUND)
16591         emit_insn (gen_sse4_1_round<mode>2
16592                    (operands[0], operands[1], GEN_INT (0x04)));
16593       else
16594         ix86_expand_rint (operand0, operand1);
16595     }
16596   else
16597     {
16598       rtx op0 = gen_reg_rtx (XFmode);
16599       rtx op1 = gen_reg_rtx (XFmode);
16600
16601       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16602       emit_insn (gen_rintxf2 (op0, op1));
16603
16604       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16605     }
16606   DONE;
16607 })
16608
16609 (define_expand "round<mode>2"
16610   [(match_operand:MODEF 0 "register_operand" "")
16611    (match_operand:MODEF 1 "nonimmediate_operand" "")]
16612   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16613    && !flag_trapping_math && !flag_rounding_math"
16614 {
16615   if (optimize_insn_for_size_p ())
16616     FAIL;
16617   if (TARGET_64BIT || (<MODE>mode != DFmode))
16618     ix86_expand_round (operand0, operand1);
16619   else
16620     ix86_expand_rounddf_32 (operand0, operand1);
16621   DONE;
16622 })
16623
16624 (define_insn_and_split "*fistdi2_1"
16625   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16626         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16627                    UNSPEC_FIST))]
16628   "TARGET_USE_FANCY_MATH_387
16629    && can_create_pseudo_p ()"
16630   "#"
16631   "&& 1"
16632   [(const_int 0)]
16633 {
16634   if (memory_operand (operands[0], VOIDmode))
16635     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16636   else
16637     {
16638       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16639       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16640                                          operands[2]));
16641     }
16642   DONE;
16643 }
16644   [(set_attr "type" "fpspc")
16645    (set_attr "mode" "DI")])
16646
16647 (define_insn "fistdi2"
16648   [(set (match_operand:DI 0 "memory_operand" "=m")
16649         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16650                    UNSPEC_FIST))
16651    (clobber (match_scratch:XF 2 "=&1f"))]
16652   "TARGET_USE_FANCY_MATH_387"
16653   "* return output_fix_trunc (insn, operands, 0);"
16654   [(set_attr "type" "fpspc")
16655    (set_attr "mode" "DI")])
16656
16657 (define_insn "fistdi2_with_temp"
16658   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16659         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16660                    UNSPEC_FIST))
16661    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16662    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16663   "TARGET_USE_FANCY_MATH_387"
16664   "#"
16665   [(set_attr "type" "fpspc")
16666    (set_attr "mode" "DI")])
16667
16668 (define_split
16669   [(set (match_operand:DI 0 "register_operand" "")
16670         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16671                    UNSPEC_FIST))
16672    (clobber (match_operand:DI 2 "memory_operand" ""))
16673    (clobber (match_scratch 3 ""))]
16674   "reload_completed"
16675   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16676               (clobber (match_dup 3))])
16677    (set (match_dup 0) (match_dup 2))]
16678   "")
16679
16680 (define_split
16681   [(set (match_operand:DI 0 "memory_operand" "")
16682         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16683                    UNSPEC_FIST))
16684    (clobber (match_operand:DI 2 "memory_operand" ""))
16685    (clobber (match_scratch 3 ""))]
16686   "reload_completed"
16687   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16688               (clobber (match_dup 3))])]
16689   "")
16690
16691 (define_insn_and_split "*fist<mode>2_1"
16692   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16693         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16694                            UNSPEC_FIST))]
16695   "TARGET_USE_FANCY_MATH_387
16696    && can_create_pseudo_p ()"
16697   "#"
16698   "&& 1"
16699   [(const_int 0)]
16700 {
16701   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16702   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16703                                         operands[2]));
16704   DONE;
16705 }
16706   [(set_attr "type" "fpspc")
16707    (set_attr "mode" "<MODE>")])
16708
16709 (define_insn "fist<mode>2"
16710   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16711         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16712                            UNSPEC_FIST))]
16713   "TARGET_USE_FANCY_MATH_387"
16714   "* return output_fix_trunc (insn, operands, 0);"
16715   [(set_attr "type" "fpspc")
16716    (set_attr "mode" "<MODE>")])
16717
16718 (define_insn "fist<mode>2_with_temp"
16719   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16720         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16721                            UNSPEC_FIST))
16722    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16723   "TARGET_USE_FANCY_MATH_387"
16724   "#"
16725   [(set_attr "type" "fpspc")
16726    (set_attr "mode" "<MODE>")])
16727
16728 (define_split
16729   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16730         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16731                            UNSPEC_FIST))
16732    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16733   "reload_completed"
16734   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16735    (set (match_dup 0) (match_dup 2))]
16736   "")
16737
16738 (define_split
16739   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16740         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16741                            UNSPEC_FIST))
16742    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16743   "reload_completed"
16744   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16745   "")
16746
16747 (define_expand "lrintxf<mode>2"
16748   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16749      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16750                       UNSPEC_FIST))]
16751   "TARGET_USE_FANCY_MATH_387"
16752   "")
16753
16754 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16755   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16756      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16757                         UNSPEC_FIX_NOTRUNC))]
16758   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16759    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16760   "")
16761
16762 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16763   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16764    (match_operand:MODEF 1 "register_operand" "")]
16765   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16766    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16767    && !flag_trapping_math && !flag_rounding_math"
16768 {
16769   if (optimize_insn_for_size_p ())
16770     FAIL;
16771   ix86_expand_lround (operand0, operand1);
16772   DONE;
16773 })
16774
16775 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16776 (define_insn_and_split "frndintxf2_floor"
16777   [(set (match_operand:XF 0 "register_operand" "")
16778         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16779          UNSPEC_FRNDINT_FLOOR))
16780    (clobber (reg:CC FLAGS_REG))]
16781   "TARGET_USE_FANCY_MATH_387
16782    && flag_unsafe_math_optimizations
16783    && can_create_pseudo_p ()"
16784   "#"
16785   "&& 1"
16786   [(const_int 0)]
16787 {
16788   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16789
16790   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16791   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16792
16793   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16794                                         operands[2], operands[3]));
16795   DONE;
16796 }
16797   [(set_attr "type" "frndint")
16798    (set_attr "i387_cw" "floor")
16799    (set_attr "mode" "XF")])
16800
16801 (define_insn "frndintxf2_floor_i387"
16802   [(set (match_operand:XF 0 "register_operand" "=f")
16803         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16804          UNSPEC_FRNDINT_FLOOR))
16805    (use (match_operand:HI 2 "memory_operand" "m"))
16806    (use (match_operand:HI 3 "memory_operand" "m"))]
16807   "TARGET_USE_FANCY_MATH_387
16808    && flag_unsafe_math_optimizations"
16809   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16810   [(set_attr "type" "frndint")
16811    (set_attr "i387_cw" "floor")
16812    (set_attr "mode" "XF")])
16813
16814 (define_expand "floorxf2"
16815   [(use (match_operand:XF 0 "register_operand" ""))
16816    (use (match_operand:XF 1 "register_operand" ""))]
16817   "TARGET_USE_FANCY_MATH_387
16818    && flag_unsafe_math_optimizations"
16819 {
16820   if (optimize_insn_for_size_p ())
16821     FAIL;
16822   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16823   DONE;
16824 })
16825
16826 (define_expand "floor<mode>2"
16827   [(use (match_operand:MODEF 0 "register_operand" ""))
16828    (use (match_operand:MODEF 1 "register_operand" ""))]
16829   "(TARGET_USE_FANCY_MATH_387
16830     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831         || TARGET_MIX_SSE_I387)
16832     && flag_unsafe_math_optimizations)
16833    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834        && !flag_trapping_math)"
16835 {
16836   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16837       && !flag_trapping_math
16838       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16839     {
16840       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16841         FAIL;
16842       if (TARGET_ROUND)
16843         emit_insn (gen_sse4_1_round<mode>2
16844                    (operands[0], operands[1], GEN_INT (0x01)));
16845       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16846         ix86_expand_floorceil (operand0, operand1, true);
16847       else
16848         ix86_expand_floorceildf_32 (operand0, operand1, true);
16849     }
16850   else
16851     {
16852       rtx op0, op1;
16853
16854       if (optimize_insn_for_size_p ())
16855         FAIL;
16856
16857       op0 = gen_reg_rtx (XFmode);
16858       op1 = gen_reg_rtx (XFmode);
16859       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16860       emit_insn (gen_frndintxf2_floor (op0, op1));
16861
16862       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16863     }
16864   DONE;
16865 })
16866
16867 (define_insn_and_split "*fist<mode>2_floor_1"
16868   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16869         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16870          UNSPEC_FIST_FLOOR))
16871    (clobber (reg:CC FLAGS_REG))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && flag_unsafe_math_optimizations
16874    && can_create_pseudo_p ()"
16875   "#"
16876   "&& 1"
16877   [(const_int 0)]
16878 {
16879   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16880
16881   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16882   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16883   if (memory_operand (operands[0], VOIDmode))
16884     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16885                                       operands[2], operands[3]));
16886   else
16887     {
16888       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16889       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16890                                                   operands[2], operands[3],
16891                                                   operands[4]));
16892     }
16893   DONE;
16894 }
16895   [(set_attr "type" "fistp")
16896    (set_attr "i387_cw" "floor")
16897    (set_attr "mode" "<MODE>")])
16898
16899 (define_insn "fistdi2_floor"
16900   [(set (match_operand:DI 0 "memory_operand" "=m")
16901         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16902          UNSPEC_FIST_FLOOR))
16903    (use (match_operand:HI 2 "memory_operand" "m"))
16904    (use (match_operand:HI 3 "memory_operand" "m"))
16905    (clobber (match_scratch:XF 4 "=&1f"))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && flag_unsafe_math_optimizations"
16908   "* return output_fix_trunc (insn, operands, 0);"
16909   [(set_attr "type" "fistp")
16910    (set_attr "i387_cw" "floor")
16911    (set_attr "mode" "DI")])
16912
16913 (define_insn "fistdi2_floor_with_temp"
16914   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16915         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16916          UNSPEC_FIST_FLOOR))
16917    (use (match_operand:HI 2 "memory_operand" "m,m"))
16918    (use (match_operand:HI 3 "memory_operand" "m,m"))
16919    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16920    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16921   "TARGET_USE_FANCY_MATH_387
16922    && flag_unsafe_math_optimizations"
16923   "#"
16924   [(set_attr "type" "fistp")
16925    (set_attr "i387_cw" "floor")
16926    (set_attr "mode" "DI")])
16927
16928 (define_split
16929   [(set (match_operand:DI 0 "register_operand" "")
16930         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16931          UNSPEC_FIST_FLOOR))
16932    (use (match_operand:HI 2 "memory_operand" ""))
16933    (use (match_operand:HI 3 "memory_operand" ""))
16934    (clobber (match_operand:DI 4 "memory_operand" ""))
16935    (clobber (match_scratch 5 ""))]
16936   "reload_completed"
16937   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16938               (use (match_dup 2))
16939               (use (match_dup 3))
16940               (clobber (match_dup 5))])
16941    (set (match_dup 0) (match_dup 4))]
16942   "")
16943
16944 (define_split
16945   [(set (match_operand:DI 0 "memory_operand" "")
16946         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16947          UNSPEC_FIST_FLOOR))
16948    (use (match_operand:HI 2 "memory_operand" ""))
16949    (use (match_operand:HI 3 "memory_operand" ""))
16950    (clobber (match_operand:DI 4 "memory_operand" ""))
16951    (clobber (match_scratch 5 ""))]
16952   "reload_completed"
16953   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16954               (use (match_dup 2))
16955               (use (match_dup 3))
16956               (clobber (match_dup 5))])]
16957   "")
16958
16959 (define_insn "fist<mode>2_floor"
16960   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16961         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16962          UNSPEC_FIST_FLOOR))
16963    (use (match_operand:HI 2 "memory_operand" "m"))
16964    (use (match_operand:HI 3 "memory_operand" "m"))]
16965   "TARGET_USE_FANCY_MATH_387
16966    && flag_unsafe_math_optimizations"
16967   "* return output_fix_trunc (insn, operands, 0);"
16968   [(set_attr "type" "fistp")
16969    (set_attr "i387_cw" "floor")
16970    (set_attr "mode" "<MODE>")])
16971
16972 (define_insn "fist<mode>2_floor_with_temp"
16973   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16974         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16975          UNSPEC_FIST_FLOOR))
16976    (use (match_operand:HI 2 "memory_operand" "m,m"))
16977    (use (match_operand:HI 3 "memory_operand" "m,m"))
16978    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16979   "TARGET_USE_FANCY_MATH_387
16980    && flag_unsafe_math_optimizations"
16981   "#"
16982   [(set_attr "type" "fistp")
16983    (set_attr "i387_cw" "floor")
16984    (set_attr "mode" "<MODE>")])
16985
16986 (define_split
16987   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16988         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16989          UNSPEC_FIST_FLOOR))
16990    (use (match_operand:HI 2 "memory_operand" ""))
16991    (use (match_operand:HI 3 "memory_operand" ""))
16992    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16993   "reload_completed"
16994   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16995                                   UNSPEC_FIST_FLOOR))
16996               (use (match_dup 2))
16997               (use (match_dup 3))])
16998    (set (match_dup 0) (match_dup 4))]
16999   "")
17000
17001 (define_split
17002   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17003         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17004          UNSPEC_FIST_FLOOR))
17005    (use (match_operand:HI 2 "memory_operand" ""))
17006    (use (match_operand:HI 3 "memory_operand" ""))
17007    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17008   "reload_completed"
17009   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17010                                   UNSPEC_FIST_FLOOR))
17011               (use (match_dup 2))
17012               (use (match_dup 3))])]
17013   "")
17014
17015 (define_expand "lfloorxf<mode>2"
17016   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17017                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17018                     UNSPEC_FIST_FLOOR))
17019               (clobber (reg:CC FLAGS_REG))])]
17020   "TARGET_USE_FANCY_MATH_387
17021    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17022    && flag_unsafe_math_optimizations"
17023   "")
17024
17025 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17026   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17027    (match_operand:MODEF 1 "register_operand" "")]
17028   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17029    && !flag_trapping_math"
17030 {
17031   if (TARGET_64BIT && optimize_insn_for_size_p ())
17032     FAIL;
17033   ix86_expand_lfloorceil (operand0, operand1, true);
17034   DONE;
17035 })
17036
17037 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17038 (define_insn_and_split "frndintxf2_ceil"
17039   [(set (match_operand:XF 0 "register_operand" "")
17040         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17041          UNSPEC_FRNDINT_CEIL))
17042    (clobber (reg:CC FLAGS_REG))]
17043   "TARGET_USE_FANCY_MATH_387
17044    && flag_unsafe_math_optimizations
17045    && can_create_pseudo_p ()"
17046   "#"
17047   "&& 1"
17048   [(const_int 0)]
17049 {
17050   ix86_optimize_mode_switching[I387_CEIL] = 1;
17051
17052   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17053   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17054
17055   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17056                                        operands[2], operands[3]));
17057   DONE;
17058 }
17059   [(set_attr "type" "frndint")
17060    (set_attr "i387_cw" "ceil")
17061    (set_attr "mode" "XF")])
17062
17063 (define_insn "frndintxf2_ceil_i387"
17064   [(set (match_operand:XF 0 "register_operand" "=f")
17065         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17066          UNSPEC_FRNDINT_CEIL))
17067    (use (match_operand:HI 2 "memory_operand" "m"))
17068    (use (match_operand:HI 3 "memory_operand" "m"))]
17069   "TARGET_USE_FANCY_MATH_387
17070    && flag_unsafe_math_optimizations"
17071   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17072   [(set_attr "type" "frndint")
17073    (set_attr "i387_cw" "ceil")
17074    (set_attr "mode" "XF")])
17075
17076 (define_expand "ceilxf2"
17077   [(use (match_operand:XF 0 "register_operand" ""))
17078    (use (match_operand:XF 1 "register_operand" ""))]
17079   "TARGET_USE_FANCY_MATH_387
17080    && flag_unsafe_math_optimizations"
17081 {
17082   if (optimize_insn_for_size_p ())
17083     FAIL;
17084   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17085   DONE;
17086 })
17087
17088 (define_expand "ceil<mode>2"
17089   [(use (match_operand:MODEF 0 "register_operand" ""))
17090    (use (match_operand:MODEF 1 "register_operand" ""))]
17091   "(TARGET_USE_FANCY_MATH_387
17092     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17093         || TARGET_MIX_SSE_I387)
17094     && flag_unsafe_math_optimizations)
17095    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17096        && !flag_trapping_math)"
17097 {
17098   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17099       && !flag_trapping_math
17100       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17101     {
17102       if (TARGET_ROUND)
17103         emit_insn (gen_sse4_1_round<mode>2
17104                    (operands[0], operands[1], GEN_INT (0x02)));
17105       else if (optimize_insn_for_size_p ())
17106         FAIL;
17107       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17108         ix86_expand_floorceil (operand0, operand1, false);
17109       else
17110         ix86_expand_floorceildf_32 (operand0, operand1, false);
17111     }
17112   else
17113     {
17114       rtx op0, op1;
17115
17116       if (optimize_insn_for_size_p ())
17117         FAIL;
17118
17119       op0 = gen_reg_rtx (XFmode);
17120       op1 = gen_reg_rtx (XFmode);
17121       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17122       emit_insn (gen_frndintxf2_ceil (op0, op1));
17123
17124       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17125     }
17126   DONE;
17127 })
17128
17129 (define_insn_and_split "*fist<mode>2_ceil_1"
17130   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17131         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17132          UNSPEC_FIST_CEIL))
17133    (clobber (reg:CC FLAGS_REG))]
17134   "TARGET_USE_FANCY_MATH_387
17135    && flag_unsafe_math_optimizations
17136    && can_create_pseudo_p ()"
17137   "#"
17138   "&& 1"
17139   [(const_int 0)]
17140 {
17141   ix86_optimize_mode_switching[I387_CEIL] = 1;
17142
17143   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17144   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17145   if (memory_operand (operands[0], VOIDmode))
17146     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17147                                      operands[2], operands[3]));
17148   else
17149     {
17150       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17151       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17152                                                  operands[2], operands[3],
17153                                                  operands[4]));
17154     }
17155   DONE;
17156 }
17157   [(set_attr "type" "fistp")
17158    (set_attr "i387_cw" "ceil")
17159    (set_attr "mode" "<MODE>")])
17160
17161 (define_insn "fistdi2_ceil"
17162   [(set (match_operand:DI 0 "memory_operand" "=m")
17163         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17164          UNSPEC_FIST_CEIL))
17165    (use (match_operand:HI 2 "memory_operand" "m"))
17166    (use (match_operand:HI 3 "memory_operand" "m"))
17167    (clobber (match_scratch:XF 4 "=&1f"))]
17168   "TARGET_USE_FANCY_MATH_387
17169    && flag_unsafe_math_optimizations"
17170   "* return output_fix_trunc (insn, operands, 0);"
17171   [(set_attr "type" "fistp")
17172    (set_attr "i387_cw" "ceil")
17173    (set_attr "mode" "DI")])
17174
17175 (define_insn "fistdi2_ceil_with_temp"
17176   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17177         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17178          UNSPEC_FIST_CEIL))
17179    (use (match_operand:HI 2 "memory_operand" "m,m"))
17180    (use (match_operand:HI 3 "memory_operand" "m,m"))
17181    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17182    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17183   "TARGET_USE_FANCY_MATH_387
17184    && flag_unsafe_math_optimizations"
17185   "#"
17186   [(set_attr "type" "fistp")
17187    (set_attr "i387_cw" "ceil")
17188    (set_attr "mode" "DI")])
17189
17190 (define_split
17191   [(set (match_operand:DI 0 "register_operand" "")
17192         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17193          UNSPEC_FIST_CEIL))
17194    (use (match_operand:HI 2 "memory_operand" ""))
17195    (use (match_operand:HI 3 "memory_operand" ""))
17196    (clobber (match_operand:DI 4 "memory_operand" ""))
17197    (clobber (match_scratch 5 ""))]
17198   "reload_completed"
17199   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17200               (use (match_dup 2))
17201               (use (match_dup 3))
17202               (clobber (match_dup 5))])
17203    (set (match_dup 0) (match_dup 4))]
17204   "")
17205
17206 (define_split
17207   [(set (match_operand:DI 0 "memory_operand" "")
17208         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17209          UNSPEC_FIST_CEIL))
17210    (use (match_operand:HI 2 "memory_operand" ""))
17211    (use (match_operand:HI 3 "memory_operand" ""))
17212    (clobber (match_operand:DI 4 "memory_operand" ""))
17213    (clobber (match_scratch 5 ""))]
17214   "reload_completed"
17215   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17216               (use (match_dup 2))
17217               (use (match_dup 3))
17218               (clobber (match_dup 5))])]
17219   "")
17220
17221 (define_insn "fist<mode>2_ceil"
17222   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17223         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17224          UNSPEC_FIST_CEIL))
17225    (use (match_operand:HI 2 "memory_operand" "m"))
17226    (use (match_operand:HI 3 "memory_operand" "m"))]
17227   "TARGET_USE_FANCY_MATH_387
17228    && flag_unsafe_math_optimizations"
17229   "* return output_fix_trunc (insn, operands, 0);"
17230   [(set_attr "type" "fistp")
17231    (set_attr "i387_cw" "ceil")
17232    (set_attr "mode" "<MODE>")])
17233
17234 (define_insn "fist<mode>2_ceil_with_temp"
17235   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17236         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17237          UNSPEC_FIST_CEIL))
17238    (use (match_operand:HI 2 "memory_operand" "m,m"))
17239    (use (match_operand:HI 3 "memory_operand" "m,m"))
17240    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17241   "TARGET_USE_FANCY_MATH_387
17242    && flag_unsafe_math_optimizations"
17243   "#"
17244   [(set_attr "type" "fistp")
17245    (set_attr "i387_cw" "ceil")
17246    (set_attr "mode" "<MODE>")])
17247
17248 (define_split
17249   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17250         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17251          UNSPEC_FIST_CEIL))
17252    (use (match_operand:HI 2 "memory_operand" ""))
17253    (use (match_operand:HI 3 "memory_operand" ""))
17254    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17255   "reload_completed"
17256   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17257                                   UNSPEC_FIST_CEIL))
17258               (use (match_dup 2))
17259               (use (match_dup 3))])
17260    (set (match_dup 0) (match_dup 4))]
17261   "")
17262
17263 (define_split
17264   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17265         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17266          UNSPEC_FIST_CEIL))
17267    (use (match_operand:HI 2 "memory_operand" ""))
17268    (use (match_operand:HI 3 "memory_operand" ""))
17269    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17270   "reload_completed"
17271   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17272                                   UNSPEC_FIST_CEIL))
17273               (use (match_dup 2))
17274               (use (match_dup 3))])]
17275   "")
17276
17277 (define_expand "lceilxf<mode>2"
17278   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17279                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17280                     UNSPEC_FIST_CEIL))
17281               (clobber (reg:CC FLAGS_REG))])]
17282   "TARGET_USE_FANCY_MATH_387
17283    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17284    && flag_unsafe_math_optimizations"
17285   "")
17286
17287 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17288   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17289    (match_operand:MODEF 1 "register_operand" "")]
17290   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17291    && !flag_trapping_math"
17292 {
17293   ix86_expand_lfloorceil (operand0, operand1, false);
17294   DONE;
17295 })
17296
17297 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17298 (define_insn_and_split "frndintxf2_trunc"
17299   [(set (match_operand:XF 0 "register_operand" "")
17300         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17301          UNSPEC_FRNDINT_TRUNC))
17302    (clobber (reg:CC FLAGS_REG))]
17303   "TARGET_USE_FANCY_MATH_387
17304    && flag_unsafe_math_optimizations
17305    && can_create_pseudo_p ()"
17306   "#"
17307   "&& 1"
17308   [(const_int 0)]
17309 {
17310   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17311
17312   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17313   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17314
17315   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17316                                         operands[2], operands[3]));
17317   DONE;
17318 }
17319   [(set_attr "type" "frndint")
17320    (set_attr "i387_cw" "trunc")
17321    (set_attr "mode" "XF")])
17322
17323 (define_insn "frndintxf2_trunc_i387"
17324   [(set (match_operand:XF 0 "register_operand" "=f")
17325         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17326          UNSPEC_FRNDINT_TRUNC))
17327    (use (match_operand:HI 2 "memory_operand" "m"))
17328    (use (match_operand:HI 3 "memory_operand" "m"))]
17329   "TARGET_USE_FANCY_MATH_387
17330    && flag_unsafe_math_optimizations"
17331   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17332   [(set_attr "type" "frndint")
17333    (set_attr "i387_cw" "trunc")
17334    (set_attr "mode" "XF")])
17335
17336 (define_expand "btruncxf2"
17337   [(use (match_operand:XF 0 "register_operand" ""))
17338    (use (match_operand:XF 1 "register_operand" ""))]
17339   "TARGET_USE_FANCY_MATH_387
17340    && flag_unsafe_math_optimizations"
17341 {
17342   if (optimize_insn_for_size_p ())
17343     FAIL;
17344   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17345   DONE;
17346 })
17347
17348 (define_expand "btrunc<mode>2"
17349   [(use (match_operand:MODEF 0 "register_operand" ""))
17350    (use (match_operand:MODEF 1 "register_operand" ""))]
17351   "(TARGET_USE_FANCY_MATH_387
17352     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17353         || TARGET_MIX_SSE_I387)
17354     && flag_unsafe_math_optimizations)
17355    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17356        && !flag_trapping_math)"
17357 {
17358   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17359       && !flag_trapping_math
17360       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17361     {
17362       if (TARGET_ROUND)
17363         emit_insn (gen_sse4_1_round<mode>2
17364                    (operands[0], operands[1], GEN_INT (0x03)));
17365       else if (optimize_insn_for_size_p ())
17366         FAIL;
17367       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17368         ix86_expand_trunc (operand0, operand1);
17369       else
17370         ix86_expand_truncdf_32 (operand0, operand1);
17371     }
17372   else
17373     {
17374       rtx op0, op1;
17375
17376       if (optimize_insn_for_size_p ())
17377         FAIL;
17378
17379       op0 = gen_reg_rtx (XFmode);
17380       op1 = gen_reg_rtx (XFmode);
17381       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17382       emit_insn (gen_frndintxf2_trunc (op0, op1));
17383
17384       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17385     }
17386   DONE;
17387 })
17388
17389 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17390 (define_insn_and_split "frndintxf2_mask_pm"
17391   [(set (match_operand:XF 0 "register_operand" "")
17392         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17393          UNSPEC_FRNDINT_MASK_PM))
17394    (clobber (reg:CC FLAGS_REG))]
17395   "TARGET_USE_FANCY_MATH_387
17396    && flag_unsafe_math_optimizations
17397    && can_create_pseudo_p ()"
17398   "#"
17399   "&& 1"
17400   [(const_int 0)]
17401 {
17402   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17403
17404   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17405   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17406
17407   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17408                                           operands[2], operands[3]));
17409   DONE;
17410 }
17411   [(set_attr "type" "frndint")
17412    (set_attr "i387_cw" "mask_pm")
17413    (set_attr "mode" "XF")])
17414
17415 (define_insn "frndintxf2_mask_pm_i387"
17416   [(set (match_operand:XF 0 "register_operand" "=f")
17417         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17418          UNSPEC_FRNDINT_MASK_PM))
17419    (use (match_operand:HI 2 "memory_operand" "m"))
17420    (use (match_operand:HI 3 "memory_operand" "m"))]
17421   "TARGET_USE_FANCY_MATH_387
17422    && flag_unsafe_math_optimizations"
17423   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17424   [(set_attr "type" "frndint")
17425    (set_attr "i387_cw" "mask_pm")
17426    (set_attr "mode" "XF")])
17427
17428 (define_expand "nearbyintxf2"
17429   [(use (match_operand:XF 0 "register_operand" ""))
17430    (use (match_operand:XF 1 "register_operand" ""))]
17431   "TARGET_USE_FANCY_MATH_387
17432    && flag_unsafe_math_optimizations"
17433 {
17434   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17435
17436   DONE;
17437 })
17438
17439 (define_expand "nearbyint<mode>2"
17440   [(use (match_operand:MODEF 0 "register_operand" ""))
17441    (use (match_operand:MODEF 1 "register_operand" ""))]
17442   "TARGET_USE_FANCY_MATH_387
17443    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17444        || TARGET_MIX_SSE_I387)
17445    && flag_unsafe_math_optimizations"
17446 {
17447   rtx op0 = gen_reg_rtx (XFmode);
17448   rtx op1 = gen_reg_rtx (XFmode);
17449
17450   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17451   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17452
17453   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17454   DONE;
17455 })
17456
17457 (define_insn "fxam<mode>2_i387"
17458   [(set (match_operand:HI 0 "register_operand" "=a")
17459         (unspec:HI
17460           [(match_operand:X87MODEF 1 "register_operand" "f")]
17461           UNSPEC_FXAM))]
17462   "TARGET_USE_FANCY_MATH_387"
17463   "fxam\n\tfnstsw\t%0"
17464   [(set_attr "type" "multi")
17465    (set_attr "length" "4")
17466    (set_attr "unit" "i387")
17467    (set_attr "mode" "<MODE>")])
17468
17469 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17470   [(set (match_operand:HI 0 "register_operand" "")
17471         (unspec:HI
17472           [(match_operand:MODEF 1 "memory_operand" "")]
17473           UNSPEC_FXAM_MEM))]
17474   "TARGET_USE_FANCY_MATH_387
17475    && can_create_pseudo_p ()"
17476   "#"
17477   "&& 1"
17478   [(set (match_dup 2)(match_dup 1))
17479    (set (match_dup 0)
17480         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17481 {
17482   operands[2] = gen_reg_rtx (<MODE>mode);
17483
17484   MEM_VOLATILE_P (operands[1]) = 1;
17485 }
17486   [(set_attr "type" "multi")
17487    (set_attr "unit" "i387")
17488    (set_attr "mode" "<MODE>")])
17489
17490 (define_expand "isinfxf2"
17491   [(use (match_operand:SI 0 "register_operand" ""))
17492    (use (match_operand:XF 1 "register_operand" ""))]
17493   "TARGET_USE_FANCY_MATH_387
17494    && TARGET_C99_FUNCTIONS"
17495 {
17496   rtx mask = GEN_INT (0x45);
17497   rtx val = GEN_INT (0x05);
17498
17499   rtx cond;
17500
17501   rtx scratch = gen_reg_rtx (HImode);
17502   rtx res = gen_reg_rtx (QImode);
17503
17504   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17505
17506   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17507   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17508   cond = gen_rtx_fmt_ee (EQ, QImode,
17509                          gen_rtx_REG (CCmode, FLAGS_REG),
17510                          const0_rtx);
17511   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17512   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17513   DONE;
17514 })
17515
17516 (define_expand "isinf<mode>2"
17517   [(use (match_operand:SI 0 "register_operand" ""))
17518    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17519   "TARGET_USE_FANCY_MATH_387
17520    && TARGET_C99_FUNCTIONS
17521    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17522 {
17523   rtx mask = GEN_INT (0x45);
17524   rtx val = GEN_INT (0x05);
17525
17526   rtx cond;
17527
17528   rtx scratch = gen_reg_rtx (HImode);
17529   rtx res = gen_reg_rtx (QImode);
17530
17531   /* Remove excess precision by forcing value through memory. */
17532   if (memory_operand (operands[1], VOIDmode))
17533     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17534   else
17535     {
17536       enum ix86_stack_slot slot = (virtuals_instantiated
17537                                    ? SLOT_TEMP
17538                                    : SLOT_VIRTUAL);
17539       rtx temp = assign_386_stack_local (<MODE>mode, slot);
17540
17541       emit_move_insn (temp, operands[1]);
17542       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17543     }
17544
17545   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17546   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17547   cond = gen_rtx_fmt_ee (EQ, QImode,
17548                          gen_rtx_REG (CCmode, FLAGS_REG),
17549                          const0_rtx);
17550   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17551   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17552   DONE;
17553 })
17554
17555 (define_expand "signbit<mode>2"
17556   [(use (match_operand:SI 0 "register_operand" ""))
17557    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17558   "TARGET_USE_FANCY_MATH_387
17559    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17560 {
17561   rtx mask = GEN_INT (0x0200);
17562
17563   rtx scratch = gen_reg_rtx (HImode);
17564
17565   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17566   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17567   DONE;
17568 })
17569 \f
17570 ;; Block operation instructions
17571
17572 (define_insn "cld"
17573   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17574   ""
17575   "cld"
17576   [(set_attr "length" "1")
17577    (set_attr "length_immediate" "0")
17578    (set_attr "modrm" "0")])
17579
17580 (define_expand "movmemsi"
17581   [(use (match_operand:BLK 0 "memory_operand" ""))
17582    (use (match_operand:BLK 1 "memory_operand" ""))
17583    (use (match_operand:SI 2 "nonmemory_operand" ""))
17584    (use (match_operand:SI 3 "const_int_operand" ""))
17585    (use (match_operand:SI 4 "const_int_operand" ""))
17586    (use (match_operand:SI 5 "const_int_operand" ""))]
17587   ""
17588 {
17589  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17590                          operands[4], operands[5]))
17591    DONE;
17592  else
17593    FAIL;
17594 })
17595
17596 (define_expand "movmemdi"
17597   [(use (match_operand:BLK 0 "memory_operand" ""))
17598    (use (match_operand:BLK 1 "memory_operand" ""))
17599    (use (match_operand:DI 2 "nonmemory_operand" ""))
17600    (use (match_operand:DI 3 "const_int_operand" ""))
17601    (use (match_operand:SI 4 "const_int_operand" ""))
17602    (use (match_operand:SI 5 "const_int_operand" ""))]
17603   "TARGET_64BIT"
17604 {
17605  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17606                          operands[4], operands[5]))
17607    DONE;
17608  else
17609    FAIL;
17610 })
17611
17612 ;; Most CPUs don't like single string operations
17613 ;; Handle this case here to simplify previous expander.
17614
17615 (define_expand "strmov"
17616   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17617    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17618    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17619               (clobber (reg:CC FLAGS_REG))])
17620    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17621               (clobber (reg:CC FLAGS_REG))])]
17622   ""
17623 {
17624   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17625
17626   /* If .md ever supports :P for Pmode, these can be directly
17627      in the pattern above.  */
17628   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17629   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17630
17631   /* Can't use this if the user has appropriated esi or edi.  */
17632   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17633       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17634     {
17635       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17636                                       operands[2], operands[3],
17637                                       operands[5], operands[6]));
17638       DONE;
17639     }
17640
17641   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17642 })
17643
17644 (define_expand "strmov_singleop"
17645   [(parallel [(set (match_operand 1 "memory_operand" "")
17646                    (match_operand 3 "memory_operand" ""))
17647               (set (match_operand 0 "register_operand" "")
17648                    (match_operand 4 "" ""))
17649               (set (match_operand 2 "register_operand" "")
17650                    (match_operand 5 "" ""))])]
17651   ""
17652   "ix86_current_function_needs_cld = 1;")
17653
17654 (define_insn "*strmovdi_rex_1"
17655   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17656         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17657    (set (match_operand:DI 0 "register_operand" "=D")
17658         (plus:DI (match_dup 2)
17659                  (const_int 8)))
17660    (set (match_operand:DI 1 "register_operand" "=S")
17661         (plus:DI (match_dup 3)
17662                  (const_int 8)))]
17663   "TARGET_64BIT"
17664   "movsq"
17665   [(set_attr "type" "str")
17666    (set_attr "mode" "DI")
17667    (set_attr "memory" "both")])
17668
17669 (define_insn "*strmovsi_1"
17670   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17671         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17672    (set (match_operand:SI 0 "register_operand" "=D")
17673         (plus:SI (match_dup 2)
17674                  (const_int 4)))
17675    (set (match_operand:SI 1 "register_operand" "=S")
17676         (plus:SI (match_dup 3)
17677                  (const_int 4)))]
17678   "!TARGET_64BIT"
17679   "movs{l|d}"
17680   [(set_attr "type" "str")
17681    (set_attr "mode" "SI")
17682    (set_attr "memory" "both")])
17683
17684 (define_insn "*strmovsi_rex_1"
17685   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17686         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17687    (set (match_operand:DI 0 "register_operand" "=D")
17688         (plus:DI (match_dup 2)
17689                  (const_int 4)))
17690    (set (match_operand:DI 1 "register_operand" "=S")
17691         (plus:DI (match_dup 3)
17692                  (const_int 4)))]
17693   "TARGET_64BIT"
17694   "movs{l|d}"
17695   [(set_attr "type" "str")
17696    (set_attr "mode" "SI")
17697    (set_attr "memory" "both")])
17698
17699 (define_insn "*strmovhi_1"
17700   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17701         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17702    (set (match_operand:SI 0 "register_operand" "=D")
17703         (plus:SI (match_dup 2)
17704                  (const_int 2)))
17705    (set (match_operand:SI 1 "register_operand" "=S")
17706         (plus:SI (match_dup 3)
17707                  (const_int 2)))]
17708   "!TARGET_64BIT"
17709   "movsw"
17710   [(set_attr "type" "str")
17711    (set_attr "memory" "both")
17712    (set_attr "mode" "HI")])
17713
17714 (define_insn "*strmovhi_rex_1"
17715   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17716         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17717    (set (match_operand:DI 0 "register_operand" "=D")
17718         (plus:DI (match_dup 2)
17719                  (const_int 2)))
17720    (set (match_operand:DI 1 "register_operand" "=S")
17721         (plus:DI (match_dup 3)
17722                  (const_int 2)))]
17723   "TARGET_64BIT"
17724   "movsw"
17725   [(set_attr "type" "str")
17726    (set_attr "memory" "both")
17727    (set_attr "mode" "HI")])
17728
17729 (define_insn "*strmovqi_1"
17730   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17731         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17732    (set (match_operand:SI 0 "register_operand" "=D")
17733         (plus:SI (match_dup 2)
17734                  (const_int 1)))
17735    (set (match_operand:SI 1 "register_operand" "=S")
17736         (plus:SI (match_dup 3)
17737                  (const_int 1)))]
17738   "!TARGET_64BIT"
17739   "movsb"
17740   [(set_attr "type" "str")
17741    (set_attr "memory" "both")
17742    (set_attr "mode" "QI")])
17743
17744 (define_insn "*strmovqi_rex_1"
17745   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17746         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17747    (set (match_operand:DI 0 "register_operand" "=D")
17748         (plus:DI (match_dup 2)
17749                  (const_int 1)))
17750    (set (match_operand:DI 1 "register_operand" "=S")
17751         (plus:DI (match_dup 3)
17752                  (const_int 1)))]
17753   "TARGET_64BIT"
17754   "movsb"
17755   [(set_attr "type" "str")
17756    (set_attr "memory" "both")
17757    (set_attr "prefix_rex" "0")
17758    (set_attr "mode" "QI")])
17759
17760 (define_expand "rep_mov"
17761   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17762               (set (match_operand 0 "register_operand" "")
17763                    (match_operand 5 "" ""))
17764               (set (match_operand 2 "register_operand" "")
17765                    (match_operand 6 "" ""))
17766               (set (match_operand 1 "memory_operand" "")
17767                    (match_operand 3 "memory_operand" ""))
17768               (use (match_dup 4))])]
17769   ""
17770   "ix86_current_function_needs_cld = 1;")
17771
17772 (define_insn "*rep_movdi_rex64"
17773   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17774    (set (match_operand:DI 0 "register_operand" "=D")
17775         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17776                             (const_int 3))
17777                  (match_operand:DI 3 "register_operand" "0")))
17778    (set (match_operand:DI 1 "register_operand" "=S")
17779         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17780                  (match_operand:DI 4 "register_operand" "1")))
17781    (set (mem:BLK (match_dup 3))
17782         (mem:BLK (match_dup 4)))
17783    (use (match_dup 5))]
17784   "TARGET_64BIT"
17785   "rep movsq"
17786   [(set_attr "type" "str")
17787    (set_attr "prefix_rep" "1")
17788    (set_attr "memory" "both")
17789    (set_attr "mode" "DI")])
17790
17791 (define_insn "*rep_movsi"
17792   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17793    (set (match_operand:SI 0 "register_operand" "=D")
17794         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17795                             (const_int 2))
17796                  (match_operand:SI 3 "register_operand" "0")))
17797    (set (match_operand:SI 1 "register_operand" "=S")
17798         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17799                  (match_operand:SI 4 "register_operand" "1")))
17800    (set (mem:BLK (match_dup 3))
17801         (mem:BLK (match_dup 4)))
17802    (use (match_dup 5))]
17803   "!TARGET_64BIT"
17804   "rep movs{l|d}"
17805   [(set_attr "type" "str")
17806    (set_attr "prefix_rep" "1")
17807    (set_attr "memory" "both")
17808    (set_attr "mode" "SI")])
17809
17810 (define_insn "*rep_movsi_rex64"
17811   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17812    (set (match_operand:DI 0 "register_operand" "=D")
17813         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17814                             (const_int 2))
17815                  (match_operand:DI 3 "register_operand" "0")))
17816    (set (match_operand:DI 1 "register_operand" "=S")
17817         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17818                  (match_operand:DI 4 "register_operand" "1")))
17819    (set (mem:BLK (match_dup 3))
17820         (mem:BLK (match_dup 4)))
17821    (use (match_dup 5))]
17822   "TARGET_64BIT"
17823   "rep movs{l|d}"
17824   [(set_attr "type" "str")
17825    (set_attr "prefix_rep" "1")
17826    (set_attr "memory" "both")
17827    (set_attr "mode" "SI")])
17828
17829 (define_insn "*rep_movqi"
17830   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17831    (set (match_operand:SI 0 "register_operand" "=D")
17832         (plus:SI (match_operand:SI 3 "register_operand" "0")
17833                  (match_operand:SI 5 "register_operand" "2")))
17834    (set (match_operand:SI 1 "register_operand" "=S")
17835         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17836    (set (mem:BLK (match_dup 3))
17837         (mem:BLK (match_dup 4)))
17838    (use (match_dup 5))]
17839   "!TARGET_64BIT"
17840   "rep movsb"
17841   [(set_attr "type" "str")
17842    (set_attr "prefix_rep" "1")
17843    (set_attr "memory" "both")
17844    (set_attr "mode" "SI")])
17845
17846 (define_insn "*rep_movqi_rex64"
17847   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17848    (set (match_operand:DI 0 "register_operand" "=D")
17849         (plus:DI (match_operand:DI 3 "register_operand" "0")
17850                  (match_operand:DI 5 "register_operand" "2")))
17851    (set (match_operand:DI 1 "register_operand" "=S")
17852         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17853    (set (mem:BLK (match_dup 3))
17854         (mem:BLK (match_dup 4)))
17855    (use (match_dup 5))]
17856   "TARGET_64BIT"
17857   "rep movsb"
17858   [(set_attr "type" "str")
17859    (set_attr "prefix_rep" "1")
17860    (set_attr "memory" "both")
17861    (set_attr "mode" "SI")])
17862
17863 (define_expand "setmemsi"
17864    [(use (match_operand:BLK 0 "memory_operand" ""))
17865     (use (match_operand:SI 1 "nonmemory_operand" ""))
17866     (use (match_operand 2 "const_int_operand" ""))
17867     (use (match_operand 3 "const_int_operand" ""))
17868     (use (match_operand:SI 4 "const_int_operand" ""))
17869     (use (match_operand:SI 5 "const_int_operand" ""))]
17870   ""
17871 {
17872  if (ix86_expand_setmem (operands[0], operands[1],
17873                          operands[2], operands[3],
17874                          operands[4], operands[5]))
17875    DONE;
17876  else
17877    FAIL;
17878 })
17879
17880 (define_expand "setmemdi"
17881    [(use (match_operand:BLK 0 "memory_operand" ""))
17882     (use (match_operand:DI 1 "nonmemory_operand" ""))
17883     (use (match_operand 2 "const_int_operand" ""))
17884     (use (match_operand 3 "const_int_operand" ""))
17885     (use (match_operand 4 "const_int_operand" ""))
17886     (use (match_operand 5 "const_int_operand" ""))]
17887   "TARGET_64BIT"
17888 {
17889  if (ix86_expand_setmem (operands[0], operands[1],
17890                          operands[2], operands[3],
17891                          operands[4], operands[5]))
17892    DONE;
17893  else
17894    FAIL;
17895 })
17896
17897 ;; Most CPUs don't like single string operations
17898 ;; Handle this case here to simplify previous expander.
17899
17900 (define_expand "strset"
17901   [(set (match_operand 1 "memory_operand" "")
17902         (match_operand 2 "register_operand" ""))
17903    (parallel [(set (match_operand 0 "register_operand" "")
17904                    (match_dup 3))
17905               (clobber (reg:CC FLAGS_REG))])]
17906   ""
17907 {
17908   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17909     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17910
17911   /* If .md ever supports :P for Pmode, this can be directly
17912      in the pattern above.  */
17913   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17914                               GEN_INT (GET_MODE_SIZE (GET_MODE
17915                                                       (operands[2]))));
17916   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17917     {
17918       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17919                                       operands[3]));
17920       DONE;
17921     }
17922 })
17923
17924 (define_expand "strset_singleop"
17925   [(parallel [(set (match_operand 1 "memory_operand" "")
17926                    (match_operand 2 "register_operand" ""))
17927               (set (match_operand 0 "register_operand" "")
17928                    (match_operand 3 "" ""))])]
17929   ""
17930   "ix86_current_function_needs_cld = 1;")
17931
17932 (define_insn "*strsetdi_rex_1"
17933   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17934         (match_operand:DI 2 "register_operand" "a"))
17935    (set (match_operand:DI 0 "register_operand" "=D")
17936         (plus:DI (match_dup 1)
17937                  (const_int 8)))]
17938   "TARGET_64BIT"
17939   "stosq"
17940   [(set_attr "type" "str")
17941    (set_attr "memory" "store")
17942    (set_attr "mode" "DI")])
17943
17944 (define_insn "*strsetsi_1"
17945   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17946         (match_operand:SI 2 "register_operand" "a"))
17947    (set (match_operand:SI 0 "register_operand" "=D")
17948         (plus:SI (match_dup 1)
17949                  (const_int 4)))]
17950   "!TARGET_64BIT"
17951   "stos{l|d}"
17952   [(set_attr "type" "str")
17953    (set_attr "memory" "store")
17954    (set_attr "mode" "SI")])
17955
17956 (define_insn "*strsetsi_rex_1"
17957   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17958         (match_operand:SI 2 "register_operand" "a"))
17959    (set (match_operand:DI 0 "register_operand" "=D")
17960         (plus:DI (match_dup 1)
17961                  (const_int 4)))]
17962   "TARGET_64BIT"
17963   "stos{l|d}"
17964   [(set_attr "type" "str")
17965    (set_attr "memory" "store")
17966    (set_attr "mode" "SI")])
17967
17968 (define_insn "*strsethi_1"
17969   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17970         (match_operand:HI 2 "register_operand" "a"))
17971    (set (match_operand:SI 0 "register_operand" "=D")
17972         (plus:SI (match_dup 1)
17973                  (const_int 2)))]
17974   "!TARGET_64BIT"
17975   "stosw"
17976   [(set_attr "type" "str")
17977    (set_attr "memory" "store")
17978    (set_attr "mode" "HI")])
17979
17980 (define_insn "*strsethi_rex_1"
17981   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17982         (match_operand:HI 2 "register_operand" "a"))
17983    (set (match_operand:DI 0 "register_operand" "=D")
17984         (plus:DI (match_dup 1)
17985                  (const_int 2)))]
17986   "TARGET_64BIT"
17987   "stosw"
17988   [(set_attr "type" "str")
17989    (set_attr "memory" "store")
17990    (set_attr "mode" "HI")])
17991
17992 (define_insn "*strsetqi_1"
17993   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17994         (match_operand:QI 2 "register_operand" "a"))
17995    (set (match_operand:SI 0 "register_operand" "=D")
17996         (plus:SI (match_dup 1)
17997                  (const_int 1)))]
17998   "!TARGET_64BIT"
17999   "stosb"
18000   [(set_attr "type" "str")
18001    (set_attr "memory" "store")
18002    (set_attr "mode" "QI")])
18003
18004 (define_insn "*strsetqi_rex_1"
18005   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18006         (match_operand:QI 2 "register_operand" "a"))
18007    (set (match_operand:DI 0 "register_operand" "=D")
18008         (plus:DI (match_dup 1)
18009                  (const_int 1)))]
18010   "TARGET_64BIT"
18011   "stosb"
18012   [(set_attr "type" "str")
18013    (set_attr "memory" "store")
18014    (set_attr "prefix_rex" "0")
18015    (set_attr "mode" "QI")])
18016
18017 (define_expand "rep_stos"
18018   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18019               (set (match_operand 0 "register_operand" "")
18020                    (match_operand 4 "" ""))
18021               (set (match_operand 2 "memory_operand" "") (const_int 0))
18022               (use (match_operand 3 "register_operand" ""))
18023               (use (match_dup 1))])]
18024   ""
18025   "ix86_current_function_needs_cld = 1;")
18026
18027 (define_insn "*rep_stosdi_rex64"
18028   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18029    (set (match_operand:DI 0 "register_operand" "=D")
18030         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18031                             (const_int 3))
18032                  (match_operand:DI 3 "register_operand" "0")))
18033    (set (mem:BLK (match_dup 3))
18034         (const_int 0))
18035    (use (match_operand:DI 2 "register_operand" "a"))
18036    (use (match_dup 4))]
18037   "TARGET_64BIT"
18038   "rep stosq"
18039   [(set_attr "type" "str")
18040    (set_attr "prefix_rep" "1")
18041    (set_attr "memory" "store")
18042    (set_attr "mode" "DI")])
18043
18044 (define_insn "*rep_stossi"
18045   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18046    (set (match_operand:SI 0 "register_operand" "=D")
18047         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18048                             (const_int 2))
18049                  (match_operand:SI 3 "register_operand" "0")))
18050    (set (mem:BLK (match_dup 3))
18051         (const_int 0))
18052    (use (match_operand:SI 2 "register_operand" "a"))
18053    (use (match_dup 4))]
18054   "!TARGET_64BIT"
18055   "rep stos{l|d}"
18056   [(set_attr "type" "str")
18057    (set_attr "prefix_rep" "1")
18058    (set_attr "memory" "store")
18059    (set_attr "mode" "SI")])
18060
18061 (define_insn "*rep_stossi_rex64"
18062   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18063    (set (match_operand:DI 0 "register_operand" "=D")
18064         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18065                             (const_int 2))
18066                  (match_operand:DI 3 "register_operand" "0")))
18067    (set (mem:BLK (match_dup 3))
18068         (const_int 0))
18069    (use (match_operand:SI 2 "register_operand" "a"))
18070    (use (match_dup 4))]
18071   "TARGET_64BIT"
18072   "rep stos{l|d}"
18073   [(set_attr "type" "str")
18074    (set_attr "prefix_rep" "1")
18075    (set_attr "memory" "store")
18076    (set_attr "mode" "SI")])
18077
18078 (define_insn "*rep_stosqi"
18079   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080    (set (match_operand:SI 0 "register_operand" "=D")
18081         (plus:SI (match_operand:SI 3 "register_operand" "0")
18082                  (match_operand:SI 4 "register_operand" "1")))
18083    (set (mem:BLK (match_dup 3))
18084         (const_int 0))
18085    (use (match_operand:QI 2 "register_operand" "a"))
18086    (use (match_dup 4))]
18087   "!TARGET_64BIT"
18088   "rep stosb"
18089   [(set_attr "type" "str")
18090    (set_attr "prefix_rep" "1")
18091    (set_attr "memory" "store")
18092    (set_attr "mode" "QI")])
18093
18094 (define_insn "*rep_stosqi_rex64"
18095   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18096    (set (match_operand:DI 0 "register_operand" "=D")
18097         (plus:DI (match_operand:DI 3 "register_operand" "0")
18098                  (match_operand:DI 4 "register_operand" "1")))
18099    (set (mem:BLK (match_dup 3))
18100         (const_int 0))
18101    (use (match_operand:QI 2 "register_operand" "a"))
18102    (use (match_dup 4))]
18103   "TARGET_64BIT"
18104   "rep stosb"
18105   [(set_attr "type" "str")
18106    (set_attr "prefix_rep" "1")
18107    (set_attr "memory" "store")
18108    (set_attr "prefix_rex" "0")
18109    (set_attr "mode" "QI")])
18110
18111 (define_expand "cmpstrnsi"
18112   [(set (match_operand:SI 0 "register_operand" "")
18113         (compare:SI (match_operand:BLK 1 "general_operand" "")
18114                     (match_operand:BLK 2 "general_operand" "")))
18115    (use (match_operand 3 "general_operand" ""))
18116    (use (match_operand 4 "immediate_operand" ""))]
18117   ""
18118 {
18119   rtx addr1, addr2, out, outlow, count, countreg, align;
18120
18121   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18122     FAIL;
18123
18124   /* Can't use this if the user has appropriated esi or edi.  */
18125   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18126     FAIL;
18127
18128   out = operands[0];
18129   if (!REG_P (out))
18130     out = gen_reg_rtx (SImode);
18131
18132   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18133   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18134   if (addr1 != XEXP (operands[1], 0))
18135     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18136   if (addr2 != XEXP (operands[2], 0))
18137     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18138
18139   count = operands[3];
18140   countreg = ix86_zero_extend_to_Pmode (count);
18141
18142   /* %%% Iff we are testing strict equality, we can use known alignment
18143      to good advantage.  This may be possible with combine, particularly
18144      once cc0 is dead.  */
18145   align = operands[4];
18146
18147   if (CONST_INT_P (count))
18148     {
18149       if (INTVAL (count) == 0)
18150         {
18151           emit_move_insn (operands[0], const0_rtx);
18152           DONE;
18153         }
18154       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18155                                      operands[1], operands[2]));
18156     }
18157   else
18158     {
18159       rtx (*cmp_insn)(rtx, rtx);
18160
18161       if (TARGET_64BIT)
18162         cmp_insn = gen_cmpdi_1;
18163       else
18164         cmp_insn = gen_cmpsi_1;
18165       emit_insn (cmp_insn (countreg, countreg));
18166       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18167                                   operands[1], operands[2]));
18168     }
18169
18170   outlow = gen_lowpart (QImode, out);
18171   emit_insn (gen_cmpintqi (outlow));
18172   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18173
18174   if (operands[0] != out)
18175     emit_move_insn (operands[0], out);
18176
18177   DONE;
18178 })
18179
18180 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18181
18182 (define_expand "cmpintqi"
18183   [(set (match_dup 1)
18184         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18185    (set (match_dup 2)
18186         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18187    (parallel [(set (match_operand:QI 0 "register_operand" "")
18188                    (minus:QI (match_dup 1)
18189                              (match_dup 2)))
18190               (clobber (reg:CC FLAGS_REG))])]
18191   ""
18192   "operands[1] = gen_reg_rtx (QImode);
18193    operands[2] = gen_reg_rtx (QImode);")
18194
18195 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18196 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18197
18198 (define_expand "cmpstrnqi_nz_1"
18199   [(parallel [(set (reg:CC FLAGS_REG)
18200                    (compare:CC (match_operand 4 "memory_operand" "")
18201                                (match_operand 5 "memory_operand" "")))
18202               (use (match_operand 2 "register_operand" ""))
18203               (use (match_operand:SI 3 "immediate_operand" ""))
18204               (clobber (match_operand 0 "register_operand" ""))
18205               (clobber (match_operand 1 "register_operand" ""))
18206               (clobber (match_dup 2))])]
18207   ""
18208   "ix86_current_function_needs_cld = 1;")
18209
18210 (define_insn "*cmpstrnqi_nz_1"
18211   [(set (reg:CC FLAGS_REG)
18212         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18213                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18214    (use (match_operand:SI 6 "register_operand" "2"))
18215    (use (match_operand:SI 3 "immediate_operand" "i"))
18216    (clobber (match_operand:SI 0 "register_operand" "=S"))
18217    (clobber (match_operand:SI 1 "register_operand" "=D"))
18218    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18219   "!TARGET_64BIT"
18220   "repz cmpsb"
18221   [(set_attr "type" "str")
18222    (set_attr "mode" "QI")
18223    (set_attr "prefix_rep" "1")])
18224
18225 (define_insn "*cmpstrnqi_nz_rex_1"
18226   [(set (reg:CC FLAGS_REG)
18227         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18228                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18229    (use (match_operand:DI 6 "register_operand" "2"))
18230    (use (match_operand:SI 3 "immediate_operand" "i"))
18231    (clobber (match_operand:DI 0 "register_operand" "=S"))
18232    (clobber (match_operand:DI 1 "register_operand" "=D"))
18233    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18234   "TARGET_64BIT"
18235   "repz cmpsb"
18236   [(set_attr "type" "str")
18237    (set_attr "mode" "QI")
18238    (set_attr "prefix_rex" "0")
18239    (set_attr "prefix_rep" "1")])
18240
18241 ;; The same, but the count is not known to not be zero.
18242
18243 (define_expand "cmpstrnqi_1"
18244   [(parallel [(set (reg:CC FLAGS_REG)
18245                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18246                                      (const_int 0))
18247                   (compare:CC (match_operand 4 "memory_operand" "")
18248                               (match_operand 5 "memory_operand" ""))
18249                   (const_int 0)))
18250               (use (match_operand:SI 3 "immediate_operand" ""))
18251               (use (reg:CC FLAGS_REG))
18252               (clobber (match_operand 0 "register_operand" ""))
18253               (clobber (match_operand 1 "register_operand" ""))
18254               (clobber (match_dup 2))])]
18255   ""
18256   "ix86_current_function_needs_cld = 1;")
18257
18258 (define_insn "*cmpstrnqi_1"
18259   [(set (reg:CC FLAGS_REG)
18260         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18261                              (const_int 0))
18262           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18263                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18264           (const_int 0)))
18265    (use (match_operand:SI 3 "immediate_operand" "i"))
18266    (use (reg:CC FLAGS_REG))
18267    (clobber (match_operand:SI 0 "register_operand" "=S"))
18268    (clobber (match_operand:SI 1 "register_operand" "=D"))
18269    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18270   "!TARGET_64BIT"
18271   "repz cmpsb"
18272   [(set_attr "type" "str")
18273    (set_attr "mode" "QI")
18274    (set_attr "prefix_rep" "1")])
18275
18276 (define_insn "*cmpstrnqi_rex_1"
18277   [(set (reg:CC FLAGS_REG)
18278         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18279                              (const_int 0))
18280           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18281                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18282           (const_int 0)))
18283    (use (match_operand:SI 3 "immediate_operand" "i"))
18284    (use (reg:CC FLAGS_REG))
18285    (clobber (match_operand:DI 0 "register_operand" "=S"))
18286    (clobber (match_operand:DI 1 "register_operand" "=D"))
18287    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18288   "TARGET_64BIT"
18289   "repz cmpsb"
18290   [(set_attr "type" "str")
18291    (set_attr "mode" "QI")
18292    (set_attr "prefix_rex" "0")
18293    (set_attr "prefix_rep" "1")])
18294
18295 (define_expand "strlensi"
18296   [(set (match_operand:SI 0 "register_operand" "")
18297         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18298                     (match_operand:QI 2 "immediate_operand" "")
18299                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18300   ""
18301 {
18302  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18303    DONE;
18304  else
18305    FAIL;
18306 })
18307
18308 (define_expand "strlendi"
18309   [(set (match_operand:DI 0 "register_operand" "")
18310         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18311                     (match_operand:QI 2 "immediate_operand" "")
18312                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18313   ""
18314 {
18315  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18316    DONE;
18317  else
18318    FAIL;
18319 })
18320
18321 (define_expand "strlenqi_1"
18322   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18323               (clobber (match_operand 1 "register_operand" ""))
18324               (clobber (reg:CC FLAGS_REG))])]
18325   ""
18326   "ix86_current_function_needs_cld = 1;")
18327
18328 (define_insn "*strlenqi_1"
18329   [(set (match_operand:SI 0 "register_operand" "=&c")
18330         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18331                     (match_operand:QI 2 "register_operand" "a")
18332                     (match_operand:SI 3 "immediate_operand" "i")
18333                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18334    (clobber (match_operand:SI 1 "register_operand" "=D"))
18335    (clobber (reg:CC FLAGS_REG))]
18336   "!TARGET_64BIT"
18337   "repnz scasb"
18338   [(set_attr "type" "str")
18339    (set_attr "mode" "QI")
18340    (set_attr "prefix_rep" "1")])
18341
18342 (define_insn "*strlenqi_rex_1"
18343   [(set (match_operand:DI 0 "register_operand" "=&c")
18344         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18345                     (match_operand:QI 2 "register_operand" "a")
18346                     (match_operand:DI 3 "immediate_operand" "i")
18347                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18348    (clobber (match_operand:DI 1 "register_operand" "=D"))
18349    (clobber (reg:CC FLAGS_REG))]
18350   "TARGET_64BIT"
18351   "repnz scasb"
18352   [(set_attr "type" "str")
18353    (set_attr "mode" "QI")
18354    (set_attr "prefix_rex" "0")
18355    (set_attr "prefix_rep" "1")])
18356
18357 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18358 ;; handled in combine, but it is not currently up to the task.
18359 ;; When used for their truth value, the cmpstrn* expanders generate
18360 ;; code like this:
18361 ;;
18362 ;;   repz cmpsb
18363 ;;   seta       %al
18364 ;;   setb       %dl
18365 ;;   cmpb       %al, %dl
18366 ;;   jcc        label
18367 ;;
18368 ;; The intermediate three instructions are unnecessary.
18369
18370 ;; This one handles cmpstrn*_nz_1...
18371 (define_peephole2
18372   [(parallel[
18373      (set (reg:CC FLAGS_REG)
18374           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18375                       (mem:BLK (match_operand 5 "register_operand" ""))))
18376      (use (match_operand 6 "register_operand" ""))
18377      (use (match_operand:SI 3 "immediate_operand" ""))
18378      (clobber (match_operand 0 "register_operand" ""))
18379      (clobber (match_operand 1 "register_operand" ""))
18380      (clobber (match_operand 2 "register_operand" ""))])
18381    (set (match_operand:QI 7 "register_operand" "")
18382         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18383    (set (match_operand:QI 8 "register_operand" "")
18384         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18385    (set (reg FLAGS_REG)
18386         (compare (match_dup 7) (match_dup 8)))
18387   ]
18388   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18389   [(parallel[
18390      (set (reg:CC FLAGS_REG)
18391           (compare:CC (mem:BLK (match_dup 4))
18392                       (mem:BLK (match_dup 5))))
18393      (use (match_dup 6))
18394      (use (match_dup 3))
18395      (clobber (match_dup 0))
18396      (clobber (match_dup 1))
18397      (clobber (match_dup 2))])]
18398   "")
18399
18400 ;; ...and this one handles cmpstrn*_1.
18401 (define_peephole2
18402   [(parallel[
18403      (set (reg:CC FLAGS_REG)
18404           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18405                                (const_int 0))
18406             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18407                         (mem:BLK (match_operand 5 "register_operand" "")))
18408             (const_int 0)))
18409      (use (match_operand:SI 3 "immediate_operand" ""))
18410      (use (reg:CC FLAGS_REG))
18411      (clobber (match_operand 0 "register_operand" ""))
18412      (clobber (match_operand 1 "register_operand" ""))
18413      (clobber (match_operand 2 "register_operand" ""))])
18414    (set (match_operand:QI 7 "register_operand" "")
18415         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18416    (set (match_operand:QI 8 "register_operand" "")
18417         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18418    (set (reg FLAGS_REG)
18419         (compare (match_dup 7) (match_dup 8)))
18420   ]
18421   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18422   [(parallel[
18423      (set (reg:CC FLAGS_REG)
18424           (if_then_else:CC (ne (match_dup 6)
18425                                (const_int 0))
18426             (compare:CC (mem:BLK (match_dup 4))
18427                         (mem:BLK (match_dup 5)))
18428             (const_int 0)))
18429      (use (match_dup 3))
18430      (use (reg:CC FLAGS_REG))
18431      (clobber (match_dup 0))
18432      (clobber (match_dup 1))
18433      (clobber (match_dup 2))])]
18434   "")
18435
18436
18437 \f
18438 ;; Conditional move instructions.
18439
18440 (define_expand "mov<mode>cc"
18441   [(set (match_operand:SWIM 0 "register_operand" "")
18442         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18443                            (match_operand:SWIM 2 "general_operand" "")
18444                            (match_operand:SWIM 3 "general_operand" "")))]
18445   ""
18446   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18447
18448 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18449 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18450 ;; So just document what we're doing explicitly.
18451
18452 (define_expand "x86_mov<mode>cc_0_m1"
18453   [(parallel
18454     [(set (match_operand:SWI48 0 "register_operand" "")
18455           (if_then_else:SWI48
18456             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18457              [(match_operand 1 "flags_reg_operand" "")
18458               (const_int 0)])
18459             (const_int -1)
18460             (const_int 0)))
18461      (clobber (reg:CC FLAGS_REG))])]
18462   ""
18463   "")
18464
18465 (define_insn "*x86_mov<mode>cc_0_m1"
18466   [(set (match_operand:SWI48 0 "register_operand" "=r")
18467         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18468                              [(reg FLAGS_REG) (const_int 0)])
18469           (const_int -1)
18470           (const_int 0)))
18471    (clobber (reg:CC FLAGS_REG))]
18472   ""
18473   "sbb{<imodesuffix>}\t%0, %0"
18474   ; Since we don't have the proper number of operands for an alu insn,
18475   ; fill in all the blanks.
18476   [(set_attr "type" "alu")
18477    (set_attr "use_carry" "1")
18478    (set_attr "pent_pair" "pu")
18479    (set_attr "memory" "none")
18480    (set_attr "imm_disp" "false")
18481    (set_attr "mode" "<MODE>")
18482    (set_attr "length_immediate" "0")])
18483
18484 (define_insn "*x86_mov<mode>cc_0_m1_se"
18485   [(set (match_operand:SWI48 0 "register_operand" "=r")
18486         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18487                              [(reg FLAGS_REG) (const_int 0)])
18488                             (const_int 1)
18489                             (const_int 0)))
18490    (clobber (reg:CC FLAGS_REG))]
18491   ""
18492   "sbb{<imodesuffix>}\t%0, %0"
18493   [(set_attr "type" "alu")
18494    (set_attr "use_carry" "1")
18495    (set_attr "pent_pair" "pu")
18496    (set_attr "memory" "none")
18497    (set_attr "imm_disp" "false")
18498    (set_attr "mode" "<MODE>")
18499    (set_attr "length_immediate" "0")])
18500
18501 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18502   [(set (match_operand:SWI48 0 "register_operand" "=r")
18503         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18504                     [(reg FLAGS_REG) (const_int 0)])))]
18505   ""
18506   "sbb{<imodesuffix>}\t%0, %0"
18507   [(set_attr "type" "alu")
18508    (set_attr "use_carry" "1")
18509    (set_attr "pent_pair" "pu")
18510    (set_attr "memory" "none")
18511    (set_attr "imm_disp" "false")
18512    (set_attr "mode" "<MODE>")
18513    (set_attr "length_immediate" "0")])
18514
18515 (define_insn "*mov<mode>cc_noc"
18516   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18517         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18518                                [(reg FLAGS_REG) (const_int 0)])
18519           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18520           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18521   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18522   "@
18523    cmov%O2%C1\t{%2, %0|%0, %2}
18524    cmov%O2%c1\t{%3, %0|%0, %3}"
18525   [(set_attr "type" "icmov")
18526    (set_attr "mode" "<MODE>")])
18527
18528 (define_insn_and_split "*movqicc_noc"
18529   [(set (match_operand:QI 0 "register_operand" "=r,r")
18530         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18531                            [(match_operand 4 "flags_reg_operand" "")
18532                             (const_int 0)])
18533                       (match_operand:QI 2 "register_operand" "r,0")
18534                       (match_operand:QI 3 "register_operand" "0,r")))]
18535   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18536   "#"
18537   "&& reload_completed"
18538   [(set (match_dup 0)
18539         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18540                       (match_dup 2)
18541                       (match_dup 3)))]
18542   "operands[0] = gen_lowpart (SImode, operands[0]);
18543    operands[2] = gen_lowpart (SImode, operands[2]);
18544    operands[3] = gen_lowpart (SImode, operands[3]);"
18545   [(set_attr "type" "icmov")
18546    (set_attr "mode" "SI")])
18547
18548 (define_expand "mov<mode>cc"
18549   [(set (match_operand:X87MODEF 0 "register_operand" "")
18550         (if_then_else:X87MODEF
18551           (match_operand 1 "ix86_fp_comparison_operator" "")
18552           (match_operand:X87MODEF 2 "register_operand" "")
18553           (match_operand:X87MODEF 3 "register_operand" "")))]
18554   "(TARGET_80387 && TARGET_CMOVE)
18555    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18556   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18557
18558 (define_insn "*movsfcc_1_387"
18559   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18560         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18561                                 [(reg FLAGS_REG) (const_int 0)])
18562                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18563                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18564   "TARGET_80387 && TARGET_CMOVE
18565    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18566   "@
18567    fcmov%F1\t{%2, %0|%0, %2}
18568    fcmov%f1\t{%3, %0|%0, %3}
18569    cmov%O2%C1\t{%2, %0|%0, %2}
18570    cmov%O2%c1\t{%3, %0|%0, %3}"
18571   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18572    (set_attr "mode" "SF,SF,SI,SI")])
18573
18574 (define_insn "*movdfcc_1"
18575   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18576         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18577                                 [(reg FLAGS_REG) (const_int 0)])
18578                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18579                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18580   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18581    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18582   "@
18583    fcmov%F1\t{%2, %0|%0, %2}
18584    fcmov%f1\t{%3, %0|%0, %3}
18585    #
18586    #"
18587   [(set_attr "type" "fcmov,fcmov,multi,multi")
18588    (set_attr "mode" "DF")])
18589
18590 (define_insn "*movdfcc_1_rex64"
18591   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18592         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18593                                 [(reg FLAGS_REG) (const_int 0)])
18594                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18595                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18596   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18597    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18598   "@
18599    fcmov%F1\t{%2, %0|%0, %2}
18600    fcmov%f1\t{%3, %0|%0, %3}
18601    cmov%O2%C1\t{%2, %0|%0, %2}
18602    cmov%O2%c1\t{%3, %0|%0, %3}"
18603   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18604    (set_attr "mode" "DF")])
18605
18606 (define_split
18607   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18608         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18609                                 [(match_operand 4 "flags_reg_operand" "")
18610                                  (const_int 0)])
18611                       (match_operand:DF 2 "nonimmediate_operand" "")
18612                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18613   "!TARGET_64BIT && reload_completed"
18614   [(set (match_dup 2)
18615         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18616                       (match_dup 5)
18617                       (match_dup 6)))
18618    (set (match_dup 3)
18619         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18620                       (match_dup 7)
18621                       (match_dup 8)))]
18622   "split_di (&operands[2], 2, &operands[5], &operands[7]);
18623    split_di (&operands[0], 1, &operands[2], &operands[3]);")
18624
18625 (define_insn "*movxfcc_1"
18626   [(set (match_operand:XF 0 "register_operand" "=f,f")
18627         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18628                                 [(reg FLAGS_REG) (const_int 0)])
18629                       (match_operand:XF 2 "register_operand" "f,0")
18630                       (match_operand:XF 3 "register_operand" "0,f")))]
18631   "TARGET_80387 && TARGET_CMOVE"
18632   "@
18633    fcmov%F1\t{%2, %0|%0, %2}
18634    fcmov%f1\t{%3, %0|%0, %3}"
18635   [(set_attr "type" "fcmov")
18636    (set_attr "mode" "XF")])
18637
18638 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18639 ;; the scalar versions to have only XMM registers as operands.
18640
18641 ;; XOP conditional move
18642 (define_insn "*xop_pcmov_<mode>"
18643   [(set (match_operand:MODEF 0 "register_operand" "=x")
18644         (if_then_else:MODEF
18645           (match_operand:MODEF 1 "register_operand" "x")
18646           (match_operand:MODEF 2 "register_operand" "x")
18647           (match_operand:MODEF 3 "register_operand" "x")))]
18648   "TARGET_XOP"
18649   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18650   [(set_attr "type" "sse4arg")])
18651
18652 ;; These versions of the min/max patterns are intentionally ignorant of
18653 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18654 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18655 ;; are undefined in this condition, we're certain this is correct.
18656
18657 (define_insn "*avx_<code><mode>3"
18658   [(set (match_operand:MODEF 0 "register_operand" "=x")
18659         (smaxmin:MODEF
18660           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18661           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18662   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18663   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18664   [(set_attr "type" "sseadd")
18665    (set_attr "prefix" "vex")
18666    (set_attr "mode" "<MODE>")])
18667
18668 (define_insn "<code><mode>3"
18669   [(set (match_operand:MODEF 0 "register_operand" "=x")
18670         (smaxmin:MODEF
18671           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18672           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18673   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18674   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18675   [(set_attr "type" "sseadd")
18676    (set_attr "mode" "<MODE>")])
18677
18678 ;; These versions of the min/max patterns implement exactly the operations
18679 ;;   min = (op1 < op2 ? op1 : op2)
18680 ;;   max = (!(op1 < op2) ? op1 : op2)
18681 ;; Their operands are not commutative, and thus they may be used in the
18682 ;; presence of -0.0 and NaN.
18683
18684 (define_insn "*avx_ieee_smin<mode>3"
18685   [(set (match_operand:MODEF 0 "register_operand" "=x")
18686         (unspec:MODEF
18687           [(match_operand:MODEF 1 "register_operand" "x")
18688            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18689          UNSPEC_IEEE_MIN))]
18690   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18691   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18692   [(set_attr "type" "sseadd")
18693    (set_attr "prefix" "vex")
18694    (set_attr "mode" "<MODE>")])
18695
18696 (define_insn "*ieee_smin<mode>3"
18697   [(set (match_operand:MODEF 0 "register_operand" "=x")
18698         (unspec:MODEF
18699           [(match_operand:MODEF 1 "register_operand" "0")
18700            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18701          UNSPEC_IEEE_MIN))]
18702   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18703   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18704   [(set_attr "type" "sseadd")
18705    (set_attr "mode" "<MODE>")])
18706
18707 (define_insn "*avx_ieee_smax<mode>3"
18708   [(set (match_operand:MODEF 0 "register_operand" "=x")
18709         (unspec:MODEF
18710           [(match_operand:MODEF 1 "register_operand" "0")
18711            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18712          UNSPEC_IEEE_MAX))]
18713   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18714   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18715   [(set_attr "type" "sseadd")
18716    (set_attr "prefix" "vex")
18717    (set_attr "mode" "<MODE>")])
18718
18719 (define_insn "*ieee_smax<mode>3"
18720   [(set (match_operand:MODEF 0 "register_operand" "=x")
18721         (unspec:MODEF
18722           [(match_operand:MODEF 1 "register_operand" "0")
18723            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18724          UNSPEC_IEEE_MAX))]
18725   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18726   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18727   [(set_attr "type" "sseadd")
18728    (set_attr "mode" "<MODE>")])
18729
18730 ;; Make two stack loads independent:
18731 ;;   fld aa              fld aa
18732 ;;   fld %st(0)     ->   fld bb
18733 ;;   fmul bb             fmul %st(1), %st
18734 ;;
18735 ;; Actually we only match the last two instructions for simplicity.
18736 (define_peephole2
18737   [(set (match_operand 0 "fp_register_operand" "")
18738         (match_operand 1 "fp_register_operand" ""))
18739    (set (match_dup 0)
18740         (match_operator 2 "binary_fp_operator"
18741            [(match_dup 0)
18742             (match_operand 3 "memory_operand" "")]))]
18743   "REGNO (operands[0]) != REGNO (operands[1])"
18744   [(set (match_dup 0) (match_dup 3))
18745    (set (match_dup 0) (match_dup 4))]
18746
18747   ;; The % modifier is not operational anymore in peephole2's, so we have to
18748   ;; swap the operands manually in the case of addition and multiplication.
18749   "if (COMMUTATIVE_ARITH_P (operands[2]))
18750      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18751                                  operands[0], operands[1]);
18752    else
18753      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18754                                  operands[1], operands[0]);")
18755
18756 ;; Conditional addition patterns
18757 (define_expand "add<mode>cc"
18758   [(match_operand:SWI 0 "register_operand" "")
18759    (match_operand 1 "comparison_operator" "")
18760    (match_operand:SWI 2 "register_operand" "")
18761    (match_operand:SWI 3 "const_int_operand" "")]
18762   ""
18763   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18764
18765 \f
18766 ;; Misc patterns (?)
18767
18768 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18769 ;; Otherwise there will be nothing to keep
18770 ;;
18771 ;; [(set (reg ebp) (reg esp))]
18772 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18773 ;;  (clobber (eflags)]
18774 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18775 ;;
18776 ;; in proper program order.
18777 (define_insn "pro_epilogue_adjust_stack_1"
18778   [(set (match_operand:SI 0 "register_operand" "=r,r")
18779         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18780                  (match_operand:SI 2 "immediate_operand" "i,i")))
18781    (clobber (reg:CC FLAGS_REG))
18782    (clobber (mem:BLK (scratch)))]
18783   "!TARGET_64BIT"
18784 {
18785   switch (get_attr_type (insn))
18786     {
18787     case TYPE_IMOV:
18788       return "mov{l}\t{%1, %0|%0, %1}";
18789
18790     case TYPE_ALU:
18791       if (CONST_INT_P (operands[2])
18792           && (INTVAL (operands[2]) == 128
18793               || (INTVAL (operands[2]) < 0
18794                   && INTVAL (operands[2]) != -128)))
18795         {
18796           operands[2] = GEN_INT (-INTVAL (operands[2]));
18797           return "sub{l}\t{%2, %0|%0, %2}";
18798         }
18799       return "add{l}\t{%2, %0|%0, %2}";
18800
18801     case TYPE_LEA:
18802       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18803       return "lea{l}\t{%a2, %0|%0, %a2}";
18804
18805     default:
18806       gcc_unreachable ();
18807     }
18808 }
18809   [(set (attr "type")
18810         (cond [(and (eq_attr "alternative" "0") 
18811                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18812                  (const_string "alu")
18813                (match_operand:SI 2 "const0_operand" "")
18814                  (const_string "imov")
18815               ]
18816               (const_string "lea")))
18817    (set (attr "length_immediate")
18818         (cond [(eq_attr "type" "imov")
18819                  (const_string "0")
18820                (and (eq_attr "type" "alu")
18821                     (match_operand 2 "const128_operand" ""))
18822                  (const_string "1")
18823               ]
18824               (const_string "*")))
18825    (set_attr "mode" "SI")])
18826
18827 (define_insn "pro_epilogue_adjust_stack_rex64"
18828   [(set (match_operand:DI 0 "register_operand" "=r,r")
18829         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18830                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18831    (clobber (reg:CC FLAGS_REG))
18832    (clobber (mem:BLK (scratch)))]
18833   "TARGET_64BIT"
18834 {
18835   switch (get_attr_type (insn))
18836     {
18837     case TYPE_IMOV:
18838       return "mov{q}\t{%1, %0|%0, %1}";
18839
18840     case TYPE_ALU:
18841       if (CONST_INT_P (operands[2])
18842           /* Avoid overflows.  */
18843           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18844           && (INTVAL (operands[2]) == 128
18845               || (INTVAL (operands[2]) < 0
18846                   && INTVAL (operands[2]) != -128)))
18847         {
18848           operands[2] = GEN_INT (-INTVAL (operands[2]));
18849           return "sub{q}\t{%2, %0|%0, %2}";
18850         }
18851       return "add{q}\t{%2, %0|%0, %2}";
18852
18853     case TYPE_LEA:
18854       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18855       return "lea{q}\t{%a2, %0|%0, %a2}";
18856
18857     default:
18858       gcc_unreachable ();
18859     }
18860 }
18861   [(set (attr "type")
18862         (cond [(and (eq_attr "alternative" "0")
18863                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18864                  (const_string "alu")
18865                (match_operand:DI 2 "const0_operand" "")
18866                  (const_string "imov")
18867               ]
18868               (const_string "lea")))
18869    (set (attr "length_immediate")
18870         (cond [(eq_attr "type" "imov")
18871                  (const_string "0")
18872                (and (eq_attr "type" "alu")
18873                     (match_operand 2 "const128_operand" ""))
18874                  (const_string "1")
18875               ]
18876               (const_string "*")))
18877    (set_attr "mode" "DI")])
18878
18879 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18880   [(set (match_operand:DI 0 "register_operand" "=r,r")
18881         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18882                  (match_operand:DI 3 "immediate_operand" "i,i")))
18883    (use (match_operand:DI 2 "register_operand" "r,r"))
18884    (clobber (reg:CC FLAGS_REG))
18885    (clobber (mem:BLK (scratch)))]
18886   "TARGET_64BIT"
18887 {
18888   switch (get_attr_type (insn))
18889     {
18890     case TYPE_ALU:
18891       return "add{q}\t{%2, %0|%0, %2}";
18892
18893     case TYPE_LEA:
18894       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18895       return "lea{q}\t{%a2, %0|%0, %a2}";
18896
18897     default:
18898       gcc_unreachable ();
18899     }
18900 }
18901   [(set_attr "type" "alu,lea")
18902    (set_attr "mode" "DI")])
18903
18904 (define_insn "allocate_stack_worker_32"
18905   [(set (match_operand:SI 0 "register_operand" "=a")
18906         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18907                             UNSPECV_STACK_PROBE))
18908    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18909    (clobber (reg:CC FLAGS_REG))]
18910   "!TARGET_64BIT && TARGET_STACK_PROBE"
18911   "call\t___chkstk"
18912   [(set_attr "type" "multi")
18913    (set_attr "length" "5")])
18914
18915 (define_insn "allocate_stack_worker_64"
18916   [(set (match_operand:DI 0 "register_operand" "=a")
18917         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18918                             UNSPECV_STACK_PROBE))
18919    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18920    (clobber (reg:DI R10_REG))
18921    (clobber (reg:DI R11_REG))
18922    (clobber (reg:CC FLAGS_REG))]
18923   "TARGET_64BIT && TARGET_STACK_PROBE"
18924   "call\t___chkstk"
18925   [(set_attr "type" "multi")
18926    (set_attr "length" "5")])
18927
18928 (define_expand "allocate_stack"
18929   [(match_operand 0 "register_operand" "")
18930    (match_operand 1 "general_operand" "")]
18931   "TARGET_STACK_PROBE"
18932 {
18933   rtx x;
18934
18935 #ifndef CHECK_STACK_LIMIT
18936 #define CHECK_STACK_LIMIT 0
18937 #endif
18938
18939   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18940       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18941     {
18942       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18943                                stack_pointer_rtx, 0, OPTAB_DIRECT);
18944       if (x != stack_pointer_rtx)
18945         emit_move_insn (stack_pointer_rtx, x);
18946     }
18947   else
18948     {
18949       x = copy_to_mode_reg (Pmode, operands[1]);
18950       if (TARGET_64BIT)
18951         x = gen_allocate_stack_worker_64 (x, x);
18952       else
18953         x = gen_allocate_stack_worker_32 (x, x);
18954       emit_insn (x);
18955     }
18956
18957   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18958   DONE;
18959 })
18960
18961 ;; Use IOR for stack probes, this is shorter.
18962 (define_expand "probe_stack"
18963   [(match_operand 0 "memory_operand" "")]
18964   ""
18965 {
18966   if (GET_MODE (operands[0]) == DImode)
18967     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18968   else
18969     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18970   DONE;
18971 })
18972
18973 (define_expand "builtin_setjmp_receiver"
18974   [(label_ref (match_operand 0 "" ""))]
18975   "!TARGET_64BIT && flag_pic"
18976 {
18977 #if TARGET_MACHO
18978   if (TARGET_MACHO)
18979     {
18980       rtx xops[3];
18981       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18982       rtx label_rtx = gen_label_rtx ();
18983       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18984       xops[0] = xops[1] = picreg;
18985       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18986       ix86_expand_binary_operator (MINUS, SImode, xops);
18987     }
18988   else
18989 #endif
18990     emit_insn (gen_set_got (pic_offset_table_rtx));
18991   DONE;
18992 })
18993 \f
18994 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18995
18996 (define_split
18997   [(set (match_operand 0 "register_operand" "")
18998         (match_operator 3 "promotable_binary_operator"
18999            [(match_operand 1 "register_operand" "")
19000             (match_operand 2 "aligned_operand" "")]))
19001    (clobber (reg:CC FLAGS_REG))]
19002   "! TARGET_PARTIAL_REG_STALL && reload_completed
19003    && ((GET_MODE (operands[0]) == HImode
19004         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19005             /* ??? next two lines just !satisfies_constraint_K (...) */
19006             || !CONST_INT_P (operands[2])
19007             || satisfies_constraint_K (operands[2])))
19008        || (GET_MODE (operands[0]) == QImode
19009            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19010   [(parallel [(set (match_dup 0)
19011                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19012               (clobber (reg:CC FLAGS_REG))])]
19013   "operands[0] = gen_lowpart (SImode, operands[0]);
19014    operands[1] = gen_lowpart (SImode, operands[1]);
19015    if (GET_CODE (operands[3]) != ASHIFT)
19016      operands[2] = gen_lowpart (SImode, operands[2]);
19017    PUT_MODE (operands[3], SImode);")
19018
19019 ; Promote the QImode tests, as i386 has encoding of the AND
19020 ; instruction with 32-bit sign-extended immediate and thus the
19021 ; instruction size is unchanged, except in the %eax case for
19022 ; which it is increased by one byte, hence the ! optimize_size.
19023 (define_split
19024   [(set (match_operand 0 "flags_reg_operand" "")
19025         (match_operator 2 "compare_operator"
19026           [(and (match_operand 3 "aligned_operand" "")
19027                 (match_operand 4 "const_int_operand" ""))
19028            (const_int 0)]))
19029    (set (match_operand 1 "register_operand" "")
19030         (and (match_dup 3) (match_dup 4)))]
19031   "! TARGET_PARTIAL_REG_STALL && reload_completed
19032    && optimize_insn_for_speed_p ()
19033    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19034        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19035    /* Ensure that the operand will remain sign-extended immediate.  */
19036    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19037   [(parallel [(set (match_dup 0)
19038                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19039                                     (const_int 0)]))
19040               (set (match_dup 1)
19041                    (and:SI (match_dup 3) (match_dup 4)))])]
19042 {
19043   operands[4]
19044     = gen_int_mode (INTVAL (operands[4])
19045                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19046   operands[1] = gen_lowpart (SImode, operands[1]);
19047   operands[3] = gen_lowpart (SImode, operands[3]);
19048 })
19049
19050 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19051 ; the TEST instruction with 32-bit sign-extended immediate and thus
19052 ; the instruction size would at least double, which is not what we
19053 ; want even with ! optimize_size.
19054 (define_split
19055   [(set (match_operand 0 "flags_reg_operand" "")
19056         (match_operator 1 "compare_operator"
19057           [(and (match_operand:HI 2 "aligned_operand" "")
19058                 (match_operand:HI 3 "const_int_operand" ""))
19059            (const_int 0)]))]
19060   "! TARGET_PARTIAL_REG_STALL && reload_completed
19061    && ! TARGET_FAST_PREFIX
19062    && optimize_insn_for_speed_p ()
19063    /* Ensure that the operand will remain sign-extended immediate.  */
19064    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19065   [(set (match_dup 0)
19066         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19067                          (const_int 0)]))]
19068 {
19069   operands[3]
19070     = gen_int_mode (INTVAL (operands[3])
19071                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19072   operands[2] = gen_lowpart (SImode, operands[2]);
19073 })
19074
19075 (define_split
19076   [(set (match_operand 0 "register_operand" "")
19077         (neg (match_operand 1 "register_operand" "")))
19078    (clobber (reg:CC FLAGS_REG))]
19079   "! TARGET_PARTIAL_REG_STALL && reload_completed
19080    && (GET_MODE (operands[0]) == HImode
19081        || (GET_MODE (operands[0]) == QImode
19082            && (TARGET_PROMOTE_QImode
19083                || optimize_insn_for_size_p ())))"
19084   [(parallel [(set (match_dup 0)
19085                    (neg:SI (match_dup 1)))
19086               (clobber (reg:CC FLAGS_REG))])]
19087   "operands[0] = gen_lowpart (SImode, operands[0]);
19088    operands[1] = gen_lowpart (SImode, operands[1]);")
19089
19090 (define_split
19091   [(set (match_operand 0 "register_operand" "")
19092         (not (match_operand 1 "register_operand" "")))]
19093   "! TARGET_PARTIAL_REG_STALL && reload_completed
19094    && (GET_MODE (operands[0]) == HImode
19095        || (GET_MODE (operands[0]) == QImode
19096            && (TARGET_PROMOTE_QImode
19097                || optimize_insn_for_size_p ())))"
19098   [(set (match_dup 0)
19099         (not:SI (match_dup 1)))]
19100   "operands[0] = gen_lowpart (SImode, operands[0]);
19101    operands[1] = gen_lowpart (SImode, operands[1]);")
19102
19103 (define_split
19104   [(set (match_operand 0 "register_operand" "")
19105         (if_then_else (match_operator 1 "comparison_operator"
19106                                 [(reg FLAGS_REG) (const_int 0)])
19107                       (match_operand 2 "register_operand" "")
19108                       (match_operand 3 "register_operand" "")))]
19109   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19110    && (GET_MODE (operands[0]) == HImode
19111        || (GET_MODE (operands[0]) == QImode
19112            && (TARGET_PROMOTE_QImode
19113                || optimize_insn_for_size_p ())))"
19114   [(set (match_dup 0)
19115         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19116   "operands[0] = gen_lowpart (SImode, operands[0]);
19117    operands[2] = gen_lowpart (SImode, operands[2]);
19118    operands[3] = gen_lowpart (SImode, operands[3]);")
19119
19120 \f
19121 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19122 ;; transform a complex memory operation into two memory to register operations.
19123
19124 ;; Don't push memory operands
19125 (define_peephole2
19126   [(set (match_operand:SI 0 "push_operand" "")
19127         (match_operand:SI 1 "memory_operand" ""))
19128    (match_scratch:SI 2 "r")]
19129   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19130    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19131   [(set (match_dup 2) (match_dup 1))
19132    (set (match_dup 0) (match_dup 2))]
19133   "")
19134
19135 (define_peephole2
19136   [(set (match_operand:DI 0 "push_operand" "")
19137         (match_operand:DI 1 "memory_operand" ""))
19138    (match_scratch:DI 2 "r")]
19139   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19140    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19141   [(set (match_dup 2) (match_dup 1))
19142    (set (match_dup 0) (match_dup 2))]
19143   "")
19144
19145 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19146 ;; SImode pushes.
19147 (define_peephole2
19148   [(set (match_operand:SF 0 "push_operand" "")
19149         (match_operand:SF 1 "memory_operand" ""))
19150    (match_scratch:SF 2 "r")]
19151   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19152    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19153   [(set (match_dup 2) (match_dup 1))
19154    (set (match_dup 0) (match_dup 2))]
19155   "")
19156
19157 (define_peephole2
19158   [(set (match_operand:HI 0 "push_operand" "")
19159         (match_operand:HI 1 "memory_operand" ""))
19160    (match_scratch:HI 2 "r")]
19161   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19162    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19163   [(set (match_dup 2) (match_dup 1))
19164    (set (match_dup 0) (match_dup 2))]
19165   "")
19166
19167 (define_peephole2
19168   [(set (match_operand:QI 0 "push_operand" "")
19169         (match_operand:QI 1 "memory_operand" ""))
19170    (match_scratch:QI 2 "q")]
19171   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19172    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19173   [(set (match_dup 2) (match_dup 1))
19174    (set (match_dup 0) (match_dup 2))]
19175   "")
19176
19177 ;; Don't move an immediate directly to memory when the instruction
19178 ;; gets too big.
19179 (define_peephole2
19180   [(match_scratch:SI 1 "r")
19181    (set (match_operand:SI 0 "memory_operand" "")
19182         (const_int 0))]
19183   "optimize_insn_for_speed_p ()
19184    && ! TARGET_USE_MOV0
19185    && TARGET_SPLIT_LONG_MOVES
19186    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19187    && peep2_regno_dead_p (0, FLAGS_REG)"
19188   [(parallel [(set (match_dup 1) (const_int 0))
19189               (clobber (reg:CC FLAGS_REG))])
19190    (set (match_dup 0) (match_dup 1))]
19191   "")
19192
19193 (define_peephole2
19194   [(match_scratch:HI 1 "r")
19195    (set (match_operand:HI 0 "memory_operand" "")
19196         (const_int 0))]
19197   "optimize_insn_for_speed_p ()
19198    && ! TARGET_USE_MOV0
19199    && TARGET_SPLIT_LONG_MOVES
19200    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19201    && peep2_regno_dead_p (0, FLAGS_REG)"
19202   [(parallel [(set (match_dup 2) (const_int 0))
19203               (clobber (reg:CC FLAGS_REG))])
19204    (set (match_dup 0) (match_dup 1))]
19205   "operands[2] = gen_lowpart (SImode, operands[1]);")
19206
19207 (define_peephole2
19208   [(match_scratch:QI 1 "q")
19209    (set (match_operand:QI 0 "memory_operand" "")
19210         (const_int 0))]
19211   "optimize_insn_for_speed_p ()
19212    && ! TARGET_USE_MOV0
19213    && TARGET_SPLIT_LONG_MOVES
19214    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19215    && peep2_regno_dead_p (0, FLAGS_REG)"
19216   [(parallel [(set (match_dup 2) (const_int 0))
19217               (clobber (reg:CC FLAGS_REG))])
19218    (set (match_dup 0) (match_dup 1))]
19219   "operands[2] = gen_lowpart (SImode, operands[1]);")
19220
19221 (define_peephole2
19222   [(match_scratch:SI 2 "r")
19223    (set (match_operand:SI 0 "memory_operand" "")
19224         (match_operand:SI 1 "immediate_operand" ""))]
19225   "optimize_insn_for_speed_p ()
19226    && TARGET_SPLIT_LONG_MOVES
19227    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19228   [(set (match_dup 2) (match_dup 1))
19229    (set (match_dup 0) (match_dup 2))]
19230   "")
19231
19232 (define_peephole2
19233   [(match_scratch:HI 2 "r")
19234    (set (match_operand:HI 0 "memory_operand" "")
19235         (match_operand:HI 1 "immediate_operand" ""))]
19236   "optimize_insn_for_speed_p ()
19237    && TARGET_SPLIT_LONG_MOVES
19238    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19239   [(set (match_dup 2) (match_dup 1))
19240    (set (match_dup 0) (match_dup 2))]
19241   "")
19242
19243 (define_peephole2
19244   [(match_scratch:QI 2 "q")
19245    (set (match_operand:QI 0 "memory_operand" "")
19246         (match_operand:QI 1 "immediate_operand" ""))]
19247   "optimize_insn_for_speed_p ()
19248    && TARGET_SPLIT_LONG_MOVES
19249    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19250   [(set (match_dup 2) (match_dup 1))
19251    (set (match_dup 0) (match_dup 2))]
19252   "")
19253
19254 ;; Don't compare memory with zero, load and use a test instead.
19255 (define_peephole2
19256   [(set (match_operand 0 "flags_reg_operand" "")
19257         (match_operator 1 "compare_operator"
19258           [(match_operand:SI 2 "memory_operand" "")
19259            (const_int 0)]))
19260    (match_scratch:SI 3 "r")]
19261   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19262   [(set (match_dup 3) (match_dup 2))
19263    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19264   "")
19265
19266 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19267 ;; Don't split NOTs with a displacement operand, because resulting XOR
19268 ;; will not be pairable anyway.
19269 ;;
19270 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19271 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19272 ;; so this split helps here as well.
19273 ;;
19274 ;; Note: Can't do this as a regular split because we can't get proper
19275 ;; lifetime information then.
19276
19277 (define_peephole2
19278   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19279         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19280   "optimize_insn_for_speed_p ()
19281    && ((TARGET_NOT_UNPAIRABLE
19282         && (!MEM_P (operands[0])
19283             || !memory_displacement_operand (operands[0], SImode)))
19284        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19285    && peep2_regno_dead_p (0, FLAGS_REG)"
19286   [(parallel [(set (match_dup 0)
19287                    (xor:SI (match_dup 1) (const_int -1)))
19288               (clobber (reg:CC FLAGS_REG))])]
19289   "")
19290
19291 (define_peephole2
19292   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19293         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19294   "optimize_insn_for_speed_p ()
19295    && ((TARGET_NOT_UNPAIRABLE
19296         && (!MEM_P (operands[0])
19297             || !memory_displacement_operand (operands[0], HImode)))
19298        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19299    && peep2_regno_dead_p (0, FLAGS_REG)"
19300   [(parallel [(set (match_dup 0)
19301                    (xor:HI (match_dup 1) (const_int -1)))
19302               (clobber (reg:CC FLAGS_REG))])]
19303   "")
19304
19305 (define_peephole2
19306   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19307         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19308   "optimize_insn_for_speed_p ()
19309    && ((TARGET_NOT_UNPAIRABLE
19310         && (!MEM_P (operands[0])
19311             || !memory_displacement_operand (operands[0], QImode)))
19312        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19313    && peep2_regno_dead_p (0, FLAGS_REG)"
19314   [(parallel [(set (match_dup 0)
19315                    (xor:QI (match_dup 1) (const_int -1)))
19316               (clobber (reg:CC FLAGS_REG))])]
19317   "")
19318
19319 ;; Non pairable "test imm, reg" instructions can be translated to
19320 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19321 ;; byte opcode instead of two, have a short form for byte operands),
19322 ;; so do it for other CPUs as well.  Given that the value was dead,
19323 ;; this should not create any new dependencies.  Pass on the sub-word
19324 ;; versions if we're concerned about partial register stalls.
19325
19326 (define_peephole2
19327   [(set (match_operand 0 "flags_reg_operand" "")
19328         (match_operator 1 "compare_operator"
19329           [(and:SI (match_operand:SI 2 "register_operand" "")
19330                    (match_operand:SI 3 "immediate_operand" ""))
19331            (const_int 0)]))]
19332   "ix86_match_ccmode (insn, CCNOmode)
19333    && (true_regnum (operands[2]) != AX_REG
19334        || satisfies_constraint_K (operands[3]))
19335    && peep2_reg_dead_p (1, operands[2])"
19336   [(parallel
19337      [(set (match_dup 0)
19338            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19339                             (const_int 0)]))
19340       (set (match_dup 2)
19341            (and:SI (match_dup 2) (match_dup 3)))])]
19342   "")
19343
19344 ;; We don't need to handle HImode case, because it will be promoted to SImode
19345 ;; on ! TARGET_PARTIAL_REG_STALL
19346
19347 (define_peephole2
19348   [(set (match_operand 0 "flags_reg_operand" "")
19349         (match_operator 1 "compare_operator"
19350           [(and:QI (match_operand:QI 2 "register_operand" "")
19351                    (match_operand:QI 3 "immediate_operand" ""))
19352            (const_int 0)]))]
19353   "! TARGET_PARTIAL_REG_STALL
19354    && ix86_match_ccmode (insn, CCNOmode)
19355    && true_regnum (operands[2]) != AX_REG
19356    && peep2_reg_dead_p (1, operands[2])"
19357   [(parallel
19358      [(set (match_dup 0)
19359            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19360                             (const_int 0)]))
19361       (set (match_dup 2)
19362            (and:QI (match_dup 2) (match_dup 3)))])]
19363   "")
19364
19365 (define_peephole2
19366   [(set (match_operand 0 "flags_reg_operand" "")
19367         (match_operator 1 "compare_operator"
19368           [(and:SI
19369              (zero_extract:SI
19370                (match_operand 2 "ext_register_operand" "")
19371                (const_int 8)
19372                (const_int 8))
19373              (match_operand 3 "const_int_operand" ""))
19374            (const_int 0)]))]
19375   "! TARGET_PARTIAL_REG_STALL
19376    && ix86_match_ccmode (insn, CCNOmode)
19377    && true_regnum (operands[2]) != AX_REG
19378    && peep2_reg_dead_p (1, operands[2])"
19379   [(parallel [(set (match_dup 0)
19380                    (match_op_dup 1
19381                      [(and:SI
19382                         (zero_extract:SI
19383                           (match_dup 2)
19384                           (const_int 8)
19385                           (const_int 8))
19386                         (match_dup 3))
19387                       (const_int 0)]))
19388               (set (zero_extract:SI (match_dup 2)
19389                                     (const_int 8)
19390                                     (const_int 8))
19391                    (and:SI
19392                      (zero_extract:SI
19393                        (match_dup 2)
19394                        (const_int 8)
19395                        (const_int 8))
19396                      (match_dup 3)))])]
19397   "")
19398
19399 ;; Don't do logical operations with memory inputs.
19400 (define_peephole2
19401   [(match_scratch:SI 2 "r")
19402    (parallel [(set (match_operand:SI 0 "register_operand" "")
19403                    (match_operator:SI 3 "arith_or_logical_operator"
19404                      [(match_dup 0)
19405                       (match_operand:SI 1 "memory_operand" "")]))
19406               (clobber (reg:CC FLAGS_REG))])]
19407   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19408   [(set (match_dup 2) (match_dup 1))
19409    (parallel [(set (match_dup 0)
19410                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19411               (clobber (reg:CC FLAGS_REG))])]
19412   "")
19413
19414 (define_peephole2
19415   [(match_scratch:SI 2 "r")
19416    (parallel [(set (match_operand:SI 0 "register_operand" "")
19417                    (match_operator:SI 3 "arith_or_logical_operator"
19418                      [(match_operand:SI 1 "memory_operand" "")
19419                       (match_dup 0)]))
19420               (clobber (reg:CC FLAGS_REG))])]
19421   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19422   [(set (match_dup 2) (match_dup 1))
19423    (parallel [(set (match_dup 0)
19424                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19425               (clobber (reg:CC FLAGS_REG))])]
19426   "")
19427
19428 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
19429 ;; refers to the destination of the load!
19430
19431 (define_peephole2
19432   [(set (match_operand:SI 0 "register_operand" "")
19433         (match_operand:SI 1 "register_operand" ""))
19434    (parallel [(set (match_dup 0)
19435                    (match_operator:SI 3 "commutative_operator"
19436                      [(match_dup 0)
19437                       (match_operand:SI 2 "memory_operand" "")]))
19438               (clobber (reg:CC FLAGS_REG))])]
19439   "REGNO (operands[0]) != REGNO (operands[1])
19440    && GENERAL_REGNO_P (REGNO (operands[0]))
19441    && GENERAL_REGNO_P (REGNO (operands[1]))"
19442   [(set (match_dup 0) (match_dup 4))
19443    (parallel [(set (match_dup 0)
19444                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19447
19448 (define_peephole2
19449   [(set (match_operand 0 "register_operand" "")
19450         (match_operand 1 "register_operand" ""))
19451    (set (match_dup 0)
19452                    (match_operator 3 "commutative_operator"
19453                      [(match_dup 0)
19454                       (match_operand 2 "memory_operand" "")]))]
19455   "REGNO (operands[0]) != REGNO (operands[1])
19456    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
19457        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19458   [(set (match_dup 0) (match_dup 2))
19459    (set (match_dup 0)
19460         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19461   "")
19462
19463 ; Don't do logical operations with memory outputs
19464 ;
19465 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19466 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19467 ; the same decoder scheduling characteristics as the original.
19468
19469 (define_peephole2
19470   [(match_scratch:SI 2 "r")
19471    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19472                    (match_operator:SI 3 "arith_or_logical_operator"
19473                      [(match_dup 0)
19474                       (match_operand:SI 1 "nonmemory_operand" "")]))
19475               (clobber (reg:CC FLAGS_REG))])]
19476   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19477    /* Do not split stack checking probes.  */
19478    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19479   [(set (match_dup 2) (match_dup 0))
19480    (parallel [(set (match_dup 2)
19481                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19482               (clobber (reg:CC FLAGS_REG))])
19483    (set (match_dup 0) (match_dup 2))]
19484   "")
19485
19486 (define_peephole2
19487   [(match_scratch:SI 2 "r")
19488    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19489                    (match_operator:SI 3 "arith_or_logical_operator"
19490                      [(match_operand:SI 1 "nonmemory_operand" "")
19491                       (match_dup 0)]))
19492               (clobber (reg:CC FLAGS_REG))])]
19493   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19494    /* Do not split stack checking probes.  */
19495    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19496   [(set (match_dup 2) (match_dup 0))
19497    (parallel [(set (match_dup 2)
19498                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19499               (clobber (reg:CC FLAGS_REG))])
19500    (set (match_dup 0) (match_dup 2))]
19501   "")
19502
19503 ;; Attempt to always use XOR for zeroing registers.
19504 (define_peephole2
19505   [(set (match_operand 0 "register_operand" "")
19506         (match_operand 1 "const0_operand" ""))]
19507   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19508    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19509    && GENERAL_REG_P (operands[0])
19510    && peep2_regno_dead_p (0, FLAGS_REG)"
19511   [(parallel [(set (match_dup 0) (const_int 0))
19512               (clobber (reg:CC FLAGS_REG))])]
19513 {
19514   operands[0] = gen_lowpart (word_mode, operands[0]);
19515 })
19516
19517 (define_peephole2
19518   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19519         (const_int 0))]
19520   "(GET_MODE (operands[0]) == QImode
19521     || GET_MODE (operands[0]) == HImode)
19522    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19523    && peep2_regno_dead_p (0, FLAGS_REG)"
19524   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19525               (clobber (reg:CC FLAGS_REG))])])
19526
19527 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19528 (define_peephole2
19529   [(set (match_operand 0 "register_operand" "")
19530         (const_int -1))]
19531   "(GET_MODE (operands[0]) == HImode
19532     || GET_MODE (operands[0]) == SImode
19533     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19534    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19535    && peep2_regno_dead_p (0, FLAGS_REG)"
19536   [(parallel [(set (match_dup 0) (const_int -1))
19537               (clobber (reg:CC FLAGS_REG))])]
19538   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19539                               operands[0]);")
19540
19541 ;; Attempt to convert simple leas to adds. These can be created by
19542 ;; move expanders.
19543 (define_peephole2
19544   [(set (match_operand:SI 0 "register_operand" "")
19545         (plus:SI (match_dup 0)
19546                  (match_operand:SI 1 "nonmemory_operand" "")))]
19547   "peep2_regno_dead_p (0, FLAGS_REG)"
19548   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19549               (clobber (reg:CC FLAGS_REG))])]
19550   "")
19551
19552 (define_peephole2
19553   [(set (match_operand:SI 0 "register_operand" "")
19554         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19555                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19556   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19557   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19558               (clobber (reg:CC FLAGS_REG))])]
19559   "operands[2] = gen_lowpart (SImode, operands[2]);")
19560
19561 (define_peephole2
19562   [(set (match_operand:DI 0 "register_operand" "")
19563         (plus:DI (match_dup 0)
19564                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19565   "peep2_regno_dead_p (0, FLAGS_REG)"
19566   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19567               (clobber (reg:CC FLAGS_REG))])]
19568   "")
19569
19570 (define_peephole2
19571   [(set (match_operand:SI 0 "register_operand" "")
19572         (mult:SI (match_dup 0)
19573                  (match_operand:SI 1 "const_int_operand" "")))]
19574   "exact_log2 (INTVAL (operands[1])) >= 0
19575    && peep2_regno_dead_p (0, FLAGS_REG)"
19576   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19577               (clobber (reg:CC FLAGS_REG))])]
19578   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19579
19580 (define_peephole2
19581   [(set (match_operand:DI 0 "register_operand" "")
19582         (mult:DI (match_dup 0)
19583                  (match_operand:DI 1 "const_int_operand" "")))]
19584   "exact_log2 (INTVAL (operands[1])) >= 0
19585    && peep2_regno_dead_p (0, FLAGS_REG)"
19586   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19587               (clobber (reg:CC FLAGS_REG))])]
19588   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19589
19590 (define_peephole2
19591   [(set (match_operand:SI 0 "register_operand" "")
19592         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19593                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19594   "exact_log2 (INTVAL (operands[2])) >= 0
19595    && REGNO (operands[0]) == REGNO (operands[1])
19596    && peep2_regno_dead_p (0, FLAGS_REG)"
19597   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19598               (clobber (reg:CC FLAGS_REG))])]
19599   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19600
19601 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19602 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19603 ;; many CPUs it is also faster, since special hardware to avoid esp
19604 ;; dependencies is present.
19605
19606 ;; While some of these conversions may be done using splitters, we use peepholes
19607 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19608
19609 ;; Convert prologue esp subtractions to push.
19610 ;; We need register to push.  In order to keep verify_flow_info happy we have
19611 ;; two choices
19612 ;; - use scratch and clobber it in order to avoid dependencies
19613 ;; - use already live register
19614 ;; We can't use the second way right now, since there is no reliable way how to
19615 ;; verify that given register is live.  First choice will also most likely in
19616 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19617 ;; call clobbered registers are dead.  We may want to use base pointer as an
19618 ;; alternative when no register is available later.
19619
19620 (define_peephole2
19621   [(match_scratch:SI 0 "r")
19622    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19623               (clobber (reg:CC FLAGS_REG))
19624               (clobber (mem:BLK (scratch)))])]
19625   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19626   [(clobber (match_dup 0))
19627    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19628               (clobber (mem:BLK (scratch)))])])
19629
19630 (define_peephole2
19631   [(match_scratch:SI 0 "r")
19632    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19633               (clobber (reg:CC FLAGS_REG))
19634               (clobber (mem:BLK (scratch)))])]
19635   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19636   [(clobber (match_dup 0))
19637    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19638    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19639               (clobber (mem:BLK (scratch)))])])
19640
19641 ;; Convert esp subtractions to push.
19642 (define_peephole2
19643   [(match_scratch:SI 0 "r")
19644    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19645               (clobber (reg:CC FLAGS_REG))])]
19646   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19647   [(clobber (match_dup 0))
19648    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19649
19650 (define_peephole2
19651   [(match_scratch:SI 0 "r")
19652    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19653               (clobber (reg:CC FLAGS_REG))])]
19654   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19655   [(clobber (match_dup 0))
19656    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19657    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19658
19659 ;; Convert epilogue deallocator to pop.
19660 (define_peephole2
19661   [(match_scratch:SI 0 "r")
19662    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19663               (clobber (reg:CC FLAGS_REG))
19664               (clobber (mem:BLK (scratch)))])]
19665   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19666   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19667               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19668               (clobber (mem:BLK (scratch)))])]
19669   "")
19670
19671 ;; Two pops case is tricky, since pop causes dependency on destination register.
19672 ;; We use two registers if available.
19673 (define_peephole2
19674   [(match_scratch:SI 0 "r")
19675    (match_scratch:SI 1 "r")
19676    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19677               (clobber (reg:CC FLAGS_REG))
19678               (clobber (mem:BLK (scratch)))])]
19679   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19680   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19681               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19682               (clobber (mem:BLK (scratch)))])
19683    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19684               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19685   "")
19686
19687 (define_peephole2
19688   [(match_scratch:SI 0 "r")
19689    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19690               (clobber (reg:CC FLAGS_REG))
19691               (clobber (mem:BLK (scratch)))])]
19692   "optimize_insn_for_size_p ()"
19693   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19694               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19695               (clobber (mem:BLK (scratch)))])
19696    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19697               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19698   "")
19699
19700 ;; Convert esp additions to pop.
19701 (define_peephole2
19702   [(match_scratch:SI 0 "r")
19703    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19704               (clobber (reg:CC FLAGS_REG))])]
19705   ""
19706   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19707               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19708   "")
19709
19710 ;; Two pops case is tricky, since pop causes dependency on destination register.
19711 ;; We use two registers if available.
19712 (define_peephole2
19713   [(match_scratch:SI 0 "r")
19714    (match_scratch:SI 1 "r")
19715    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19716               (clobber (reg:CC FLAGS_REG))])]
19717   ""
19718   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19719               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19720    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19721               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19722   "")
19723
19724 (define_peephole2
19725   [(match_scratch:SI 0 "r")
19726    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19727               (clobber (reg:CC FLAGS_REG))])]
19728   "optimize_insn_for_size_p ()"
19729   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19730               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19731    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19732               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19733   "")
19734 \f
19735 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19736 ;; required and register dies.  Similarly for 128 to -128.
19737 (define_peephole2
19738   [(set (match_operand 0 "flags_reg_operand" "")
19739         (match_operator 1 "compare_operator"
19740           [(match_operand 2 "register_operand" "")
19741            (match_operand 3 "const_int_operand" "")]))]
19742   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19743      && incdec_operand (operands[3], GET_MODE (operands[3])))
19744     || (!TARGET_FUSE_CMP_AND_BRANCH
19745         && INTVAL (operands[3]) == 128))
19746    && ix86_match_ccmode (insn, CCGCmode)
19747    && peep2_reg_dead_p (1, operands[2])"
19748   [(parallel [(set (match_dup 0)
19749                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19750               (clobber (match_dup 2))])]
19751   "")
19752 \f
19753 (define_peephole2
19754   [(match_scratch:DI 0 "r")
19755    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19756               (clobber (reg:CC FLAGS_REG))
19757               (clobber (mem:BLK (scratch)))])]
19758   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19759   [(clobber (match_dup 0))
19760    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19761               (clobber (mem:BLK (scratch)))])])
19762
19763 (define_peephole2
19764   [(match_scratch:DI 0 "r")
19765    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19766               (clobber (reg:CC FLAGS_REG))
19767               (clobber (mem:BLK (scratch)))])]
19768   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19769   [(clobber (match_dup 0))
19770    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19771    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19772               (clobber (mem:BLK (scratch)))])])
19773
19774 ;; Convert esp subtractions to push.
19775 (define_peephole2
19776   [(match_scratch:DI 0 "r")
19777    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19778               (clobber (reg:CC FLAGS_REG))])]
19779   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19780   [(clobber (match_dup 0))
19781    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19782
19783 (define_peephole2
19784   [(match_scratch:DI 0 "r")
19785    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19786               (clobber (reg:CC FLAGS_REG))])]
19787   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19788   [(clobber (match_dup 0))
19789    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19790    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19791
19792 ;; Convert epilogue deallocator to pop.
19793 (define_peephole2
19794   [(match_scratch:DI 0 "r")
19795    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19796               (clobber (reg:CC FLAGS_REG))
19797               (clobber (mem:BLK (scratch)))])]
19798   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19799   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19800               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19801               (clobber (mem:BLK (scratch)))])]
19802   "")
19803
19804 ;; Two pops case is tricky, since pop causes dependency on destination register.
19805 ;; We use two registers if available.
19806 (define_peephole2
19807   [(match_scratch:DI 0 "r")
19808    (match_scratch:DI 1 "r")
19809    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19810               (clobber (reg:CC FLAGS_REG))
19811               (clobber (mem:BLK (scratch)))])]
19812   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19813   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19814               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19815               (clobber (mem:BLK (scratch)))])
19816    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19817               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19818   "")
19819
19820 (define_peephole2
19821   [(match_scratch:DI 0 "r")
19822    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19823               (clobber (reg:CC FLAGS_REG))
19824               (clobber (mem:BLK (scratch)))])]
19825   "optimize_insn_for_size_p ()"
19826   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19827               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19828               (clobber (mem:BLK (scratch)))])
19829    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19830               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19831   "")
19832
19833 ;; Convert esp additions to pop.
19834 (define_peephole2
19835   [(match_scratch:DI 0 "r")
19836    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19837               (clobber (reg:CC FLAGS_REG))])]
19838   ""
19839   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19840               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19841   "")
19842
19843 ;; Two pops case is tricky, since pop causes dependency on destination register.
19844 ;; We use two registers if available.
19845 (define_peephole2
19846   [(match_scratch:DI 0 "r")
19847    (match_scratch:DI 1 "r")
19848    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19849               (clobber (reg:CC FLAGS_REG))])]
19850   ""
19851   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19852               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19853    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19854               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19855   "")
19856
19857 (define_peephole2
19858   [(match_scratch:DI 0 "r")
19859    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19860               (clobber (reg:CC FLAGS_REG))])]
19861   "optimize_insn_for_size_p ()"
19862   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19863               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19864    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19865               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19866   "")
19867 \f
19868 ;; Convert imul by three, five and nine into lea
19869 (define_peephole2
19870   [(parallel
19871     [(set (match_operand:SI 0 "register_operand" "")
19872           (mult:SI (match_operand:SI 1 "register_operand" "")
19873                    (match_operand:SI 2 "const_int_operand" "")))
19874      (clobber (reg:CC FLAGS_REG))])]
19875   "INTVAL (operands[2]) == 3
19876    || INTVAL (operands[2]) == 5
19877    || INTVAL (operands[2]) == 9"
19878   [(set (match_dup 0)
19879         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19880                  (match_dup 1)))]
19881   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19882
19883 (define_peephole2
19884   [(parallel
19885     [(set (match_operand:SI 0 "register_operand" "")
19886           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19887                    (match_operand:SI 2 "const_int_operand" "")))
19888      (clobber (reg:CC FLAGS_REG))])]
19889   "optimize_insn_for_speed_p ()
19890    && (INTVAL (operands[2]) == 3
19891        || INTVAL (operands[2]) == 5
19892        || INTVAL (operands[2]) == 9)"
19893   [(set (match_dup 0) (match_dup 1))
19894    (set (match_dup 0)
19895         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19896                  (match_dup 0)))]
19897   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19898
19899 (define_peephole2
19900   [(parallel
19901     [(set (match_operand:DI 0 "register_operand" "")
19902           (mult:DI (match_operand:DI 1 "register_operand" "")
19903                    (match_operand:DI 2 "const_int_operand" "")))
19904      (clobber (reg:CC FLAGS_REG))])]
19905   "TARGET_64BIT
19906    && (INTVAL (operands[2]) == 3
19907        || INTVAL (operands[2]) == 5
19908        || INTVAL (operands[2]) == 9)"
19909   [(set (match_dup 0)
19910         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19911                  (match_dup 1)))]
19912   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19913
19914 (define_peephole2
19915   [(parallel
19916     [(set (match_operand:DI 0 "register_operand" "")
19917           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19918                    (match_operand:DI 2 "const_int_operand" "")))
19919      (clobber (reg:CC FLAGS_REG))])]
19920   "TARGET_64BIT
19921    && optimize_insn_for_speed_p ()
19922    && (INTVAL (operands[2]) == 3
19923        || INTVAL (operands[2]) == 5
19924        || INTVAL (operands[2]) == 9)"
19925   [(set (match_dup 0) (match_dup 1))
19926    (set (match_dup 0)
19927         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19928                  (match_dup 0)))]
19929   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19930
19931 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19932 ;; imul $32bit_imm, reg, reg is direct decoded.
19933 (define_peephole2
19934   [(match_scratch:DI 3 "r")
19935    (parallel [(set (match_operand:DI 0 "register_operand" "")
19936                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19937                             (match_operand:DI 2 "immediate_operand" "")))
19938               (clobber (reg:CC FLAGS_REG))])]
19939   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19940    && !satisfies_constraint_K (operands[2])"
19941   [(set (match_dup 3) (match_dup 1))
19942    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19943               (clobber (reg:CC FLAGS_REG))])]
19944 "")
19945
19946 (define_peephole2
19947   [(match_scratch:SI 3 "r")
19948    (parallel [(set (match_operand:SI 0 "register_operand" "")
19949                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19950                             (match_operand:SI 2 "immediate_operand" "")))
19951               (clobber (reg:CC FLAGS_REG))])]
19952   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19953    && !satisfies_constraint_K (operands[2])"
19954   [(set (match_dup 3) (match_dup 1))
19955    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19956               (clobber (reg:CC FLAGS_REG))])]
19957 "")
19958
19959 (define_peephole2
19960   [(match_scratch:SI 3 "r")
19961    (parallel [(set (match_operand:DI 0 "register_operand" "")
19962                    (zero_extend:DI
19963                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19964                               (match_operand:SI 2 "immediate_operand" ""))))
19965               (clobber (reg:CC FLAGS_REG))])]
19966   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19967    && !satisfies_constraint_K (operands[2])"
19968   [(set (match_dup 3) (match_dup 1))
19969    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19970               (clobber (reg:CC FLAGS_REG))])]
19971 "")
19972
19973 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19974 ;; Convert it into imul reg, reg
19975 ;; It would be better to force assembler to encode instruction using long
19976 ;; immediate, but there is apparently no way to do so.
19977 (define_peephole2
19978   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19979                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19980                             (match_operand:DI 2 "const_int_operand" "")))
19981               (clobber (reg:CC FLAGS_REG))])
19982    (match_scratch:DI 3 "r")]
19983   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19984    && satisfies_constraint_K (operands[2])"
19985   [(set (match_dup 3) (match_dup 2))
19986    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19987               (clobber (reg:CC FLAGS_REG))])]
19988 {
19989   if (!rtx_equal_p (operands[0], operands[1]))
19990     emit_move_insn (operands[0], operands[1]);
19991 })
19992
19993 (define_peephole2
19994   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19995                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19996                             (match_operand:SI 2 "const_int_operand" "")))
19997               (clobber (reg:CC FLAGS_REG))])
19998    (match_scratch:SI 3 "r")]
19999   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20000    && satisfies_constraint_K (operands[2])"
20001   [(set (match_dup 3) (match_dup 2))
20002    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20003               (clobber (reg:CC FLAGS_REG))])]
20004 {
20005   if (!rtx_equal_p (operands[0], operands[1]))
20006     emit_move_insn (operands[0], operands[1]);
20007 })
20008
20009 (define_peephole2
20010   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20011                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20012                             (match_operand:HI 2 "immediate_operand" "")))
20013               (clobber (reg:CC FLAGS_REG))])
20014    (match_scratch:HI 3 "r")]
20015   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20016   [(set (match_dup 3) (match_dup 2))
20017    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20018               (clobber (reg:CC FLAGS_REG))])]
20019 {
20020   if (!rtx_equal_p (operands[0], operands[1]))
20021     emit_move_insn (operands[0], operands[1]);
20022 })
20023
20024 ;; After splitting up read-modify operations, array accesses with memory
20025 ;; operands might end up in form:
20026 ;;  sall    $2, %eax
20027 ;;  movl    4(%esp), %edx
20028 ;;  addl    %edx, %eax
20029 ;; instead of pre-splitting:
20030 ;;  sall    $2, %eax
20031 ;;  addl    4(%esp), %eax
20032 ;; Turn it into:
20033 ;;  movl    4(%esp), %edx
20034 ;;  leal    (%edx,%eax,4), %eax
20035
20036 (define_peephole2
20037   [(parallel [(set (match_operand 0 "register_operand" "")
20038                    (ashift (match_operand 1 "register_operand" "")
20039                            (match_operand 2 "const_int_operand" "")))
20040                (clobber (reg:CC FLAGS_REG))])
20041    (set (match_operand 3 "register_operand")
20042         (match_operand 4 "x86_64_general_operand" ""))
20043    (parallel [(set (match_operand 5 "register_operand" "")
20044                    (plus (match_operand 6 "register_operand" "")
20045                          (match_operand 7 "register_operand" "")))
20046                    (clobber (reg:CC FLAGS_REG))])]
20047   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20048    /* Validate MODE for lea.  */
20049    && ((!TARGET_PARTIAL_REG_STALL
20050         && (GET_MODE (operands[0]) == QImode
20051             || GET_MODE (operands[0]) == HImode))
20052        || GET_MODE (operands[0]) == SImode
20053        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20054    /* We reorder load and the shift.  */
20055    && !rtx_equal_p (operands[1], operands[3])
20056    && !reg_overlap_mentioned_p (operands[0], operands[4])
20057    /* Last PLUS must consist of operand 0 and 3.  */
20058    && !rtx_equal_p (operands[0], operands[3])
20059    && (rtx_equal_p (operands[3], operands[6])
20060        || rtx_equal_p (operands[3], operands[7]))
20061    && (rtx_equal_p (operands[0], operands[6])
20062        || rtx_equal_p (operands[0], operands[7]))
20063    /* The intermediate operand 0 must die or be same as output.  */
20064    && (rtx_equal_p (operands[0], operands[5])
20065        || peep2_reg_dead_p (3, operands[0]))"
20066   [(set (match_dup 3) (match_dup 4))
20067    (set (match_dup 0) (match_dup 1))]
20068 {
20069   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20070   int scale = 1 << INTVAL (operands[2]);
20071   rtx index = gen_lowpart (Pmode, operands[1]);
20072   rtx base = gen_lowpart (Pmode, operands[3]);
20073   rtx dest = gen_lowpart (mode, operands[5]);
20074
20075   operands[1] = gen_rtx_PLUS (Pmode, base,
20076                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20077   if (mode != Pmode)
20078     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20079   operands[0] = dest;
20080 })
20081 \f
20082 ;; Call-value patterns last so that the wildcard operand does not
20083 ;; disrupt insn-recog's switch tables.
20084
20085 (define_insn "*call_value_pop_0"
20086   [(set (match_operand 0 "" "")
20087         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20088               (match_operand:SI 2 "" "")))
20089    (set (reg:SI SP_REG)
20090         (plus:SI (reg:SI SP_REG)
20091                  (match_operand:SI 3 "immediate_operand" "")))]
20092   "!TARGET_64BIT"
20093 {
20094   if (SIBLING_CALL_P (insn))
20095     return "jmp\t%P1";
20096   else
20097     return "call\t%P1";
20098 }
20099   [(set_attr "type" "callv")])
20100
20101 (define_insn "*call_value_pop_1"
20102   [(set (match_operand 0 "" "")
20103         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20104               (match_operand:SI 2 "" "")))
20105    (set (reg:SI SP_REG)
20106         (plus:SI (reg:SI SP_REG)
20107                  (match_operand:SI 3 "immediate_operand" "i")))]
20108   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20109 {
20110   if (constant_call_address_operand (operands[1], Pmode))
20111     return "call\t%P1";
20112   return "call\t%A1";
20113 }
20114   [(set_attr "type" "callv")])
20115
20116 (define_insn "*sibcall_value_pop_1"
20117   [(set (match_operand 0 "" "")
20118         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20119               (match_operand:SI 2 "" "")))
20120    (set (reg:SI SP_REG)
20121         (plus:SI (reg:SI SP_REG)
20122                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20123   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20124   "@
20125    jmp\t%P1
20126    jmp\t%A1"
20127   [(set_attr "type" "callv")])
20128
20129 (define_insn "*call_value_0"
20130   [(set (match_operand 0 "" "")
20131         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20132               (match_operand:SI 2 "" "")))]
20133   "!TARGET_64BIT"
20134 {
20135   if (SIBLING_CALL_P (insn))
20136     return "jmp\t%P1";
20137   else
20138     return "call\t%P1";
20139 }
20140   [(set_attr "type" "callv")])
20141
20142 (define_insn "*call_value_0_rex64"
20143   [(set (match_operand 0 "" "")
20144         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20145               (match_operand:DI 2 "const_int_operand" "")))]
20146   "TARGET_64BIT"
20147 {
20148   if (SIBLING_CALL_P (insn))
20149     return "jmp\t%P1";
20150   else
20151     return "call\t%P1";
20152 }
20153   [(set_attr "type" "callv")])
20154
20155 (define_insn "*call_value_0_rex64_ms_sysv"
20156   [(set (match_operand 0 "" "")
20157         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20158               (match_operand:DI 2 "const_int_operand" "")))
20159    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20160    (clobber (reg:TI XMM6_REG))
20161    (clobber (reg:TI XMM7_REG))
20162    (clobber (reg:TI XMM8_REG))
20163    (clobber (reg:TI XMM9_REG))
20164    (clobber (reg:TI XMM10_REG))
20165    (clobber (reg:TI XMM11_REG))
20166    (clobber (reg:TI XMM12_REG))
20167    (clobber (reg:TI XMM13_REG))
20168    (clobber (reg:TI XMM14_REG))
20169    (clobber (reg:TI XMM15_REG))
20170    (clobber (reg:DI SI_REG))
20171    (clobber (reg:DI DI_REG))]
20172   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20173 {
20174   if (SIBLING_CALL_P (insn))
20175     return "jmp\t%P1";
20176   else
20177     return "call\t%P1";
20178 }
20179   [(set_attr "type" "callv")])
20180
20181 (define_insn "*call_value_1"
20182   [(set (match_operand 0 "" "")
20183         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20184               (match_operand:SI 2 "" "")))]
20185   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20186 {
20187   if (constant_call_address_operand (operands[1], Pmode))
20188     return "call\t%P1";
20189   return "call\t%A1";
20190 }
20191   [(set_attr "type" "callv")])
20192
20193 (define_insn "*sibcall_value_1"
20194   [(set (match_operand 0 "" "")
20195         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20196               (match_operand:SI 2 "" "")))]
20197   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20198   "@
20199    jmp\t%P1
20200    jmp\t%A1"
20201   [(set_attr "type" "callv")])
20202
20203 (define_insn "*call_value_1_rex64"
20204   [(set (match_operand 0 "" "")
20205         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20206               (match_operand:DI 2 "" "")))]
20207   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20208    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20209 {
20210   if (constant_call_address_operand (operands[1], Pmode))
20211     return "call\t%P1";
20212   return "call\t%A1";
20213 }
20214   [(set_attr "type" "callv")])
20215
20216 (define_insn "*call_value_1_rex64_ms_sysv"
20217   [(set (match_operand 0 "" "")
20218         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20219               (match_operand:DI 2 "" "")))
20220    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20221    (clobber (reg:TI XMM6_REG))
20222    (clobber (reg:TI XMM7_REG))
20223    (clobber (reg:TI XMM8_REG))
20224    (clobber (reg:TI XMM9_REG))
20225    (clobber (reg:TI XMM10_REG))
20226    (clobber (reg:TI XMM11_REG))
20227    (clobber (reg:TI XMM12_REG))
20228    (clobber (reg:TI XMM13_REG))
20229    (clobber (reg:TI XMM14_REG))
20230    (clobber (reg:TI XMM15_REG))
20231    (clobber (reg:DI SI_REG))
20232    (clobber (reg:DI DI_REG))]
20233   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20234 {
20235   if (constant_call_address_operand (operands[1], Pmode))
20236     return "call\t%P1";
20237   return "call\t%A1";
20238 }
20239   [(set_attr "type" "callv")])
20240
20241 (define_insn "*call_value_1_rex64_large"
20242   [(set (match_operand 0 "" "")
20243         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20244               (match_operand:DI 2 "" "")))]
20245   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20246   "call\t%A1"
20247   [(set_attr "type" "callv")])
20248
20249 (define_insn "*sibcall_value_1_rex64"
20250   [(set (match_operand 0 "" "")
20251         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20252               (match_operand:DI 2 "" "")))]
20253   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20254   "@
20255    jmp\t%P1
20256    jmp\t%A1"
20257   [(set_attr "type" "callv")])
20258 \f
20259 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20260 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20261 ;; caught for use by garbage collectors and the like.  Using an insn that
20262 ;; maps to SIGILL makes it more likely the program will rightfully die.
20263 ;; Keeping with tradition, "6" is in honor of #UD.
20264 (define_insn "trap"
20265   [(trap_if (const_int 1) (const_int 6))]
20266   ""
20267   { return ASM_SHORT "0x0b0f"; }
20268   [(set_attr "length" "2")])
20269
20270 (define_expand "sse_prologue_save"
20271   [(parallel [(set (match_operand:BLK 0 "" "")
20272                    (unspec:BLK [(reg:DI XMM0_REG)
20273                                 (reg:DI XMM1_REG)
20274                                 (reg:DI XMM2_REG)
20275                                 (reg:DI XMM3_REG)
20276                                 (reg:DI XMM4_REG)
20277                                 (reg:DI XMM5_REG)
20278                                 (reg:DI XMM6_REG)
20279                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20280               (use (match_operand:DI 1 "register_operand" ""))
20281               (use (match_operand:DI 2 "immediate_operand" ""))
20282               (use (label_ref:DI (match_operand 3 "" "")))])]
20283   "TARGET_64BIT"
20284   "")
20285
20286 (define_insn "*sse_prologue_save_insn"
20287   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20288                           (match_operand:DI 4 "const_int_operand" "n")))
20289         (unspec:BLK [(reg:DI XMM0_REG)
20290                      (reg:DI XMM1_REG)
20291                      (reg:DI XMM2_REG)
20292                      (reg:DI XMM3_REG)
20293                      (reg:DI XMM4_REG)
20294                      (reg:DI XMM5_REG)
20295                      (reg:DI XMM6_REG)
20296                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20297    (use (match_operand:DI 1 "register_operand" "r"))
20298    (use (match_operand:DI 2 "const_int_operand" "i"))
20299    (use (label_ref:DI (match_operand 3 "" "X")))]
20300   "TARGET_64BIT
20301    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20302    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20303 {
20304   int i;
20305   operands[0] = gen_rtx_MEM (Pmode,
20306                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20307   /* VEX instruction with a REX prefix will #UD.  */
20308   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20309     gcc_unreachable ();
20310
20311   output_asm_insn ("jmp\t%A1", operands);
20312   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20313     {
20314       operands[4] = adjust_address (operands[0], DImode, i*16);
20315       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20316       PUT_MODE (operands[4], TImode);
20317       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20318         output_asm_insn ("rex", operands);
20319       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20320     }
20321   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20322                                      CODE_LABEL_NUMBER (operands[3]));
20323   return "";
20324 }
20325   [(set_attr "type" "other")
20326    (set_attr "length_immediate" "0")
20327    (set_attr "length_address" "0")
20328    (set (attr "length")
20329      (if_then_else
20330        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20331        (const_string "34")
20332        (const_string "42")))
20333    (set_attr "memory" "store")
20334    (set_attr "modrm" "0")
20335    (set_attr "prefix" "maybe_vex")
20336    (set_attr "mode" "DI")])
20337
20338 (define_expand "prefetch"
20339   [(prefetch (match_operand 0 "address_operand" "")
20340              (match_operand:SI 1 "const_int_operand" "")
20341              (match_operand:SI 2 "const_int_operand" ""))]
20342   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20343 {
20344   int rw = INTVAL (operands[1]);
20345   int locality = INTVAL (operands[2]);
20346
20347   gcc_assert (rw == 0 || rw == 1);
20348   gcc_assert (locality >= 0 && locality <= 3);
20349   gcc_assert (GET_MODE (operands[0]) == Pmode
20350               || GET_MODE (operands[0]) == VOIDmode);
20351
20352   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20353      supported by SSE counterpart or the SSE prefetch is not available
20354      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20355      of locality.  */
20356   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20357     operands[2] = GEN_INT (3);
20358   else
20359     operands[1] = const0_rtx;
20360 })
20361
20362 (define_insn "*prefetch_sse"
20363   [(prefetch (match_operand:SI 0 "address_operand" "p")
20364              (const_int 0)
20365              (match_operand:SI 1 "const_int_operand" ""))]
20366   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20367 {
20368   static const char * const patterns[4] = {
20369    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20370   };
20371
20372   int locality = INTVAL (operands[1]);
20373   gcc_assert (locality >= 0 && locality <= 3);
20374
20375   return patterns[locality];
20376 }
20377   [(set_attr "type" "sse")
20378    (set_attr "atom_sse_attr" "prefetch")
20379    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20380    (set_attr "memory" "none")])
20381
20382 (define_insn "*prefetch_sse_rex"
20383   [(prefetch (match_operand:DI 0 "address_operand" "p")
20384              (const_int 0)
20385              (match_operand:SI 1 "const_int_operand" ""))]
20386   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20387 {
20388   static const char * const patterns[4] = {
20389    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20390   };
20391
20392   int locality = INTVAL (operands[1]);
20393   gcc_assert (locality >= 0 && locality <= 3);
20394
20395   return patterns[locality];
20396 }
20397   [(set_attr "type" "sse")
20398    (set_attr "atom_sse_attr" "prefetch")
20399    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20400    (set_attr "memory" "none")])
20401
20402 (define_insn "*prefetch_3dnow"
20403   [(prefetch (match_operand:SI 0 "address_operand" "p")
20404              (match_operand:SI 1 "const_int_operand" "n")
20405              (const_int 3))]
20406   "TARGET_3DNOW && !TARGET_64BIT"
20407 {
20408   if (INTVAL (operands[1]) == 0)
20409     return "prefetch\t%a0";
20410   else
20411     return "prefetchw\t%a0";
20412 }
20413   [(set_attr "type" "mmx")
20414    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20415    (set_attr "memory" "none")])
20416
20417 (define_insn "*prefetch_3dnow_rex"
20418   [(prefetch (match_operand:DI 0 "address_operand" "p")
20419              (match_operand:SI 1 "const_int_operand" "n")
20420              (const_int 3))]
20421   "TARGET_3DNOW && TARGET_64BIT"
20422 {
20423   if (INTVAL (operands[1]) == 0)
20424     return "prefetch\t%a0";
20425   else
20426     return "prefetchw\t%a0";
20427 }
20428   [(set_attr "type" "mmx")
20429    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20430    (set_attr "memory" "none")])
20431
20432 (define_expand "stack_protect_set"
20433   [(match_operand 0 "memory_operand" "")
20434    (match_operand 1 "memory_operand" "")]
20435   ""
20436 {
20437 #ifdef TARGET_THREAD_SSP_OFFSET
20438   if (TARGET_64BIT)
20439     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20440                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20441   else
20442     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20443                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20444 #else
20445   if (TARGET_64BIT)
20446     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20447   else
20448     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20449 #endif
20450   DONE;
20451 })
20452
20453 (define_insn "stack_protect_set_si"
20454   [(set (match_operand:SI 0 "memory_operand" "=m")
20455         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20456    (set (match_scratch:SI 2 "=&r") (const_int 0))
20457    (clobber (reg:CC FLAGS_REG))]
20458   ""
20459   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20460   [(set_attr "type" "multi")])
20461
20462 (define_insn "stack_protect_set_di"
20463   [(set (match_operand:DI 0 "memory_operand" "=m")
20464         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20465    (set (match_scratch:DI 2 "=&r") (const_int 0))
20466    (clobber (reg:CC FLAGS_REG))]
20467   "TARGET_64BIT"
20468   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20469   [(set_attr "type" "multi")])
20470
20471 (define_insn "stack_tls_protect_set_si"
20472   [(set (match_operand:SI 0 "memory_operand" "=m")
20473         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20474    (set (match_scratch:SI 2 "=&r") (const_int 0))
20475    (clobber (reg:CC FLAGS_REG))]
20476   ""
20477   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20478   [(set_attr "type" "multi")])
20479
20480 (define_insn "stack_tls_protect_set_di"
20481   [(set (match_operand:DI 0 "memory_operand" "=m")
20482         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20483    (set (match_scratch:DI 2 "=&r") (const_int 0))
20484    (clobber (reg:CC FLAGS_REG))]
20485   "TARGET_64BIT"
20486   {
20487      /* The kernel uses a different segment register for performance reasons; a
20488         system call would not have to trash the userspace segment register,
20489         which would be expensive */
20490      if (ix86_cmodel != CM_KERNEL)
20491         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20492      else
20493         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20494   }
20495   [(set_attr "type" "multi")])
20496
20497 (define_expand "stack_protect_test"
20498   [(match_operand 0 "memory_operand" "")
20499    (match_operand 1 "memory_operand" "")
20500    (match_operand 2 "" "")]
20501   ""
20502 {
20503   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20504
20505 #ifdef TARGET_THREAD_SSP_OFFSET
20506   if (TARGET_64BIT)
20507     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20508                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20509   else
20510     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20511                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20512 #else
20513   if (TARGET_64BIT)
20514     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20515   else
20516     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20517 #endif
20518
20519   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20520                                   flags, const0_rtx, operands[2]));
20521   DONE;
20522 })
20523
20524 (define_insn "stack_protect_test_si"
20525   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20526         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20527                      (match_operand:SI 2 "memory_operand" "m")]
20528                     UNSPEC_SP_TEST))
20529    (clobber (match_scratch:SI 3 "=&r"))]
20530   ""
20531   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20532   [(set_attr "type" "multi")])
20533
20534 (define_insn "stack_protect_test_di"
20535   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20536         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20537                      (match_operand:DI 2 "memory_operand" "m")]
20538                     UNSPEC_SP_TEST))
20539    (clobber (match_scratch:DI 3 "=&r"))]
20540   "TARGET_64BIT"
20541   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20542   [(set_attr "type" "multi")])
20543
20544 (define_insn "stack_tls_protect_test_si"
20545   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20546         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20547                      (match_operand:SI 2 "const_int_operand" "i")]
20548                     UNSPEC_SP_TLS_TEST))
20549    (clobber (match_scratch:SI 3 "=r"))]
20550   ""
20551   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20552   [(set_attr "type" "multi")])
20553
20554 (define_insn "stack_tls_protect_test_di"
20555   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20556         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20557                      (match_operand:DI 2 "const_int_operand" "i")]
20558                     UNSPEC_SP_TLS_TEST))
20559    (clobber (match_scratch:DI 3 "=r"))]
20560   "TARGET_64BIT"
20561   {
20562      /* The kernel uses a different segment register for performance reasons; a
20563         system call would not have to trash the userspace segment register,
20564         which would be expensive */
20565      if (ix86_cmodel != CM_KERNEL)
20566         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20567      else
20568         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20569   }
20570   [(set_attr "type" "multi")])
20571
20572 (define_insn "sse4_2_crc32<mode>"
20573   [(set (match_operand:SI 0 "register_operand" "=r")
20574         (unspec:SI
20575           [(match_operand:SI 1 "register_operand" "0")
20576            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20577           UNSPEC_CRC32))]
20578   "TARGET_SSE4_2 || TARGET_CRC32"
20579   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20580   [(set_attr "type" "sselog1")
20581    (set_attr "prefix_rep" "1")
20582    (set_attr "prefix_extra" "1")
20583    (set (attr "prefix_data16")
20584      (if_then_else (match_operand:HI 2 "" "")
20585        (const_string "1")
20586        (const_string "*")))
20587    (set (attr "prefix_rex")
20588      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20589        (const_string "1")
20590        (const_string "*")))
20591    (set_attr "mode" "SI")])
20592
20593 (define_insn "sse4_2_crc32di"
20594   [(set (match_operand:DI 0 "register_operand" "=r")
20595         (unspec:DI
20596           [(match_operand:DI 1 "register_operand" "0")
20597            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20598           UNSPEC_CRC32))]
20599   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20600   "crc32{q}\t{%2, %0|%0, %2}"
20601   [(set_attr "type" "sselog1")
20602    (set_attr "prefix_rep" "1")
20603    (set_attr "prefix_extra" "1")
20604    (set_attr "mode" "DI")])
20605
20606 (define_expand "rdpmc"
20607   [(match_operand:DI 0 "register_operand" "")
20608    (match_operand:SI 1 "register_operand" "")]
20609   ""
20610 {
20611   rtx reg = gen_reg_rtx (DImode);
20612   rtx si;
20613
20614   /* Force operand 1 into ECX.  */
20615   rtx ecx = gen_rtx_REG (SImode, CX_REG);
20616   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20617   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20618                                 UNSPECV_RDPMC);
20619
20620   if (TARGET_64BIT)
20621     {
20622       rtvec vec = rtvec_alloc (2);
20623       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20624       rtx upper = gen_reg_rtx (DImode);
20625       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20626                                         gen_rtvec (1, const0_rtx),
20627                                         UNSPECV_RDPMC);
20628       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20629       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20630       emit_insn (load);
20631       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20632                                    NULL, 1, OPTAB_DIRECT);
20633       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20634                                  OPTAB_DIRECT);
20635     }
20636   else
20637     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20638   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20639   DONE;
20640 })
20641
20642 (define_insn "*rdpmc"
20643   [(set (match_operand:DI 0 "register_operand" "=A")
20644         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20645                             UNSPECV_RDPMC))]
20646   "!TARGET_64BIT"
20647   "rdpmc"
20648   [(set_attr "type" "other")
20649    (set_attr "length" "2")])
20650
20651 (define_insn "*rdpmc_rex64"
20652   [(set (match_operand:DI 0 "register_operand" "=a")
20653         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20654                             UNSPECV_RDPMC))
20655   (set (match_operand:DI 1 "register_operand" "=d")
20656        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20657   "TARGET_64BIT"
20658   "rdpmc"
20659   [(set_attr "type" "other")
20660    (set_attr "length" "2")])
20661
20662 (define_expand "rdtsc"
20663   [(set (match_operand:DI 0 "register_operand" "")
20664         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20665   ""
20666 {
20667   if (TARGET_64BIT)
20668     {
20669       rtvec vec = rtvec_alloc (2);
20670       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20671       rtx upper = gen_reg_rtx (DImode);
20672       rtx lower = gen_reg_rtx (DImode);
20673       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20674                                          gen_rtvec (1, const0_rtx),
20675                                          UNSPECV_RDTSC);
20676       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20677       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20678       emit_insn (load);
20679       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20680                                    NULL, 1, OPTAB_DIRECT);
20681       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20682                                    OPTAB_DIRECT);
20683       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20684       DONE;
20685     }
20686 })
20687
20688 (define_insn "*rdtsc"
20689   [(set (match_operand:DI 0 "register_operand" "=A")
20690         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20691   "!TARGET_64BIT"
20692   "rdtsc"
20693   [(set_attr "type" "other")
20694    (set_attr "length" "2")])
20695
20696 (define_insn "*rdtsc_rex64"
20697   [(set (match_operand:DI 0 "register_operand" "=a")
20698         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20699    (set (match_operand:DI 1 "register_operand" "=d")
20700         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20701   "TARGET_64BIT"
20702   "rdtsc"
20703   [(set_attr "type" "other")
20704    (set_attr "length" "2")])
20705
20706 (define_expand "rdtscp"
20707   [(match_operand:DI 0 "register_operand" "")
20708    (match_operand:SI 1 "memory_operand" "")]
20709   ""
20710 {
20711   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20712                                     gen_rtvec (1, const0_rtx),
20713                                     UNSPECV_RDTSCP);
20714   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20715                                     gen_rtvec (1, const0_rtx),
20716                                     UNSPECV_RDTSCP);
20717   rtx reg = gen_reg_rtx (DImode);
20718   rtx tmp = gen_reg_rtx (SImode);
20719
20720   if (TARGET_64BIT)
20721     {
20722       rtvec vec = rtvec_alloc (3);
20723       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20724       rtx upper = gen_reg_rtx (DImode);
20725       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20726       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20727       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20728       emit_insn (load);
20729       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20730                                    NULL, 1, OPTAB_DIRECT);
20731       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20732                                  OPTAB_DIRECT);
20733     }
20734   else
20735     {
20736       rtvec vec = rtvec_alloc (2);
20737       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20738       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20739       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20740       emit_insn (load);
20741     }
20742   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20743   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20744   DONE;
20745 })
20746
20747 (define_insn "*rdtscp"
20748   [(set (match_operand:DI 0 "register_operand" "=A")
20749         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20750    (set (match_operand:SI 1 "register_operand" "=c")
20751         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20752   "!TARGET_64BIT"
20753   "rdtscp"
20754   [(set_attr "type" "other")
20755    (set_attr "length" "3")])
20756
20757 (define_insn "*rdtscp_rex64"
20758   [(set (match_operand:DI 0 "register_operand" "=a")
20759         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20760    (set (match_operand:DI 1 "register_operand" "=d")
20761         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20762    (set (match_operand:SI 2 "register_operand" "=c")
20763         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20764   "TARGET_64BIT"
20765   "rdtscp"
20766   [(set_attr "type" "other")
20767    (set_attr "length" "3")])
20768
20769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20770 ;;
20771 ;; LWP instructions
20772 ;;
20773 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20774
20775 (define_expand "lwp_llwpcb"
20776   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20777                     UNSPECV_LLWP_INTRINSIC)]
20778   "TARGET_LWP"
20779   "")
20780
20781 (define_insn "*lwp_llwpcb<mode>1"
20782   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20783                     UNSPECV_LLWP_INTRINSIC)]
20784   "TARGET_LWP"
20785   "llwpcb\t%0"
20786   [(set_attr "type" "lwp")
20787    (set_attr "mode" "<MODE>")
20788    (set_attr "length" "5")])
20789
20790 (define_expand "lwp_slwpcb"
20791   [(set (match_operand 0 "register_operand" "=r")
20792         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20793   "TARGET_LWP"
20794   {
20795     if (TARGET_64BIT)
20796       emit_insn (gen_lwp_slwpcbdi (operands[0]));
20797     else
20798       emit_insn (gen_lwp_slwpcbsi (operands[0]));
20799     DONE;
20800   })
20801
20802 (define_insn "lwp_slwpcb<mode>"
20803   [(set (match_operand:P 0 "register_operand" "=r")
20804         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20805   "TARGET_LWP"
20806   "slwpcb\t%0"
20807   [(set_attr "type" "lwp")
20808    (set_attr "mode" "<MODE>")
20809    (set_attr "length" "5")])
20810
20811 (define_expand "lwp_lwpval<mode>3"
20812   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20813                      (match_operand:SI 2 "nonimmediate_operand" "rm")
20814                      (match_operand:SI 3 "const_int_operand" "i")]
20815                     UNSPECV_LWPVAL_INTRINSIC)]
20816   "TARGET_LWP"
20817   "/* Avoid unused variable warning.  */
20818    (void) operand0;")
20819
20820 (define_insn "*lwp_lwpval<mode>3_1"
20821   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20822                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20823                      (match_operand:SI 2 "const_int_operand" "i")]
20824                     UNSPECV_LWPVAL_INTRINSIC)]
20825   "TARGET_LWP"
20826   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20827   [(set_attr "type" "lwp")
20828    (set_attr "mode" "<MODE>")
20829    (set (attr "length")
20830         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20831
20832 (define_expand "lwp_lwpins<mode>3"
20833   [(set (reg:CCC FLAGS_REG)
20834         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20835                               (match_operand:SI 2 "nonimmediate_operand" "rm")
20836                               (match_operand:SI 3 "const_int_operand" "i")]
20837                              UNSPECV_LWPINS_INTRINSIC))
20838    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20839         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20840   "TARGET_LWP"
20841   "")
20842
20843 (define_insn "*lwp_lwpins<mode>3_1"
20844   [(set (reg:CCC FLAGS_REG)
20845         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20846                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20847                               (match_operand:SI 2 "const_int_operand" "i")]
20848                              UNSPECV_LWPINS_INTRINSIC))]
20849   "TARGET_LWP"
20850   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20851   [(set_attr "type" "lwp")
20852    (set_attr "mode" "<MODE>")
20853    (set (attr "length")
20854         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20855
20856 (include "mmx.md")
20857 (include "sse.md")
20858 (include "sync.md")